Gayan Ranasinghe Gayan Ranasinghe - 1 month ago 16
C# Question

Post data using jquery HybridDictionary as action parameter

i want to post data to action controller with this format

{
"key1" : "value1",
"key2" : "value2"
}


i want to map those values to
HybridDictionary
on my jquery post i use like this

$.ajax("/profile/post",
{
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({ "key1": "value1", "key2": "value2" }),
method: "POST",
async: true,
success(e) { defer.resolve(e); },
error(e) { defer.reject(e); }
});


my action controller i get
Post(HybridDictionary data)
but seems it never gets posted values what was the wrong that i have done?

update

this is format I am getting those values

var c= new HybridDictionary();
c.Add("hello", "world");
c.Add("hello2", "world2");
c.Add("hello3", "world3");

Answer

There is nothing wrong with your ajax call. The problem is that you have no model binder setup to deserialize your json object on call execution. You can create a JsonModelBinder class in your App_Start folder and this code:

public class JsonModelBinder : DefaultModelBinder
{
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (!IsJsonRequest(controllerContext))
            {
                return base.BindModel(controllerContext, bindingContext);
            }

            // Get the JSON data that's been posted
            var request = controllerContext.HttpContext.Request;
            //in some setups there is something that already reads the input stream if content type = 'application/json', so seek to the begining
            request.InputStream.Seek(0, SeekOrigin.Begin);
            var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();

            // Use the built-in serializer to do the work for us
            return new JavaScriptSerializer()
                .Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);

            // -- REQUIRES .NET4
            // If you want to use the .NET4 version of this, change the target framework and uncomment the line below
            // and comment out the above return statement
            //return new JavaScriptSerializer().Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);
        }

        private static bool IsJsonRequest(ControllerContext controllerContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            return contentType.Contains("application/json");
        }
}

    public static class JavaScriptSerializerExt
    {
        public static object Deserialize(this JavaScriptSerializer serializer, string input, Type objType)
        {
            var deserializerMethod = serializer.GetType().GetMethod("Deserialize", BindingFlags.NonPublic | BindingFlags.Static);

            // internal static method to do the work for us
            //Deserialize(this, input, null, this.RecursionLimit);

            return deserializerMethod.Invoke(serializer,
                new object[] { serializer, input, objType, serializer.RecursionLimit });
        }
    }

Then register it in your Global.asax.cs Application_Start method:

ModelBinders.Binders.DefaultBinder = new JsonModelBinder();