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. mySQL 教程 第7章 存储过程和函数

    存储过程和存储函数 MySQL的存储过程(stored procedure)和函数(stored function)统称为stored routines. 1. MySQL存储过程和函数的区别 函数只 ...

  2. CentOS安装Git

    准备安装Gityum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel #下载git-1 ...

  3. snapshot standby database

    快照备库接收和归档主库发送来的redo,但是不会应用:切换成physical standby之后会自动开启redo apply.快照standby不可以参加主备切换:在最大保护性模式下,如果只有一个备 ...

  4. mongodb的基本操作与插入文档(document)

    一.mongodb的基本操作: 1.查看mongodb当前所有的databases : show dbs 2.选择数据库(database) : use databaseName(该数据库不存在则会自 ...

  5. UEditor和CKEditor配置上传图片,视频,附件

    UEditor: http://blog.sina.com.cn/s/blog_8bb128230102v12x.html CKEditor:http://blog.sina.com.cn/s/blo ...

  6. Leetcode: Trapping Rain Water II

    Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...

  7. SQL 数据库备、还,附、分,数据查询,聚合函数

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...

  8. CCF真题之最大矩形

    201312-3 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩形构成了一个直方图.例如,下图中六个矩形的高度就分别是3, 1, 6 ...

  9. kafka迁移数据目录

    问题 先前存储kafka日志的磁盘空间太小,zabbix警报不断,于是加了磁盘,将日志存到新磁盘上. 解决方案 依次在每台机器上操作,保证有机器能响应producer和consumer的操作. 加磁盘 ...

  10. Android DatePickerDialog TimepickerDialog

    package com.example.myact5; import java.util.Calendar; import android.app.DatePickerDialog; import a ...