WCF WebInvoke JSON反序列化失败 - 400错误请求

时间:2013-11-05 09:03:42

标签: c# json wcf deserialization webinvoke

我在WebServiceHost中使用WCF .NET 4.0托管。 Normaly一直有效,直到我在类中使用我自己定义的类数组。

服务器端功能

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "foo")]
[OperationContract]
void Foo(FooQuery query);

[DataContract(Namespace="")]
public class FooQuery
{
    [DataMember]
    public MyFoo[] FooArray;
}

[DataContract(Namespace = "")]
public class MyFoo
{
    [DataMember]
    public string[] items;
}

客户方:

        //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();

我也尝试用System.Runtime.Serialization.Json.DataContractJsonSerializer操作我的类 - 一切正常,直到我发送到服务器和webinvoke回复错误400.为什么webInvoke不知道如何反序列化它或有任何其他错误?

3 个答案:

答案 0 :(得分:1)

我发现了一个名为 CollectionDataContract 的魔法属性,这就是诀窍。

添加新的集合类:

[CollectionDataContract(Namespace = "")]
public class MyFooCollection : List<MyFoo>
{
}

更改了查询类

[DataContract(Namespace="")]
public class FooQuery
{
    [DataMember]
    public /*MyFoo[]*/MyFooCollection FooArray;
}

客户端代码更改:

MyFooCollection _collection = new MyFooCollection();
_collection.Add(_myFoo);
myOriginalFoo.FooArray = _collection; //new MyFoo[] { _myFoo };

所有变量现在都已经序列化了:)是啊......需要花费很多时间才能搞清楚。

答案 1 :(得分:0)

由于这是一个网络请求,请尝试改为GET:

[WebGet(ResponseFormat = WebMessageFormat.Json)]

答案 2 :(得分:0)

将WebMessageBodyStyle设置为wrappedRequest,如下所示,以使WCF服务期望包装的JSON字符串。默认情况下,它需要一个普通的String。

 [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]