MVC--DefaultModelBinder解析request参数
转载:http://www.cnblogs.com/leotsai/p/ASPNET-MVC-DefaultModelBinder.html
看到很多ASP.NET MVC项目还在从request.querystring或者formContext里面获取数据,这实在是非常落后的做法。也有的项目建了大量的自定义的modelbinder,以为很牛,实际上也落后的很。
ASP.NET MVC提供了IModelBinder的默认实现,这个实现的类就叫DefaultModelBinder。我们在写代码的时候,几乎感觉不到这个类的存在,因为这个类自动将request信息解析成action参数。本文将向大家展示这个类是多么强大,可以拯救大量的代码。
先看个例子。假如有如下表单,用于编辑用户信息以及该用户的时间表。在这个例子中,我要利用DefaultModelBinder自动将整个表单数据解析成复杂实体类的实例。一行手工解析的C#代码都不用写。
对应的controller的代码如下,很简单:
public class DemoController : PublicControllerBase
{
public ActionResult UserEditor()
{
return View();
} [HttpPost]
public string SaveUser(DemoUser user)
{
var result = string.Empty;
if (user != null)
{
result = Serializer.ToJson(user);
}
return result;
}
}
相关的实体类的定义,也很简单:
public class DemoUser
{
public string Username { get; set; }
public string Email { get; set; }
public string Language { get; set; }
public Gender Gender { get; set; }
public int[] RoleIds { get; set; }
public List<ScheduledJob> Jobs { get; set; }
} public class ScheduledJob
{
public string Job { get; set; }
public string From { get; set; }
public string To { get; set; }
} public enum Gender
{
Unknown = ,
Male = ,
Female =
}
请注意SaveUser这个action的参数,一个比较复杂的实体类的对象。DefaultModelBinder会自动将这个复杂的表单解析出来。这个保存的action将参数user直接序列化JSON字符串返回到浏览器。
下面看看HTML和JS。
HTML:
<form id="formUserEditor" action="/demo/saveuser" method="POST">
<table class="form">
<colgroup>
<col width="100"/>
<col width="auto"/>
</colgroup>
<tbody>
<tr>
<td>用户名:</td>
<td>
<input id="txtUsername" type="text" name="username" />
</td>
</tr>
<tr>
<td>Email:</td>
<td>
<input id="txtEmail" type="text" name="email" />
</td>
</tr>
<tr>
<td>语言:</td>
<td>
<select id="ddlLanguages" name="language">
<option value="zh-cn">中文</option>
<option value="en-us">英文</option>
</select>
</td>
</tr>
<tr>
<td>性别:</td>
<td id="genders">
<input type="radio" name="gender" value="@(Taoad.Web.Publics.Controllers.Gender.Unknown)" id="rdUnknown" />
<label for="rdUnknown">未知</label>
<input type="radio" name="gender" value="@(Taoad.Web.Publics.Controllers.Gender.Male)" id="rdMale" />
<label for="rdMale">男</label>
<input type="radio" name="gender" value="@(Taoad.Web.Publics.Controllers.Gender.Female)" id="rdFemale" />
<label for="rdFemale">女</label>
</td>
</tr>
<tr>
<td>角色:</td>
<td id="roles">
<input type="checkbox" name="roleids" value="1" id="cb1" />
<label for="cb1">管理员</label>
<input type="checkbox" name="roleids" value="2" id="cb2" />
<label for="cb2">部门经理</label>
<input type="checkbox" name="roleids" value="3" id="cb3" />
<label for="cb3">客户</label>
</td>
</tr>
<tr>
<td>时间:</td>
<td>
<ul id="jobs">
</ul>
<input type="button" value="添加" id="btnAddJob"/>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="button" value="保存" id="btnSave"/>
<input type="button" value="取消" id="btnCancel" />
</td>
</tr>
</tbody>
</table>
</form>
<hr/>
<div id="json">
</div>
JS:
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#btnAddJob").click(function() {
var $newLi = $(html);
$("#jobs").append($newLi);
bindLi($newLi);
}); $("#btnSave").click(function() {
var data = $("#formUserEditor").serialize();
$("#jobs li").each(function(i) {
var prefix = "&jobs[" + i + "]";
data += prefix + ".job=" + $(this).find(".job-id").val();
data += prefix + ".from=" + $(this).find(".job-from").val();
data += prefix + ".to=" + $(this).find(".job-to").val();
});
demo.ajax.post("/demo/saveuser", data, function(json) {
$("#json").html(json);
});
});
}); function bindLi(li) {
$(li).find(".btn-add").click(function () {
var $li = $(this).closest("li");
var $newLi = $(html);
$li.after($newLi);
bindLi($newLi);
});
$(li).find(".btn-delete").click(function () {
$(this).closest("li").remove();
});
} var html = '<li>\
<select class="job-id">\
<option value="job1">工作1</option>\
<option value="job2">工作2</option>\
</select>\
<input type="text" placeholder="开始时间" class="job-from"/>\
————\
<input type="text" placeholder="结束时间" class="job-to"/>\
<a href="javascript:void(0);" class="btn-add">添加</a> |\
<a href="javascript:void(0);" class="btn-delete">删除</a>\
</li>';
</script>
如果是如下的表单数据:
点击保存之后,返回的JSON数据为:
可以看到所有的表单数据都保存成功了。
再看看request信息:
请注意content-type的值。
实际上,POST到服务器的表单数据只是一个字符串,如下:
复制出来就是下面这样的字符串:
ajax=true&username=leo&email=leo%40gmail.com&language=zh-cn&gender=Unknown&roleids=1&roleids=3&jobs[0].job=job1&jobs[0].from=9:00&jobs[0].to=10:00&jobs[1].job=job2&jobs[1].from=10:00&jobs[1].to=11:00
由此可知,可用JS来拼接字符串,将整个表单通过键值对的形式序列化成一个字符串,再将该字符串传到服务器,这时DefaultModelBinder就可以自动解析实体类了。
关键点在于,对于List或者数组类型的数据,要加上数组下标。这样,任意复杂的数据结构,DefaultModelBinder都可以自动解析了。
MVC--DefaultModelBinder解析request参数的更多相关文章
- MVC路由解析---MapRoute
文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 引言 前面我们讲了IgnoreRout ...
- MVC路由解析---UrlRoutingModule
文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 引言: 此文全文内容90%转自 一.前 ...
- [置顶]
MVC输出缓存(OutputCache参数详解)
1.学习之前你应该知道这些 几乎每个项目都会用到缓存,这是必然的.以前在学校时做的网站基本上的一个标准就是1.搞定增删改查2.页面做的不要太差3.能运行(ps真的有这种情况,答辩验收的时候几个人在讲台 ...
- MVC输出缓存(OutputCache参数详解)
版权声明:本文为博主原创文章,未经博主允许转载随意. https://blog.csdn.net/kebi007/article/details/59199115 1.学习之前你应该知道这些 几乎每个 ...
- Spring MVC的Post请求参数中文乱码的原因&处理
一.项目配置: Spring 4.4.1-RELEASE Jetty 9.3.5 JDK 1.8 Servlet 3.1.0 web.xml文件中没有配置编解码Filter 二.实际遇到的问题:客户端 ...
- Netty实现java多线程Post请求解析(Map参数类型)—SKY
netty解析Post的键值对 解析时必须加上一个方法,ch.pipeline().addLast(new HttpObjectAggregator(2048)); 放在自己的Handel前面. ht ...
- django-rest-framework解析请求参数
django-rest-framework解析请求参数 前言 前面的文章中编写了接口, 调通了接口文档. 接口文档可以直接填写参数进行请求, 接下来的问题是如何接受参数, 由于请求方式与参数序列化形式 ...
- MVC路由解析---IgnoreRoute
MVC路由解析---IgnoreRoute 文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Are ...
- [源码解析] 机器学习参数服务器ps-lite (1) ----- PostOffice
[源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 目录 [源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 0x00 ...
随机推荐
- 「PKUSC2018」主斗地(暴搜)
这道斗地主比 \(PKUWC\) 那道可做多了... 我们用 \(NOIP\) 那道斗地主的思路:暴搜出三代和四代,贪心出散牌. 还有jry为什么要出xx网友而不出他的另一个老婆 我们发现两个人的每回 ...
- Linux学习笔记-基本操作2
1. 压缩包管理2. 进程管理3. 网路管理4. ftp服务器搭建5. nfs服务器搭建6. ssh服务器7. scp命令8. 其他命令9. 关机重启 1. 压缩包管理 1>. 屌丝版:不能对目 ...
- 7. Bagging & Random Forest
通过前面集成学习的介绍我们知道,欲得到泛化性能强的集成学习器,集成中个体学习器应尽量相互独立:虽然“独立”在现实任务中无法做到,但可以设法使基学习器尽可能具有较大差异. 1. Bagging 自助采样 ...
- python 跨平台获取网卡信息和本机ip地址
笔者在项目中遇到过获取本机网卡ip的例子,利用python库psutil解决了此问题. def get_netcard(): """获取网卡名称和ip地址 "& ...
- Build OpenJdk
1 ,下载源代码 nuget 2,说明文档 http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html 2,安装 Cy ...
- odoo 开发基础 -- postgresql重新启动、状态查看
场景描述: 当遇到数据库不能正常访问的时候,我们首先想到的是,查看相关的告警日志,一般先查看系统的日志,然后查看数据库的日志,Linux平台下,postgresql的日志文件存放目录在如下路径: te ...
- Log4j 相关
Log4j(Log for Java) Log4j是Apache提供的一种专门用于Java程序记录日志的工具,是目前主流的开发日志技术. 日志的作用: 1.记录系统运行过程中的重要运行信息 a) 付费 ...
- Apache版本的Hadoop HA集群启动详细步骤【包括Zookeeper、HDFS HA、YARN HA、HBase HA】(图文详解)
不多说,直接上干货! 1.先每台机器的zookeeper启动(bigdata-pro01.kfk.com.bigdata-pro02.kfk.com.bigdata-pro03.kfk.com) 2. ...
- windows系统搭建禅道系统(BUG管理工具)
我也呆过三家公司了,用过的BUG管理工具也是五花八门的,常见的一般有禅道,bugzilla,jira等 个人比较推荐禅道,功能强大,主页的说明文档也是相当详细,最主要的是,用的人比较多,出现使用问题一 ...
- T-SQL触发器,限制一次只能删除一条数据
/****** Object: Trigger [dbo].[trg_del] Script Date: 01/01/2016 12:58:28 ******/ SET ANSI_NULLS ON G ...