Post (Error in deserializing body of request message for operation) - c#

I have this method:
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "foo",
ResponseFormat = WebMessageFormat.Json)]
ResultChange Foo(int bar, String foobar);
I've downloaded a Firefox plugin (Poster) so I can easily send POST request.
But I get the
The server encountered an error processing the request. The exception
message is 'Error in deserializing body of request message for
operation 'ChangeDetails'. The OperationFormatter could not
deserialize any information from the Message because the Message is
empty (IsEmpty = true).'.
I've set the style to Wrapped as you can see, but that did not solve my issue. This was a solution provided here: Bad Request Error On REST service Method call with POST (json Data)? but did not solve it.
Update: I've succesfully sent a test() function, and it sent me back: "OK, the service is working". as it returns a string with that content.
What can I do to fix my issue?

Related

WCF REST: The incoming message has an unexpected message format 'Json'. Expected message format is 'Raw'

So I've seen many questions reagrding an error the other way around, but not this way.
In my WCF Service I've defined the method like:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "v1/posttest")]
void PostTest(Stream incoming);
In my request header I've set Content-Type to application/json
So everything should work, right? However, I get a 400 Bad Request error and the notification you see in the question title.
Any help is appreciated. Thanks a lot!
Turns out, I should've just tried the most obvious thing... Removing the Content-Type header in my client solved the problem.
It still seems unintuitive to me, can anyone explain why WCF does that?
Very nice! Thank you a lot.
This runs perfectly:
read: {
url: "http://localhost:33473/Service2.svc/GetProfile", //contentType: "application/json; charset=utf-8", // tells the web service to serialize JSON
type: "POST", //use HTTP POST request as the default GET is not allowed for svc
}

Can't execute WCF REST services for POST and GET with basic endpoint address

I'm attempting to create a set of WCF REST services with the following endpoints (among others):
/Session (supports HTTP POST and creates a Session object. Returns sid in the response)
/Session/{sid} (supports HTTP GET and returns a JSON object representing a previously created Session)
Here are the definitions in the service contract:
[OperationContract]
[WebInvoke(Method="POST", RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json, UriTemplate="Session")]
string InitializeSession(Stream contents);
[OperationContract]
[WebInvoke (Method="GET", RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json, UriTemplate="Session/{sid}")]
string RetrieveSession(string sid);
Without the GET Operation defined I can invoke the POST just fine and get the expected sid in the response. When the GET OperationContract is included, invoking the POST throws:
500 System.ServiceModel.ServiceActivationException
with no additional data in the response (very helpful) even though I've got
<serviceDebug includeExceptionDetailInFaults="true"/>
defined in the Service Behavior in web.config.
Do the OperationContract definitions look correct for what I'm trying to achieve (assuming what I'm trying to achieve is properly RESTful)? If so any ideas on what silly config option I'm likely missing that would allow access to both operations?
Try changing your operation contracts of your get and post methods to some thing like below:
1. Post
[OperationContract]
[WebInvoke(UriTemplate = "Session", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
2. Get
[OperationContract]
[WebInvoke(UriTemplate = "Session/{sid}", Method = "GET", ResponseFormat =
WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]

COSM Trigger extracting JSON values using C# from an HTTP Post

Trying to receive COSM Trigger HTTP Post via a C# RESTful service, not receiving the alert. I took the COSM API JSON payload and used it from a test client - that worked. When I setup my feed and either try the debug trigger test, or just force the trigger to fire normally, my REST service doesn't get called. If I try any form of test client the service processes the JSON POST just fine.
C# service is here:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "cosm",
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string CosmAlert(CosmTrigger data);
Where CosmTrigger is my class mirroring the COSM Trigger fields.
My COSM feed is here.
I'm starting from the COSM portal to fire a trigger, Twitter based trigger works fine, the HTTP Post to my URL isn't. How to debug this?
A Cosm trigger currently doesn't send triggers as a JSON body, it actually sends a URL encoded request with the JSON trigger body encoded as a parameter called 'body'.
Using http://requestb.in on a test trigger, and viewing the raw output this shows the basic request looks like this:
POST /103s0dh1 HTTP/1.1
X-Request-Id: e05e9d699edbd5f584fc491cf9416df747be4df4
User-Agent: Cosm Deliverator (Axino/0.3.02) - https://cosm.com
Host: requestb.in
Content-Type: application/x-www-form-urlencoded
Content-Length: 918
Connection: close
body=%7B%22id%22%3A7443%2C%22url%22%3A%22http%3A%2F%2Fapi.cosm.com%2Fv2%2Ftriggers%2F7443%22%2C%22type%22%3A%22lt%22%2C%22threshold_value%22%3A%2220%22%2C%22timestamp%22%3A%222013-04-14T09%3A50%3A47.590044Z%22%2C%22environment%22%3A%7B%22id%22%3A57346%2C%22feed%22%3A%22http%3A%2F%2Fapi.cosm.com%2Fv2%2Ffeeds%2F57346%22%2C%22title%22%3A%22Macbook+Battery+Level%22%2C%22description%22%3A%22%22%2C%22private%22%3Afalse%2C%22location%22%3A%7B%22lat%22%3Anull%2C%22lon%22%3Anull%2C%22name%22%3A%22%22%7D%7D%2C%22triggering_datastream%22%3A%7B%22id%22%3A%22battery%22%2C%22url%22%3A%22http%3A%2F%2Fapi.cosm.com%2Fv2%2Ffeeds%2F57346%2Fdatastreams%2Fbattery%22%2C%22at%22%3A%222013-04-14T09%3A50%3A02.406927Z%22%2C%22value%22%3A%7B%22max_value%22%3A1724.0%2C%22min_value%22%3A0.0%2C%22value%22%3A%2226.28%22%7D%2C%22units%22%3A%7B%22type%22%3Anull%2C%22symbol%22%3A%22%25%22%2C%22label%22%3Anull%7D%7D%2C%22debug%22%3Atrue%7D
I'm not a C# expert unfortunately but I suspect the problem is something to do with the service not being configured to extract the JSON body from a standard urlencoded request body, but perhaps this might give a clue to how to figure out what is going wrong for someone who does know C#.
Tested and working code -
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
UriTemplate = "cosm")]
string cosmStream(Stream body);

Intermittent deserialization errors in REST WCF Service in .NET 4.5

Since updating our project to Visual Studio 2012 and a targeting the .NET framework 4.5 from 4.0, we've been intermittently experiencing serialization exception issues when attempting to return data from our service methods, though for purposes of debugging the problem, we've focused our attention on a single service method, GetPageSelectListForSite.
This methods interface declaration is the following:
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "/Pages/Site/ListItems/{siteId}",
BodyStyle = WebMessageBodyStyle.Bare),
Description("")]
IEnumerable<PageInfoItem> GetPreviousPages(string siteId);
It is called with the same signature parameter, and the same IEnumerable data is returned inside of a controller; however, occassionally (once every 100 or so times) this will result in a serialization exception when the controller is trying to deserialize the REST service reply:
System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type System.Collections.Generic.IEnumerable`1[[Synodine.Hkd.Models.PageInfoItem, Synodine.Hkd.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Encountered unexpected character 'D'. ---> System.Xml.XmlException: Encountered unexpected character 'D'.
The full exception and corresponding stack trace is available here:
http://pastebin.com/jaqQDbru
PageInfoItem is a fairly simple class containing a string, and derives from ListInfoBase which contains a guid, some strings, some bools, and a DateTime.
Attempts to decorate the classes with [Serializable] AND/OR [DataContract]/[DataMember] have not had any effect. We have not been able to consistently reproduce the problem.
I should note that we've seen the serialization exception error occur on an extremely simple REST GET method, with response/request formats set to Json and BodyStyle of Bare that returns a single string. It doesn't seem to matter if the rest service method in question is a POST/GET or whether its style is set to Bare or Wrapped, though in all cases we are making use of the WebMessageFormat.Json.
We've tried serializing the data ourselves and logging it to see if the JSON was malformed in some way, but the JSON is valid and is identical across failed/succeeded requests.
This was the code we used to serialize the data:
var stream1 = new MemoryStream();
var ser = new DataContractJsonSerializer(typeof(IEnumerable<PageInfoItem>));
ser.WriteObject(stream1, PageInfoItems);
stream1.Position = 0;
var streamReader = new StreamReader(stream1);
A sample of the JSON that is being logged is:
[
{
"DateLastUpdate": "\/Date(1362438368000+0000)\/",
"DateLastUpdateString": null,
"Id": "df2544e6-71a3-4f1c-ac54-d3c85269804f",
"IsSelected": false,
"Name": "samplepage",
"Path": "\/samplepage"
},
<snip>
]
This problem only occurs in our deployed environments. All attempts to reproduce the problem on our local IIS webservers have failed.
We are using the WebChannelFactory to consume the WCF REST Services. Because of this, we don't have (and are not sure how to get) direct access to the Response so we cannot be 100% of the data being sent across the wire.
Has anyone encountered anything similar to this when upgrading their projects to Visual Studio 2012/.NET 4.5 Framework?
Any responses definitely appreciated,
-- Shaun
Can you try exposing another function which return same data that GetPreviousPage returns, but changing the ResponseFormat to say Xml? Then call it multiple times (e.g. from a browser) and see if this new function ever fails. This well help you know if the problem is with Json Serializer.
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "/Pages/Site/ListItemsNew/{siteId}",
BodyStyle = WebMessageBodyStyle.Bare),
Description("")]
IEnumerable<PageInfoItem> GetPreviousPagesNew(string siteId);
PS: Posted this as an answer as it's difficult to post code in comment.

Does the Content-Type of a POST or PUT request need to be 'application/x-www-form-urlencoded' in a WCF ReSTful service?

What I am trying to do is, seemingly, simple: send some POX via the request body, have the WCF service process it, and return a 201 status code. In my ServiceContract I have defined the following method:
[WebInvoke(Method = "PUT", UriTemplate = "/content/add", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat=WebMessageFormat.Xml)]
[OperationContract]
Stream AddContent(Stream input);
The verb here doesn't matter; I could easily replace 'PUT' with 'POST' and wind up with the same result. The implementation of the above method is as follows:
public Stream AddContent(Stream input)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Created;
}
Since what this method actually does is of little consequence I have omitted all of the procedural code. To test this functionality I fired up Fiddler and issued the following request:
User-Agent: Fiddler
Host: myhost.com
Content-Length: 771
Content-Type: text/xml && application/xml; charset: utf8
<xmlDataGoesHere></xmlDataGoesHere>
The supplied value for Content-Type is incorrect, I know, I am just using it to illustrate the Content-Type's that I have tried. If I click on 'Execute' in Fiddler the response code from my service is 400 Bad Request. It is worth noting that my service method is not actually getting hit in this secnario, the request dies before it even gets there. So after copious amounts of reading and process of elimination I changed the Content-Type to :
Content-Type: application/x-www-form-urlencoded
If I execute the Fiddler request now the status code returned from my service is 201 Created. Is there something I am missing as to why I can't set the Content-Type to anything but URLEncoded? I have tried tweaking the BodyStyle and RequestFormat properties in the ServiceContract but those did not have any impact on the outcome. Can anyone shed any light on why this is happening?
I think the problem is related to the fact that when you send XML to a WebHttpBinding, it detects that you are sending XML and tries to deserialize it. It ignores the fact that your signature is expecting a stream. There are workarounds that I have seen but I can't find the links at the moment. If I find them I'll update the post.
Take a look at this http://wcfrestcontrib.codeplex.com/
Ok I have figured this out and the issue I am having is "by design". I found the post 'WCF "Raw" programming model - receiving arbitrary data' over at http://blogs.msdn.com/carlosfigueira/ which led to the solution. The solution here was to create my own customBinding that will return the raw encoder all the time as the blog pointed out. Thanks for all the help.

Categories

Resources