在MVC3框架中,JSON数据交互是一种常见的需求。通过AJAX请求,可以在不刷新页面的情况下与服务器进行数据交换。本文将详细介绍如何在MVC3中实现这一过程,包括视图、控制器、模型和模型绑定器的编写方法。
首先,需要在项目中添加一些必要的库和引用。例如,需要引入Douglas Crockford创建的Json2库,以及System.Reflection和System.Web.Script.Serialization这两个命名空间,以便在模型绑定器中使用。
在视图层,需要创建一个按钮,当用户点击这个按钮时,会触发一个名为ComeOnJson的JavaScript函数。这个函数会将数据以JSON格式发送到服务器。
以下是视图的HTML代码:
<input type="button" value="Come on Json" onclick="javascript:ComeOnJson()" id="jsonResult" />
<script language="javascript" type="text/javascript">
var data = [{
"lastName": "Orue",
"firstName": "Esteban",
"phones": [{
"type": "Mobile",
"number": "(011) 4121-2121"
},
{
"type": "Home",
"number": "(011) 4123-4567"
}]
},
{
"firstName": "Sensei",
"lastName": "Miyagi",
"phones": [{
"type": "Mobile",
"number": "(011) 4121-7777"
},
{
"type": "Home",
"number": "(011) 4121-9999"
}]
}];
function ComeOnJson(){
alert(JSON.stringify(data));
$.ajax({
url: '/Home/CollectJsonData',
data: JSON.stringify(data),
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(result) {
alert(result);
},
error: function() {
alert("error");
}
});
}
</script>
在控制器中,需要定义一个名为CollectJsonData的方法,这个方法将接收从客户端发送的JSON数据,并将其转换为一个对象列表。然后,可以对这个对象列表进行处理,例如返回第一个对象的firstName属性。
以下是控制器的C#代码:
[HttpPost]
public ActionResult CollectJsonData(List<Person> person)
{
return Json(data: person[0].firstName.ToString());
}
在模型层,需要定义两个类:Person和Phone。Person类表示一个人,包含firstName、lastName和phones属性。Phone类表示一个电话号码,包含type和number属性。
以下是模型的C#代码:
public class Person
{
public string firstName { get; set; }
public string lastName { get; set; }
public List<Phone> phones { get; set; }
}
public class Phone
{
public string type { get; set; }
public string number { get; set; }
}
为了能够将JSON数据绑定到模型,需要自定义一个模型绑定器。这个模型绑定器会检查请求的Content-Type是否为application/json,如果是,则将JSON数据反序列化为模型对象。
以下是模型绑定器的C#代码:
using System.Reflection;
using System.Web.Script.Serialization;
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;
var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();
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);
return deserializerMethod.Invoke(serializer, new object[] { serializer, input, objType, serializer.RecursionLimit });
}
}
最后,在全局配置文件中,需要将默认的模型绑定器替换为自定义的JsonModelBinder。这样,当MVC框架处理请求时,就会使用模型绑定器来处理JSON数据。
protected void Application_Start()
{
// AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.DefaultBinder = new JsonModelBinder();
RegisterRoutes(RouteTable.Routes);
}