Search code examples
jsonasp.net-mvc-3stringify

Formcollection cannot process JSON with "="


When I try to do something like this:

$.post('@Url.Action("PostComment")', {"Id":32,"Title":"=","Desc":"=",}, function (data) {
    ....
}

My controller receives this value in the FormCollection:

public ActionResult PostComment(FormCollection comment) {
    ....
}

Strangelly the value looks like:

","Desc":"="}

(The value is made with: JSON.stringify( { Id: 32, Title: "=", Desc: "=" })

However, when the characters are other than "=" the object is received correctly.

How can I send a JSON object with this special character? Seems like MVC3 cannot process those values...


Solution

  • I got a little bit confused about what are you realy trying to send, so I will describe both cases.

    Your JavaScript snippet and action method would suggest that you are sending application/x-www-form-urlencoded - in that case you should not use JSON.stringify on your data and everything should work just fine.

    But if you really want to send JSON (application/json), than first your JavaScript should be a little bit different:

    $.ajax({
        type: 'POST',
        url: '@Url.Action("PostComment")',
        data: JSON.stringify( { Id: 32, Title: '=', Desc: '=' }),
        contentType: 'application/json',
        success: function(result) {
        ...
        }
    });
    

    You should also get yourself a class for the entity (it can be also used for application/x-www-form-urlencoded data):

    public class Comment
    {
        public int Id { get; set; }
    
        public string Title { get; set; }
    
        public string Desc { get; set; }
    }
    

    Which allows you to change your action method like this (again this can be done for application/x-www-form-urlencoded data as well):

    public ActionResult PostComment(Comment comment)
    {
        ...
    }
    

    ASP.NET MVC will bind the data properly, just make sure your are sending data in right format with right content type and that JSON should be bind to the object.

    UPDATE

    There is one more scenario emerging from your comment - posting JSON as a value of a field in form. To achieve this you should start by changing your JavaScript to look more like this:

    $.post('@Url.Action("PostComment")', { jsonComment: JSON.stringify({ Id: 32, Title: '=', Desc: '=' }) }, function (data) {
        ...
    });
    

    Now the raw JSON can be accessed in one of two ways, through the FormCollection:

    [HttpPost]
    public ActionResult PostComment(FormCollection fields)
    {
        string jsonComment = fields["jsonComment"];
        ...
    }
    

    or directly by name:

    [HttpPost]
    public ActionResult PostComment(string jsonComment)
    {
        ...
    }
    

    This wrapping is needed because FromCollection can`t work with JSON directly, it is not designed for it. You need to post proper form data, but you can have JSON as a value with no issue (and you can have other simple values in that form data as well).