WCF的HttpPost无效的JSON字符串。

3
我可以帮您进行翻译。以下是需要翻译的内容:

我正在尝试从网站调用我的WCF服务上的POST方法。然而,WCF服务报错说JSON字符串无效。

WCF服务方法:

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "reserve/batteries", BodyStyle = WebMessageBodyStyle.Bare)]
public bool ReserveBatteries(ReserveModel values)

调用POST方法,来自网站:

var stations = TempData["Stations"];
string jsonStations = JsonHelper.SerializeJson(stations);

HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://localhost:49288/reserve/batteries");

UTF8Encoding encoding = new UTF8Encoding();
string postData = "{\"Stations\": " + jsonStations;
postData += ", \"User\": \"" + User.Identity.Name + "\" }";
byte[] data = encoding.GetBytes(postData);

httpWReq.Method = "POST";
httpWReq.ContentType = "application/json; charset=utf-8";
httpWReq.ContentLength = data.Length;

using (Stream stream = httpWReq.GetRequestStream())
{
      stream.Write(data, 0, data.Length);
}

HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();

string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

我正在使用Newtonsoft json库进行序列化。 我正在尝试发送到我的服务的json字符串是:

{
    "Stations": [
        {
            "BatteryStorages": null,
            "CreatedDate": "2013-06-06T00:00:00+02:00",
            "Description": "Aalborg City",
            "Edges": [],
            "ID": 3,
            "IsActive": true,
            "IsOperational": true,
            "Reservations": [],
            "StationLat": 57.02881,
            "StationLong": 9.91777,
            "StationMaintenances": [],
            "StationType": null,
            "Title": "Aalborg",
            "TypeId": 1,
        }
    ],
    "User": "user1"
}

我已经使用JsonLint验证过这个字符串,它是有效的。
WCF接受的非有效字符串(根据JsonLint的说法):
{
    "Stations": "[
         {
             BatteryStorages:null,
             CreatedDate:\"/Date(1370469600000+0200)/\",
             Description:\"Aalborg City\",
             Edges:[],
             ID:\"3\",
             IsActive:\"true\",
             IsOperational:\"true\",
             Reservations:[],
             StationLat:\"57.02881\",
             StationLong:\"9.91777\",
             StationMaintenances:[],
             StationType:null,
             Title:\"Aalborg\",
             TypeId:\"1\"
         }
     ]",
     "User": "user1"
}

来自WCF的异常:

反序列化类型RestfulAPI.Resources.ReserveModel对象时出错。期望命名空间为''的结束元素'Stations'。但找到了命名空间为''的元素'item'。

这是怎么回事?为什么WCF会抱怨它无效,而jsonlint(和其他工具)却说它有效。

编辑:

[DataContract]
public class ReserveModel
{
    [DataMember]
    public string Stations { get; set; }
    [DataMember]
    public string User { get; set; }
}

你能否尝试在客户端和服务器之间共享ReserveModel类(或在客户端上复制它),然后使用Newtonsoft序列化它?刚刚注意到你的最后一次编辑,这让我想起了什么。 - Marcel N.
我不是很确定该怎么做。据我所知,Newtonsoft 不接受类型参数,使用的方法是 JsonConvert.SerializeObject(obj); - KLIM8D
我删除了我的回答,因为它并不是很有帮助。稍后会尝试做一个测试。 - Marcel N.
1个回答

5
问题在于你的Model对象格式不正确。
要从JSON创建正确的JSON类,你可以使用json2csharp,或者如果你有例如VS2012 update 2之类的软件,你可以复制你的JSON,然后将JSON作为类粘贴(编辑 -> Paste Special > Paste JSON as classes)。
你必须记住,例如DateTime对象必须按照WCF支持的某种方式传递。更多信息可以在这里找到(msdn - WCF JSON serialization)。要避免这个问题,你可以只将变量键入为字符串,并在以后将其转换。
希望这有所帮助!

谢谢,问题解决了!我现在只需要弄清楚如何将日期“2013-06-06T00:00:00+02:00”包装在“new Date()”中。 - KLIM8D
如果您的模型希望从JSON中获得日期,可以将其类型定义为字符串。这样一来,您就不必进行转义和格式转换了。这确实允许您创建另一个属性,将字符串转换为DateTime。虽然不是“最佳方法”,但可以创建更简单的JSON。例如:public DateTime DateName { get { return DateTime.Parse(YourString) } } - Xciles
1
谢谢,那是一个可能的解决方案。然而,由于我正在使用Newtonsoft来序列化我的json,我可以通过JsonSerializerSettings指定我想要的日期格式 - http://james.newtonking.com/projects/json/help/index.html?topic=html/DatesInJSON.htm - KLIM8D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接