Unable to deserialize array

2019-02-16 23:29发布

问题:

Data sent from client will not get deserialized.

Client:

$.ajax({
     type: 'POST',
     dataType: "json",
     url: 'savecommentsservice',
     data: { "Pid": 0, "Comments": [{ "User": "bbbbbb", "Text": "aaaaaaaa" }, { "User": "ddddddd", "Text": "ccccccccc"}] },

DTO:

public class Comment
{
    public string User { get; set; }
    public string Text { get; set; }
}
public class SaveCommentsRequest
{
    public int Pid { get; set; }
    public string SiteId { get; set; }
    public string Column { get; set; }
    public List<Comment> Comments { get; set; }
}

Server:

Routes.Add<SaveCommentsRequest>("/savecommentsservice");

...

public object Execute(SaveCommentsRequest request)
    {
        // Why is request.Comments null !!! All other params of the request works fine

        // THe string I'm putting in is generated below - just to make sure its correct
        request.Comments = new List<Comment>();
        request.Comments.Add(new Comment { Text = "aaaaaaaa", User = "bbbbbb" });
        request.Comments.Add(new Comment { Text = "ccccccccc", User = "ddddddd" });

        var thisIsWhatIPutInto$AjaxCall = JsonSerializer.SerializeToString<SaveCommentsRequest>(request);

Any Idea what's wrong? Why is the Comments array not populated. As you can see from the comments I've generated the string with the servicestack json serializer.

Maybe I'm missing some obvisous here?

EDIT When looking at fiddler whats beeing transmitted I see this:

    POST http://localhost:4920/savecommentsservice HTTP/1.1
Host: localhost:4920
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://localhost:4920/default.cshtml?viewId=3
Content-Length: 227
Cookie: ASP.NET_SessionId=slbw453revfgmwuuxyrim1an
Pragma: no-cache
Cache-Control: no-cache

SiteId=Site1&Pid=0&Column=C6&Comments%5B0%5D%5BUser%5D=bbbbbb&Comments%5B0%5D%5BText%5D=aaaaaaaa&Comments%5B1%5D%5BUser%5D=ddddddd&Comments%5B1%5D%5BText%5D=ccccccccc&Comments%5B2%5D%5BUser%5D=ggggggg&Comments%5B2%5D%5BText%5D=

And in firebug:

    Parametersapplication/x-www-form-urlencoded
Column  C6
Comments[0][Text]   aaaaaaaa
Comments[0][User]   bbbbbb
Comments[1][Text]   ccccccccc
Comments[1][User]   ddddddd
Comments[2][Text]   
Comments[2][User]   ggggggg
Pid 0
SiteId  SiteId0
Source
SiteId=SiteId0&Pid=0&Column=C6&Comments%5B0%5D%5BUser%5D=bbbbbb&Comments%5B0%5D%5BText%5D=aaaaaaaa&Comments%5B1%5D%5BUser%5D=ddddddd&Comments%5B1%5D%5BText%5D=ccccccccc&Comments%5B2%5D%5BUser%5D=ggggggg&Comments%5B2%5D%5BText%5D=

Regards

Larsi

回答1:

As you can see by default jQuery's Ajax submits it as 'application/x-www-form-urlencoded' which is the default HTML Form Post Content-Type. Unfortunately it doesn't handle nested objects very well and ServiceStack will expect nested objects in the JSV Format.

So for complex types / nested objects you want to tell jQuery to send the request as JSON which you can do by specifying the contentType:application/json parameter e.g:

var data = { "Pid": 0, "Comments": [{ "User": "bbbbbb", "Text": "aaaaaaaa" }]};
$.ajax({
     type: 'POST',
     dataType: "json",
     contentType: "application/json",
     url: 'savecommentsservice',
     data: JSON.stringify(data)
);


回答2:

I believe you need to add the name of the parameter (request) to your string. Something along the lines of..

$.ajax({
     type: 'POST',
     dataType: "json",
     url: 'savecommentsservice',
     data: {"request": "Pid": 0, "Comments": [{ "User": "bbbbbb", "Text": "aaaaaaaa" }, { "User": "ddddddd", "Text": "ccccccccc"}] },