문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

Since it is a web request, try GET instead:

[WebGet(ResponseFormat = WebMessageFormat.Json)]

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)]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top