MVC应用中的数据绑定和自定义格式化

MVC框架中,数据绑定和请求/响应处理是框架的关键可扩展点之一。本文将介绍如何在MVC应用中实现自定义数据格式的绑定和处理。

自定义格式化器

自定义格式化器非常有用,尤其是当需要发送或接收JSON或XML以外的数据结构时。虽然MVC默认支持这两种数据编码方案,但更好的解决方案可能是编写自定义格式化器并将其集成到MVC框架中。例如,如果有一些逗号分隔的信息想要传递给API,将展示如何使用自定义格式化器处理这样的值。

首先,定义了一个简单的数据传输对象(DTO)类:

public class Person { public string Name { get; set; } public string Surname { get; set; } }

接下来,创建了一个名为CommaFormatter的类,它继承自BufferedMediaTypeFormatter。在构造函数中,选择了MIME类型:

public class CommaFormatter : BufferedMediaTypeFormatter { public CommaFormatter() { SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/colon")); } public override bool CanReadType(Type type) { if (type == typeof(Person) || type == typeof(List)) return true; else return false; } public override bool CanWriteType(Type type) { if (type == typeof(Person) || type == typeof(List)) return true; else return false; } public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) { List<Person> Obj = new List<Person>(); Person p = null; StreamReader reader = new StreamReader(readStream); string str = reader.ReadToEnd(); string[] propArr = str.Split(','); foreach (var item in propArr) { string[] propAttribute = item.Split('|'); p = new Person(); foreach (var item1 in propAttribute) { string[] propAttribute1 = item1.Split('='); if (propAttribute1[0].ToLower().Trim().Equals("name")) { p.Name = propAttribute1[1]; } if (propAttribute1[0].ToLower().Trim().Equals("surname")) { p.Surname = propAttribute1[1]; } } Obj.Add(p); } return Obj; } }

现在,需要在全局配置页面中注册这个格式化器,以便它在MVC中被注册:

GlobalConfiguration.Configuration.Formatters.Add(new CommaFormatter());

APIPost方法中,尝试传递“Person”列表:

public class CustomController : ApiController { [HttpPost] public void Post(List<Person> p) { } }

请确保在请求头中设置了“Content-Type”。可以观察到,负载是自定义的数据格式,并且绑定到动作方法。

自定义模型绑定

这是另一种将未格式化数据绑定MVC端点的方法。想象一下,数据来自查询字符串的场景。知道,如果查询字符串的键与模型属性匹配,MVC默认能够智能绑定。但如果查询字符串与模型属性不匹配呢?自定义模型绑定器就派上用场了。用一个简单的“Person”模型来演示这个例子。

创建了一个名为PersonModelBinder的类,它继承自DefaultModelBinder并覆盖了BindModel方法。在这个方法中,从请求上下文中获取查询字符串的值,并将其作为Person模型的具体对象返回:

public class PersonModelBinder : DefaultModelBinder { public PersonModelBinder() { } public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var request = controllerContext.HttpContext.Request; string name = request.QueryString["name"]; string surname = request.QueryString["surname"]; return new Person { Name = name, Surname = surname }; } }

以下是将自定义格式化器集成到MVC管道中的步骤:

ModelBinders.Binders.Add(typeof(Person), new PersonModelBinder());

为了将数据作为参数接收,必须使用ModelBinder属性:

public class CustomController : Controller { public void Post([ModelBinder(typeof(PersonModelBinder))] Person p) { } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485