简体   繁体   中英

json data not received by asp.net mvc action method

I am trying to get some data to a controller from client side script, I am stringfying my data so I receive something like:

{"Name":"","Description":"","FieldType":"radio","Fields":[{"Field":{"Name":"something","Value":"nameit"}},{"Field":{"Name":"something else","Value":"dontnameit"}}]}

I will need to validate my data on the controller however, in my action I am recieving a null for some reason, if I use object or string? Why is that?

I have had a look into a lot of other posts but it is not clear, do I need to create my own custom IValueProvider implementation? I think there is one available in the ms futures assembley, I tried to locate the file as I do not want all the code inside the dll, but I could not find it...

Any pointers would be appreciated...

Controller:

[HttpPost]
public JsonResult AddField(string field) //or object
{
//code here
}

Edit: I have followed the post by phill haack but had some errors actually returning the strongly typed object to my view...

my ajax call..

{
        url: url,
        type: "post",
        dataType: 'json',
        traditional: true,
        data: jsondata, // { "field" : jsondata},
        contentType: 'application/json; charset=utf-8',
...
}

I created a custom value provider...

public class Jsonify : ValueProviderFactory { public Jsonify() { }

    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        var jsonData = GetDeserializedJson(controllerContext);
        if (jsonData == null)
        {
            return null;
        }

        //currently used by mvc2 futures
        //return new DictionaryValueProvider<object>(backingStore, 
        //CultureInfo.CurrentCulture);
        // what do I return?

    }
private static object GetDeserializedJson(ControllerContext controllerContext)
        {
            if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            {
                // not JSON request
                return null;
            }

            StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
            string bodyText = reader.ReadToEnd();
            if (String.IsNullOrEmpty(bodyText))
            {
                // no JSON data
                return null;
            }

            //json.net
            var jsonData = JsonConvert.DeserializeObject<SurveyField>(bodyText);
            return jsonData;
        }
}

Controller:

public JsonResult AddSimpleField(SurveyField field) {  ... }

You may take a look at the following blog post which illustrates how you could use a custom JsonValueProviderFactory to send a JSON encoded string from client scripts to a controller action and have this action receive it as a strongly typed model and benefit from the validation of the default model binder:

[HttpPost]
public ActionResult AddField(SomeViewModel model)
{
    if (!ModelState.IsValid)
    {
        // the client sent an invalid data
        return Json(new { IsSuccess = false });
    }
    // the model passed validation => do some processing with this model
    return Json(new { IsSuccess = true });
}

As Phil Haack explains it this custom JsonValueProviderFactory is only necessary if you are working with ASP.NET MVC 2 and is built-in ASP.NET MVC 3 so it should work out of the box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM