Model Binding


本文已经同步到《Asp.net Vnext 系列教程 》中]

Model binding(绑定)简单来说就是通过遍历ValueProvider(值提供者)获取的数据对Action参数进行赋值.

在学习本篇教程,应对model binding有基础了解。

DefaultPropertyBindingPredicateProvider


DefaultPropertyBindingPredicateProvider:提供一种基于表达式的方法来提供包括的属性。

    public class DefaultPropertyBindingPredicateProvider<TModel> : IPropertyBindingPredicateProvider where TModel : class
{
public DefaultPropertyBindingPredicateProvider(); public virtual string Prefix { get; }
public virtual Func<ModelBindingContext, string, bool> PropertyFilter { get; } public virtual IEnumerable<Expression<Func<TModel, object>>> PropertyIncludeExpressions { get; }
}

这个类有三个属性:

Prefix 表示前缀名
PropertyFilter :属性过滤
PropertyIncludeExpressions :属性包括表达式
来看下怎么用实例代码


     private class ExcludeUserPropertiesAtParameter : DefaultPropertyBindingPredicateProvider<User>
{
Func<ModelBindingContext, string, bool> _defaultFilter1 =
(context, propertyName) => false; public ExcludeUserPropertiesAtParameter()
{ }
public override string Prefix
{
get
{
return "user";
}
} public override IEnumerable<Expression<Func<User, object>>> PropertyIncludeExpressions
{ get
{ yield return m => m.RegisterationMonth;
yield return m => m.UserName;
}
}
}
控制器
  public class BindAttributeController : Controller
{
public User EchoUser([Bind(typeof(ExcludeUserPropertiesAtParameter))] User user)
{
return user;
}

User实体


 public class User
{
[Required]
public int Id { get; set; }
public int Key { get; set; } [Required]
public string RegisterationMonth { get; set; }
public string UserName { get; set; } public Address Address { get; set; }
}


Prefix 前缀名是user,也就是说请求id必需加上user作为前缀
PropertyIncludeExpressions:属性包括:
get
{ yield return m => m.RegisterationMonth; yield return m => m.UserName; }
表示:支队这个属性进行赋值。
我们来看看PropertyFilter作用


   private class ExcludeUserPropertiesAtParameter : DefaultPropertyBindingPredicateProvider<User>
{
Func<ModelBindingContext, string, bool> _defaultFilter1 =
(context, propertyName) => false; public ExcludeUserPropertiesAtParameter()
{ }
public override string Prefix
{
get
{
return "user";
}
}
public override Func<ModelBindingContext, string, bool> PropertyFilter
{
get
{
return _defaultFilter1;
}
} }

_defaultFilter1 表达式一直返回false

全部没有赋值,
PropertyFilter:
PropertyIncludeExpressions等于null propertyFilter 将默认返回true.

FromRoute
FromQuery
FromForm
FromBody
FromHeader
FromServices


这是属性表示绑定的值从何获取

  [Route("/FromAttributes/[Action]/{HomeAddress.Street}/{HomeAddress.State}/{HomeAddress.Zip}", Name = "yangwen")]
public User_FromForm GetUser([FromRoute] Address homeAddress, [FromQuery] Address shippingAddress)
{ return new User_FromForm
{
HomeAddress = homeAddress, ShippingAddress = shippingAddress
};
}

控制器

FromRoute:从路由绑定

FromQuery:参数绑定

控制器

  [Route("/FromAttributes1",Name ="yangwen1")]
public void GetUser1( [FromForm] Address officeAddress )
{ }

视图

@model ModelBindingWebSite.Models.Address
@using (Html.BeginRouteForm("yangwen1", FormMethod.Post))
{ @Html.EditorForModel();
<input type="submit" value="Submit"> }

FromForm:表单绑定

控制器

 [HttpGet("BindToModelWithInitializedValue")]
public object BindToModelWithInitializedValue(BlogPostWithInitializedValue blogPost)
{
return new Result()
{
HeaderValue = blogPost.Host,
HeaderValues = blogPost.Tags,
ModelStateErrors = ModelState.Where(kvp => kvp.Value.Errors.Count > ).Select(kvp => kvp.Key).ToArray(),
};
}
 public class BlogPostWithInitializedValue
{
[Required]
[FromHeader]
public string Host { get; set; } = "How to Make Soup"; [FromHeader]
public string[] Tags { get; set; } = new string[] { "Cooking" }; public string Author { get; set; }
}

FromHeader:Header绑定

控制器

        public int Add(int left, int right, [FromServices] ICalculator calculator)
{
return calculator.Operation('+', left, right);
}

IOC

    services.AddSingleton<ICalculator, DefaultCalculator>();

FromServices:绑定IOC

FromBody

public void Post([FromBody]Person p)

POST http://localhost:10725/api/values?name=b&age=2HTTP/1.1
Content-Type: application/json
Host: localhost:10725
Content-Length: 30

{“Name” : “John”, “Age” : 24 }

IModelMetadataProvider


Model元数据提供者

  public class AdditionalValuesMetadataProvider : IDisplayMetadataProvider
{ private static Guid _guid = new Guid("7d6d0de2-8d59-49ac-99cc-881423b75a76"); public void GetDisplayMetadata(DisplayMetadataProviderContext context)
{

//添加附加值
context.DisplayMetadata.AdditionalValues.Add("key1", _guid);
context.DisplayMetadata.AdditionalValues.Add("key2", "value2"); }
}

启动类

   services.AddMvc()
.Configure<MvcOptions>(m =>
{ m.ModelMetadataDetailsProviders.Add(new AdditionalValuesMetadataProvider());
});

控制器

 public IReadOnlyDictionary<object, object> GetAdditionalValues([FromServices] IModelMetadataProvider provider)
{
var metadata = provider.GetMetadataForType(typeof(LargeModelWithValidation));
//输出附加值
return metadata.AdditionalValues;
}

IModelBinder


模型绑定

  private class ProductModelBinder : IModelBinder
{
public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
{
if (typeof(Product).IsAssignableFrom(bindingContext.ModelType))
{
//实例
var model = (Product)Activator.CreateInstance(bindingContext.ModelType); model.BinderType = GetType(); var key =
string.IsNullOrEmpty(bindingContext.ModelName) ?
"productId" :
bindingContext.ModelName + "." + "productId"; //获取值
var value = await bindingContext.ValueProvider.GetValueAsync(key);
model.ProductId = (int)value.ConvertTo(typeof(int)); return new ModelBindingResult(model, key, true);
} return null;
}
}

控制器

   public string GetBinderType_UseModelBinder(
[ModelBinder(BinderType = typeof(ProductModelBinder))] Product model)
{
return model.BinderType.FullName;
}

Asp.net Vnext ModelBinding的更多相关文章

  1. POCO Controller 你这么厉害,ASP.NET vNext 知道吗?

    写在前面 阅读目录: POCO 是什么? 为什么会有 POJO? POJO 的意义 POJO 与 PO.VO 的区别 POJO 的扩展 POCO VS DTO Controller 是什么? 关于 P ...

  2. 兼容Mono的下一代云环境Web开发框架ASP.NET vNext

    微软在2014年5月12日的TechEd大会上宣布将会发布下一代ASP.NET框架ASP.NET vNext的预览.此次发布的ASP.NET框架与以前相比发生了根本性的变化,凸显了微软“云优先”(cl ...

  3. 在Linux上运行ASP.NET vNext

    最新的ASP.NET vNext完全开源且可以跨多个平台运行,在Windows环境下我尝试了下,几乎没花什么工夫就跑起了Sample,而在Linux环境下则要多花了不少时间,所以特别记录下整个过程,希 ...

  4. 让 ASP.NET vNext 在 Mac OS 中飞呀飞。。。

    写在前面 阅读目录: 娓娓道来 Install ASP.NET vNext Command Line Tools 安装 Homebrew 使用 Homebrew,安装 KVM Install Subl ...

  5. Mac OS X上编写 ASP.NET vNext(一)KRE环境搭建

    最新的asp.net vnext已经可以支持在mac上运行了,当然用的是mono.相比linux来说,mac的安装略显繁琐.对于大部分用Windows开发asp.net的程序员来说,初次配置还是很费时 ...

  6. 分享我对 ASP.NET vNext 的一些感受,也许多年回过头看 So Easy!

    写在前面 阅读目录: Visual Studio "14" CTP 关于 ASP.NET vNext ASP.NET vNext 实践 后记 ASP.NET vNext 发布已经过 ...

  7. 开发 ASP.NET vNext 续篇:云优化的概念、Entity Framework 7.0、简单吞吐量压力测试

    继续上一篇<开发 ASP.NET vNext 初步总结(使用Visual Studio 2014 CTP1)>之后, 关于云优化和版本控制: 我本想做一下MAC和LINUX的self-ho ...

  8. 开发 ASP.NET vNext 初步总结(使用Visual Studio 14 CTP1)

    新特性: vNext又称MVC 6.0,不再需要依赖System.Web,占用的内存大大减少(从前无论是多么简单的一个请求,System.Web本身就要占用31KB内存). 可以self-host模式 ...

  9. ASP.NET vNext 概述

    兼容Mono的下一代云环境Web开发框架ASP.NET vNext 我们知道了ASP.NET vNext是一个全新的框架,是一个与时俱进的框架.这篇文章将深入讨论在整体架构更多的细节,文档参照 ASP ...

随机推荐

  1. ISymbol

    public void Draw (IGeometry Geometry); public void QueryBoundary (     int hDC,     ITransformation ...

  2. javaee学习之servlet

    一.tomcat相关知识 tomecat虚拟主机与虚拟路径 1.tomcat的应用默认放在webapps目录下面,可以将其放在其他目录分区,让tomcat进行管理吗? 答:当然可以.方法:配置虚拟目录 ...

  3. Hadoop学习(2)-- HDFS

    随着信息技术的高度发展,数据量越来越多,当一个操作系统管辖范围存储不下时,只能将数据分配到更多的磁盘中存储,但是数据分散在多台磁盘上非常不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,因此诞 ...

  4. java io读书笔记(7) Closing Output Streams

    输出完毕后,需要close这个stream,从而使操作系统释放相关的资源.举例: public void close( ) throws IOException 并不是所有的stream都需要clos ...

  5. c语言的基本语法

    1. 二目运算符从右往左 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右   () 圆括号 (表达式)/函数名(形参表)   . 成员选择(对象 ...

  6. JAVA-面向对象-多态

    多态 1.方法重载 2.方法重写 3.对象转型 4.抽象(可以定义类和方法)    (关键字  abstract)   ( 如: public abstract class robot  )(不能修饰 ...

  7. WebService的简单应用

    具体看项目源文件:包含: ip地址查询, QQ在线状态查询,和自定义的MD5 破解和加密(呵呵有形无势...) http://pan.baidu.com/s/1bn09WQj SOAP 1.1 The ...

  8. (转)SQL Server 2005 中的计算字段

    在实际工作上遇到的问题: 在订单表中有某项商品是将“订购数量(Quantity)”乘以“单件价格(UnitCost)”等于该项商品的总价(Subtotal). 在数据表中有的列(以下皆改叫为“字段”) ...

  9. 找到多个与名为“Index”的控制器匹配的类型的解决方法!

    “/”应用程序中的服务器错误. 找到多个与名为“Index”的控制器匹配的类型.如果为此请求(“{controller}/{action}/{id}”)提供服务的路由在搜索匹配此请求的控制器时没有指定 ...

  10. PTPX中的report 选项

    Report的生成 report_power表示产生power report,update_power表示进行power analysis. report_power命令可以生成四种形式的report ...