《ASP.NET MVC 4 实战》学习笔记 11:模型绑定器与值提供器

一、创建自定义模型绑定器:

利用请求数据塑造模型对象并将对象传递给动作参数的过程称为模型绑定(Model Binding)。

大多数时候动作参数是对象的主键或其他唯一标识符,因此我们可以不必在所有的动作中都放置一段重复的数据访问代码(下面代码“\\Before”部分),而是使用一个自定义的模型绑定器(下面代码“\\After”部分)。它能够在动作执行之前加载存储对象,于是动作不再以唯一标识符而是以持久化的对象类型作为参数。

// Before
public ViewResult Edit (Guid id)
{
  var profile=_profileRepository.GetById(id);
  return View(new ProfileEditModel(profile));
}

// After
public ViewResult Edit (Profile id)
{
  return View(new ProfileEditModel(id));
}

MVC的可扩展性允许我们注册模型绑定器,这是通过为某一模型类型指定应该使用的绑定器来实现的。但是在实体比较多的情况下,比较理想的情况是我们只对一个公共基类型(Common Base Type)的自定义模型绑定器进行一次注册或者让每个自定义绑定器自己决定是否应该绑定。为了实现这一功能我们需要同时提供自定义模型绑定器提供器和自定义模型绑定器。提供器是由MVC框架使用的以决定使用哪一个模型绑定器进行模型绑定。

为了实现一个自定义模型绑定器提供器,我们需要实现IModelBinderProvider接口:

public interface IModelBinderProvider
{
  IModelBinder GetBinder(Type modelType)
}

任何想要运用自定义匹配逻辑的IModelBinderProvider的实现只需要检测传过来的模型类型,并判断能否返回自定义模型绑定器实例。

自定义模型绑定器提供器的一个实现:

public class EntityModelBinderProvider:IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        if(!typeof(Entity).IsAssignable(modelType))
            return null;
        return new EntityModelBinder();
    }
}

上例中我们首先检查modelType参数是否继承于Entity,如果不是则返回null表明该模型绑定器提供器不能为这一给定的类型提供模型绑定器,反之则返回一个EntityModelBinder(实体模型绑定器)的新实例。

完整的模型绑定器需要实现IModelBinder接口:

public class EntityModelBinder:IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext,
        ModelBinderContext bindingContext)
    {
        ValueProviderResult value=
            bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);

            if(value==null)
                return null;
            if(string.IsNullOrEmpty(value.AttemptedValue))
                return null;
            int entityId;
            if(!int.TryParse(value.AttemptedValue,out entityId))
            {
                return null;
            }
            Type repositoryType=typeof(IRepository<>)
            .MakeGenericType(bindingContext.ModelType);
            var repository=(IRepository)ServiceLocator
            .Resolve(repositoryType);
            Entity entity=repository.GetById(entityId);
            return entity;
    }
}        

public interface IRepository<TEntity>
    where TEntity:Entity
{
    TEntity Get(int id);
}

注册自定义模型绑定器提供器:

protected void Application_Start()
{
    ModelBinderProviders.BinderProviders
    .Add(new EntityModelBinderProvider());
}

二、使用自定义值提供器:
通过建立额外的自定义值提供器我们可以进一步消除控制器范文动作中的查询代码:

// Before
public ViewResult LogOnWidget(LogOnWidgetModel model)
{
    bool inAuthenticated=Request.IsAuthenticated;
    model.IsAuthenticated=isAuthenticated;
    model.CurrentUser=Session[""];
    return View(model);
}

// After
public ViewResult LogOnWidget(LogOnWidgetModel model)
{
    bool inAuthenticated=Request.IsAuthenticated;
    model.IsAuthenticated=isAuthenticated;
    return View(model);
}
    

我感觉还是暂且略过吧,搞不懂。。。

时间: 2024-10-06 07:35:36

《ASP.NET MVC 4 实战》学习笔记 11:模型绑定器与值提供器的相关文章

ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

首页 头条 文章 频道                         设计频道 Web前端 Python开发 Java技术 Android应用 iOS应用 资源 小组 相亲 频道 首页 头条 文章 小组 相亲 资源 设计 前端 Python Java 安卓 iOS 登录 注册 首页 最新文章 经典回顾 开发 Web前端 Python Android iOS Java C/C++ PHP .NET Ruby Go 设计 UI设计 网页设计 交互设计 用户体验 设计教程 设计职场 极客 IT技术

ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习

一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留下来的ASPX引擎或者第三方的NVelocity模板引擎. Razor在减少代码冗余.增强代码可读性和Visual Studio智能感知方面,都有着突出的优势.Razor一经推出就深受广大ASP.Net开发者的喜爱. 1.2 Razor的语法 (1)Razor文件类型:Razor支持两种文件类型,分

ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. 但是,如果手写Html标签效率又比较低,可重用度比较低.这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码: <input name="UserName&quo

ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器

一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据模型中的各个字段的验证.这些特性用于定义常见的验证模式,例如范围检查和必填字段.而 DataAnnotations 特性使 MVC 能够提供客户端和服务器验证检查,使你无需进行额外的编码来控制数据的有效. 通过为模型类增加数据描述的 DataAnnotations ,我们可以容易地为应用程序增加验证

ASP.Net MVC开发基础学习笔记(1):走向MVC模式

链接地址:http://blog.jobbole.com/84992/ 一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/blog/index.aspx的URL,那么我们的WebForm程序会到网站根目录下去寻找blog目录下的index.aspx文件,然后由index.aspx页面的CodeBehind文件(.CS文件)进行逻辑处理,其中或许也包括到

ASP.Net MVC开发基础学习笔记:一、走向MVC模式

一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/blog/index.aspx的URL,那么我们的WebForm程序会到网站根目录下去寻找blog目录下的index.aspx文件,然后由index.aspx页面的CodeBehind文件(.CS文件)进行逻辑处理,其中或许也包括到数据库去取出数据(其中的经过怎样的BLL到DAL这里就不谈了),然后再由

ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新的区域,可以让我们的项目不至于太复杂而导致管理混乱.有了区域后,每个模块的页面都放入相应的区域内进行管理很方便.例如:上图中有两个模块,一个是Admin模块,另一个是Product模块,所有关于这两个模块的控制器.Model以及视图都放入各自的模块内.可以从上图中看出,区域的功能类似一个小的MVC项

ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法

一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. 但是,如果手写Html标签效率又比较低,可重用度比较低.这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码: 1 <input name="UserName&q

ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新的区域,可以让我们的项目不至于太复杂而导致管理混乱.有了区域后,每个模块的页面都放入相应的区域内进行管理很方便.例如:上图中有两个模块,一个是Admin模块,另一个是Product模块,所有关于这两个模块的控制器.Model以及视图都放入各自的模块内.可以从上图中看出,区域的功能类似一个小的MVC项