timb has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,

for quite a while I'm retrieving data from Sharepoint using perl on my linuxmachine.

Now I also have to change data on SP.

I added some logic to retrieve the digesttoken (needed for posting) but altough it looked promising at the beginning now I'm stuck with that really annoying error:

"A supported MIME type could not be found that matches the content type of the response. None of the supported type(s) 'application/atom+xml;type=entry, application/atom+xml, application/json;odata=verbose' matches the content type 'application/json'."

I've already spent days searching the web for a solution, but was unsuccessful so far.

Maybe there is a monk out there who can help me out.

This is my code:

#!/usr/bin/perl use strict; use LWP::UserAgent; use LWP::Authen::Ntlm; use JSON; use Data::Dumper; # config my $host = "mysite.local"; my $user = 'domain\spadmin'; my $pass = "sucKmYducK"; my $resource = "business/mytestsite"; my $listid = "1bd8d1bc-e797-41ae-97c0-e3876406d0fe"; my $itemindex = 20; # globals my $digest; # create useragent my $ua = LWP::UserAgent->new( keep_alive => 1); $ua->credentials("$host:443", "", $user, $pass); $ua->default_header('Accept' => "application/json;odata=verbose"); $ua->timeout( 10 ); # get digest my $response = $ua->post( "https://$host/$resource/_api/contextinfo" + ); if ($response->is_success) { my $json = decode_json $response->decoded_content; $digest = $json->{d}->{GetContextWebInformation}->{FormDigestValue +}; } else { die $response->status_line; } # post data my $msg = '{"__metadata":{"type":"SP.Data.DocLibItem"},"Title":"This + is my testtitle"}'; $ua->default_header ( 'Accept' => "application/json;odata=verbose", 'Content-type' => "application/json;odata=verbose", 'Content-length' => length( $msg ), 'X-HTTP-Method' => "MERGE", 'X-RequestDigest' => $digest, 'IF-MATCH' => "*" ); my $response = $ua->post ( "https://$host/$resource/_api/lists('$listid')/items($itemindex)", { data => $msg } ); my $json = decode_json $response->decoded_content; print Dumper( $json ); if ($response->is_success) { print "place to be :)\n"; } else { die $response->status_line; }

tia

tiMb

Replies are listed 'Best First'.
Re: Changing data in Sharepointlist via LWP/JSON - OData.ODataContentTypeException :(
by Corion (Patriarch) on May 13, 2014 at 14:22 UTC

    I just looked at your code again, and I find it a very weird approach to (re)set $ua->default_header for each request. The more traditional way would be to simply construct the appropriate HTTP::Request objects instead. At least from my spurious attempts, it does not feel as if a POST request uses the ->default_header:

    > perl -MLWP::UserAgent -e "$ua=LWP::UserAgent->new();$ua->default_hea +der('Content-type' => 'application/json;odata=verbose'); $ua->add_handler('request_send',sub{shift->dump;return}); $ua->post('http://localhost:1234',{foo => bar})" POST http://localhost:1234 User-Agent: libwww-perl/6.04 Content-Length: 7 Content-Type: application/x-www-form-urlencoded foo=bar

    Explicitly creating the HTTP::Request and then sending that one seems to create headers that I expect:

    >perl -MLWP::UserAgent -MHTTP::Request::Common -e "$ua=LWP::UserAgent- +>new(); req= POST 'http://localhost:1234', 'Content-type' => 'applicati +on/json;odata=verbose', Content => { foo => 'bar' }; $ua->add_handler('request_send',sub{shift->dump;return}); $ua->req +uest($req)" POST http://localhost:1234 User-Agent: libwww-perl/6.04 Content-Length: 7 Content-Type: application/json;odata=verbose foo=bar

    So I suggest you do more debugging on whether the values you think you are sending actually get send, and you also switch to the more common and accepted use of ->default_header() of setting only default headers and not per-request specific headers.

      You are absolutely right! I was using LWP the wrong way. Quite embarassing after using it for so many years. But so far I never had the need to send a different content-type.

      As soon as I corrected my code I got a completely new error ;)

      But this one is Sharepoint-related so I won't bother anyone here anymore.

      Thanks for helping me out!

      tiMb

        Just for completeness. I now have a working example of how to change data in Sharepoint via Perl.
        #!/usr/bin/perl use strict; use LWP::UserAgent; use LWP::Authen::Ntlm; use HTTP::Request::Common; use JSON; use Data::Dumper; # config my $host = "mysite.local"; my $user = 'domain\spadmin'; my $pass = "iLikeMyBike"; my $resource = "business/mytestsite"; my $listid = "1bd8d1bc-e797-41ae-97c0-e3876406d0fe"; my $itemindex = 20; # globals my $digest; # create useragent my $ua = LWP::UserAgent->new( keep_alive => 1); $ua->credentials("$host:443", "", $user, $pass); $ua->default_header('Accept' => "application/json;odata=verbose"); $ua->timeout( 10 ); # get digest my $response = $ua->post( "https://$host/$resource/_api/contextinfo" + ); if ($response->is_success) { my $json = decode_json $response->decoded_content; $digest = $json->{d}->{GetContextWebInformation}->{FormDigestValue +}; } else { die $response->status_line; } # post data my $msg = '{"__metadata":{"type":"SP.Data.DocLibItem"},"Title":"This + is my testtitle"}'; my $req = POST "https://$host/$resource/_api/lists('$listid')/items( +$itemindex)", "Content-type" => "application/json;odata=verbose", "X-HTTP-Method" => "MERGE", "X-RequestDigest" => $digest, "IF-MATCH" => "*", "Content" => $msg; $response = $ua->request( $req ); my $json = decode_json $response->decoded_content; print Dumper( $json ); if ($response->is_success) { print "place to be :)\n"; } else { die $response->status_line; }
Re: Changing data in Sharepointlist via LWP/JSON - OData.ODataContentTypeException :(
by Anonymous Monk on May 12, 2014 at 20:35 UTC
    hah, if you ask a bartender for Pepsi, and the bartender says we only have Cocacola, well, there is no way you'll get a Pepsi from that bartender -- stop asking "sharepoint" for Pepsi , it doesn't like it
      I was hoping for a more professional reply. I have no intention to start a religious war. I don't really like Sharepoint either. But I have to work with it and I'm glad I can use perl.

        Have you looked at what your script sends in a traffic analyzer like Wireshark LWP::Debug (as you're using HTTPS, it's likely easier to dump things at the source side)?

        The error message is highly unclear about whether the Sharepoint server received something with Content-Type: application/json, and could not handle it, or whether it wants ti send something with Content-Type: application/json and your client doesn't offer that in the appropriate way.

        I see that you're setting both, Accept and Content-Type headers, so the next thing would be to make really sure that they actually get sent over the wire.

        Maybe you can find out if the Sharepoint logs point out a better error cause.

        I was hoping for a more professional reply. I have no intention to start a religious war. I don't really like Sharepoint either. But I have to work with it and I'm glad I can use perl.

        Hmm,

        you're asking why some random website is saying its only getting "application/json" when the program you show is sending "application/json;odata=verbose" ...

        the bartending analogy seems apt :)

        Corion brings up a good point about looking outside of perl locally (using wireshark) for interlopers (firewalls), but odds are its a bartending problem

        https://metacpan.org/pod/XML::Compile::SOAP#Supported-servers says Both BEA and SharePoint servers produce illegal SOAP responses! It is a sad story. , who knows, maybe the same goes for sharepoint JSON support (wouldn't be surprised)

        So, my response doesn't seem unprofessional to me, or religious ...

        I didn't even try to roast your fowl for your included test password of sucKmYducK

        I think the reason you will find very little help on Perlmonks (or you will get unkind responses - I fought back the urge to write one myself) for basically a Microsoft-based question is that you have not 'sold' us onto the idea that the problem you are facing is indeed a Perl problem.

        Over the years there have been thousands of posts that read like this, 'I was using Perl and I now it broke.' What elicits the bad response is not the post nor the problem -- it is the approach. I'm speaking from experience when I say that Microsoft's claim to fame is that they build tools that do everything for you. You don't really have to know how anything works -- their Knowledgebase has examples, sample code, and everything is essentially a black box. Here you are not just interfacing Perl with Sharepoint, you are trying to interface two completely different cultures.

        When I first started learning Perl I was a VB programmer. I was in shock that I actually had to read documentation and solve problems myself. When I started learning how to use Linux I was, again, in shock that everything wasn't clearly spelled out and all in one place. I had to seek out answers to problems from different people and it was important to contribute, even if it was just a bug report.

        You made a comment that the first responder to your post was unprofessional. That exemplifies my point. Why should you expect a professional response to anything on Perlmonks? Here we are, on our own time, providing answers to our peers and people new to the language. This environment is anything but professional. It is not anyone's job to help you with your problems. You have Perlmonks confused with the boys/girls at Redmond.

        I may get downvoted for saying this but I am just going to come out and say it -- unless you spend time trying to grasp what free software/open source is about stop using Perl. Don't use Linux. Give up now; buy Windows 8/9/whatever and reinstall it on that machine. Switch your client to something in .NET and when you run into trouble contact Microsoft support (http://support.microsoft.com/contactus/?ln=en-us).

        That is my professional response.

        Celebrate Intellectual Diversity

        A reply falls below the community's threshold of quality. You may see it by logging in.