ASP.NET MVC中的模型绑定(ModerBinder)和简单场景

Table of Contents

1 模型绑定

先看一个普通的方法:

public ActionResult Index(Student student)
{
    return View();
}

这个方法接受的参数是一个Student对象,前端传递过来的参数跟Student对象里的属性保持一直,那么就自动被绑定到这个对象里了,不需要在方法里new Student这个对象并挨个绑定属性了,绑定的过程由MVC中的DefaultModelBinder完成的,DefaultModelBinder同时继承了IModelBinder接口,现在就利用IModelBinder接口和DefaultModelBinder来实现更加灵活的模型绑定。

2 简单场景

2.1 IModelBinder相关

场景一、前端传过来了一个加密的字符串token,方法里需要用token里的某些字段,那就得在方法里接收这个字符串、解密字符串、转换成对象,这样一个方法还好说,多了的话重复代码非常多,就算提取通用方法,还是要在方法里调用这个通用方法,有没有办法直接在参数里就封装好这个对象?

模型绑定的对象:

public class TokenModel
{
    /// <summary>
    /// 主键
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name { set; get; }

    /// <summary>
    /// 简介
    /// </summary>
    public string Description { get; set; }

}

新建一个TokenBinder继承IModelBinder接口并实现其中的BindModel方法:

public class TokenBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
      ModelBindingContext bindingContext)
    {
        var token = controllerContext.HttpContext.Request["token"];
        if (!string.IsNullOrEmpty(token))
        {
            string[] array = token.Split(':');
            if (array.Length == 3)
            {
                return new TokenModel() 
                    { Id = int.Parse(array[0]),
                      Name = array[1], Description = array[2] };
            }
            else
            {
                return new TokenModel() { Id = 0 };
            }
        }
        else
        {
            return new TokenModel() { Id = 0 };
        }
    }
}

这个方法里接收了一个token参数,并对token参数进行了解析和封装。代码部分完成了需要到Application-Start方法里进行下注册:

ModelBinders.Binders.Add(typeof(TokenModel), new TokenBinder());

模拟接口:

public JsonResult TokenBinderTest(TokenModel tokenModel)
{
    var output = "Id:" + tokenModel.Id + ",Name:" 
      + tokenModel.Name + ",Description:" + tokenModel.Description;
    return Json(new ReturnModel_Common { msg = output });
}

2.2 DefaultModelBinder相关

场景二、去除对象某个属性的首位空格

public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Class { get; set; }
}

如果前端传来的Name属性有空格,如何去除呢?利用DefaultModelBinder即可实现更灵活的控制

public class TrimModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext,
      ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor,
      IModelBinder propertyBinder)
    {
        var obj = base.GetPropertyValue(controllerContext, bindingContext,
          propertyDescriptor, propertyBinder);
        //判断是string类型且有[Trim]标记
        if (obj is string
            && propertyDescriptor.Attributes[typeof(TrimAttribute)] != null)
        {
            return (obj as string).Trim();
        }
        return obj;
    }
}

标注下需要格式化首位属性的实体:

[ModelBinder(typeof(TrimModelBinder))]
public class Student
{
    public int Id { get; set; }

    [Trim]
    public string Name { get; set; }

    public string Class { get; set; }
}

模拟接口:

public JsonResult TrimBinderTest(Student student)
{
    if (string.IsNullOrEmpty(student.Name) || string.IsNullOrEmpty(student.Class))
    {
        return Json(new ReturnModel_Common { msg = "未找到参数" });
    }
    else
    {
        return Json(new ReturnModel_Common 
          { msg = "Name:" + student.Name + ",长度:" 
              + student.Name.Length + " Class:"
              + student.Class + ",长度:" + student.Class.Length });
    }
}

3 其他参考