Reputation: 51
I am using WCF .NET 4.0 hosting inside WebServiceHost. Normaly all works until i use my own defined class array inside class.
Server side function
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "foo")]
[OperationContract]
void Foo(FooQuery query);
Classes
[DataContract(Namespace="")]
public class FooQuery
{
[DataMember]
public MyFoo[] FooArray;
}
[DataContract(Namespace = "")]
public class MyFoo
{
[DataMember]
public string[] items;
}
Client side:
//create object
FooQuery myOriginalFoo = new FooQuery();
MyFoo _myFoo = new MyFoo();
_myFoo.items = new string[] { "one", "two" };
myOriginalFoo.FooArray = new MyFoo[] { _myFoo };
//serialize
var json = new JavaScriptSerializer().Serialize(myOriginalFoo);
string _text = json.ToString();
//output:
// {"FooArray":[{"items":["one","two"]}]}
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:2213/foo");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(_text);
streamWriter.Flush();
streamWriter.Close();
}
//here server give back: 400 Bad Request.
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
I have also tried manipulate my class with System.Runtime.Serialization.Json.DataContractJsonSerializer - all fine until i send to server and webinvoke give back error 400. Why webInvoke don't know how deserialize it or there any other error?
Upvotes: 2
Views: 3593
Reputation: 51
I found magic attribute called CollectionDataContract what makes a trick.
Adding new collection class:
[CollectionDataContract(Namespace = "")]
public class MyFooCollection : List<MyFoo>
{
}
Changed Query class
[DataContract(Namespace="")]
public class FooQuery
{
[DataMember]
public /*MyFoo[]*/MyFooCollection FooArray;
}
client code change:
MyFooCollection _collection = new MyFooCollection();
_collection.Add(_myFoo);
myOriginalFoo.FooArray = _collection; //new MyFoo[] { _myFoo };
All variables serialized now right :) yeah..takes many hours to figure out.
Upvotes: 1
Reputation: 2008
Set the WebMessageBodyStyle to wrappedRequest as below for the WCF service to expect a wrapped JSON string. by default it expects a plain String.
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
Upvotes: 0
Reputation: 4866
Since it is a web request, try GET instead:
[WebGet(ResponseFormat = WebMessageFormat.Json)]
Upvotes: 0