一起谈.NET技术,ASP.NET MVC & EF 构建智能查询 二、模型的设计与ModelBinder

  在第一篇中,我讲解了我们要做智能查询的原因,以及基本的解决方案设计。从这篇开始我们开始讲解它的实现过程。

  其实在写这一系列文章之初,我其实是想由底至上去讲解,但是我又整理了一遍代码才发现,其实如果不了解最表面的东西,也是不太好深入的。

  所以我们的第二篇文章就来讲一下我们这个智能查询框架中最浅,但也是使用最频繁的部分,也就是Model。

  首先我们的Entity  或者说数据库的结构如下:

  另外如下面代码,我们有一个用于传递name=value对,及查询谓词的model:


public ActionResult Index(QueryModel model)
{
using(var db=new DbEntities())
{
var list = db.Users.Where(model).ToList();
return View(list);
}
}

  我命名之为QueryModel。它由Action的参数传入,再传入EF的Where扩展方法,它是构建Lambda表达式的原型,上面是我们的一个通用的查询Action的代码。

  而QueryModel的代码为:

  QueryModel的唯一一个属性Items,是一个ConditionItem的集合,它里面存着所有的查询条件。而ConditionItem里面的属性:

  1. Field表示要查询的目标属性的名称,我们的设定它是支持子属性查询的,例如 “Profile.MyUser.Id”。
  2. Method则是当前使用的谓词,它是QueryMethod的一个枚举值。
  3. OrGroup是一个字符串,是一个OrGroup的多个表达式将会以Or操作符进行关联,然后再And。
  4. Prefix是一个分类的前缀,我们假定一个Action可能处理多个查询条件组的时候为了分开这些查询条件而加的属性。
  5. Value则是这个表达试的值。

  而我们在页面上类似:


<form action="" method="post">
姓名:<input id="Name" name="[Like]Name" type="text" value="" />
Email:<input id="Email" name="[Equal]Email" type="text" value="" /><br />
Id: <input id="Id" name="[Equal]Id" type="text" value="" />
生日: <input id="Birthday" name="[Equal]Birthday" type="text" value="" /><br />
<input type="submit" value="查询" />
</form>

  这样的表单,我们提交到服务器端,我们要进行ASP.NET MVC 中IModelBinder的转换,要将querystring 或 postdata中的KeyValuePair转换为我们的ConditionItem。

  当然,我们除了谓词Method之外,还有Prefix以及OrGroup要从客户端提交过来所以我们就要制定一个规则,我们约定:

  1. 中括号[]中的为查询谓词
  2. 小括号()中的为前缀Prefix
  3. 大括号{}中的为OrGroup

  我们可以通过以下IModelBinder的实现将Request.QueryString或Request.Form中的值转换到QueryModel中:


public class SearchModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = (QueryModel)(bindingContext.Model ?? new QueryModel());
var dict = controllerContext.HttpContext.Request.Params;
var keys = dict.AllKeys.Where(c => c.StartsWith("["));//我们认为只有[开头的为需要处理的
if (keys.Count() != 0)
{
foreach (var key in keys)
{
if (!key.StartsWith("[")) continue;
var val = dict[key];
//处理无值的情况
if (string.IsNullOrEmpty(val)) continue;
AddSearchItem(model, key, val);
}
}
return model;
}

/// <summary>
/// 将一组key=value添加入QueryModel.Items
/// </summary>
/// <param name="model">QueryModel</param>
/// <param name="key">当前项的HtmlName</param>
/// <param name="val">当前项的值</param>
public static void AddSearchItem(QueryModel model, string key, string val)
{
string field = "", prefix = "", orGroup = "", method = "";
var keywords = key.Split(']', ')', '}');
//将Html中的name分割为我们想要的几个部分
foreach (var keyword in keywords)
{
if (Char.IsLetterOrDigit(keyword[0])) field = keyword;
var last = keyword.Substring(1);
if (keyword[0] == '(') prefix = last;
if (keyword[0] == '[') method = last;
if (keyword[0] == '{') orGroup = last;
}
if (string.IsNullOrEmpty(method)) return;
if (!string.IsNullOrEmpty(field))
{
var item = new ConditionItem
{
Field = field,
Value = val.Trim(),
Prefix = prefix,
OrGroup = orGroup,
Method = (QueryMethod) Enum.Parse(typeof (QueryMethod), method)
};
model.Items.Add(item);
}
}
}

  当然我们还要在Global.asax中添加:


ModelBinders.Binders.Add(typeof (QueryModel), new SearchModelBinder());

  这样我们就可以在Action中获取到相应的查询条件了:

  我们可以看到,从表单提交过来的数据我们已经正确地存放在QueryModel中了。

时间: 2024-09-15 23:13:55

一起谈.NET技术,ASP.NET MVC &amp; EF 构建智能查询 二、模型的设计与ModelBinder的相关文章

ASP.NET MVC &amp;amp; EF 构建智能查询 二、模型的设计“.NET研究”与ModelBinder

在第一篇中,我讲解了我们要做智能查询的原因,以及基本的解决方案设计.从这篇开始我们开始讲解它的实现过程. 其实在写这一系列文章之初,我其实是想由底至上去讲解,但是我又整理了一遍代码才发现,其实如果不了解最表面的东西,也是不太好深入的. 所以我们的第二篇文章就来讲一下我们这个智能查询框架中最浅,但也是使用最频繁的部分,也就是Model. 首先我们的Entity  或者说数据库的结构如下: 另外如下面代码,我们有一个用于传递name=value对,及查询谓词的model: public Action

ASP.NET MVC &amp;amp; EF 构建智能查询 一、智“.NET研究”能查询的需求与设计

关于复用 在我们日常的开发过程中,代码的复用其实是很重要的一部分,ASP.NET MVC框架本身为我们提供了很多很好的复用机制,让我们能充分地利用它们来节省我们的Coding成本. 在简单的Coding中,我们可以通过构造方法来实现代码段的复用,在OOP编程中我们可以使用继承多态来进行类的复用,我们也可以使用设计模式来做类或对象间的代码设计的复用,随着程序的复杂我们就想构造出更佳的复用方式,可以向更高层次上抽象. 应用场景与目标 在信息管理系统中我们会开发大量的List页面,它们功能上通常是非常

ASP.NET MVC &amp; EF 构建智能查询 二、模型的设计与ModelBinder

在第一篇中,我讲解了我们要做智能查询的原因,以及基本的解决方案设计.从这篇开始我们开始讲解它的实现过程. 其实在写这一系列文章之初,我其实是想由底至上去讲解,但是我又整理了一遍代码才发现,其实如果不了解最表面的东西,也是不太好深入的. 所以我们的第二篇文章就来讲一下我们这个智能查询框架中最浅,但也是使用最频繁的部分,也就是Model. 首先我们的Entity  或者说数据库的结构如下 另外如下面代码,我们有一个用于传递name=value对,及查询谓词的model 1: public Actio

ASP.NET MVC &amp; EF 构建智能查询 一、智能查询的需求与设计

关于复用 在我们日常的开发过程中,代码的复用其实是很重要的一部分,ASP.NET MVC框架本身为我们提供了很多很好的复用机制,让我们能充分地利用它们来节省我们的Coding成本. 在简单的Coding中,我们可以通过构造方法来实现代码段的复用,在OOP编程中我们可以使用继承多态来进行类的复用,我们也可以使用设计模式来做类或对象间的代码设计的复用,随着程序的复杂我们就想构造出更佳的复用方式,可以向更高层次上抽象.   应用场景与目标 在信息管理系统中我们会开发大量的List页面,它们功能上通常是

ASP.NET MVC &amp; EF 构建智能查询 三、解析QueryModel

ASP.NET MVC & EF 构建智能查询 一.智能查询的需求与设计 ASP.NET MVC & EF 构建智能查询 二.模型的设计与ModelBinder 上节说到我们已经将表单转化为了QueryModel 并且将查询条件按我们的设计存为了ConditionItem.并且传递到了IQueryable.Where扩展方法中,对EF进行了查询: 当然,这里的Where是一个IQueryable的扩展方法,其中调用了将QueryModel转换为Expression表达式的类Queryabl

ASP.NET MVC小结之基础篇(二)_实用技巧

整理除了这个笔记,共享一下子,基本MVC的所有东西都介绍了,但是都是很基础的东西.本来打算一篇发表完的,但是发现东西有点多,所以分成了两篇文章,这是最后一篇了! 1.ASP.NET MVC请求过程 1 2.Controller (1) 控制器在ASP.NET MVC中扮演着处理客户端请求的角色 1)必须实现System.Web.Mvc.IController接口 ->通常直接继承System.Web.MVC.Controller类 2)必须要以Controller结尾 3)通过不同的Action

一起谈.NET技术,WCF+WF双剑合璧构建微软的SOA系列(一):从一个简单的Demo开始

本系列文章将从实例出发,以实例结尾.由浅入深讲解在我们项目中如何使用WCF和WF.我们会发现使用WCF+WF将造就出其他技术无法达到的高度.最后我会将程序架到云端. 微软.net的3W(WPF.WCF.WF)战略如下图.WCF负责通信,WPF负责界面展示,WF负责处理业务逻辑,如下图. 本系列文章会主要用到上图中的所有技术,但是主要讲述如何使用WCF和WF来实现系统的中间层.看过亮剑的朋友知道李云龙常打胜仗,并不是他懂得很多很多的战争的理论知识,而是来自实战中的经验.所以本系列的文章以实战为核心

ASP.NET MVC 音乐商店 - 10. 完成导航和站点的设计

转自 http://www.cnblogs.com/haogj/archive/2011/11/20/2255680.html 我们已经完成了网站的大部分工作,但是,还有一些添加到站点的导航功能,主页,以及商店的浏览页面. 创建购物车汇总部分视图 我们希望在整个站点的页面上都可以看到购物车中的数量.                         通过创建一个部分视图,然后添加到网站的布局中就可以容易地完成, 前面看到,在 ShoppingCart 控制器中包含了一个名为 CartSummary

ASP.NET MVC 音乐商店 - 6. 使用 DataAnnotations 进行模型验证

转自http://www.cnblogs.com/haogj/archive/2011/11/16/2251920.html 在前面的创建专辑与编辑专辑的表单中存在一个问题:我们没有进行任何验证.字段的内容可以不输入,或者在价格的字段中输入一些字符,在执行程序的时候,这些错误会导致数据库保存过程中出现错误,我们将会看到来自数据库的错误信息. 通过为模型类增加数据描述的 DataAnnotations ,我们可以容易地为应用程序增加验证的功能.DataAnnotations  允许我们描述希望应用