原文:
返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性
作者: webabcd
介绍
asp.net mvc 之 asp.net mvc 2.0 新特性:如通过 DataAnnotations 实现数据验证及客户端验证,MVC 与 Dynamic Data 的结合,对异步 Controller 的支持,对 Area 的支持,新增的一些帮助方法等
示例
1、新特性总结
Index.aspx
2、异步 Controller 的 Demo
Areas/AsynchronousController/Controllers/HomeController.cs
Areas/AsynchronousController/Views/Home/Index.aspx
3、Area 的 Demo
Areas/AsynchronousController/AsynchronousControllerAreaRegistration.cs
Global.asax
4、对 DataAnnotations 的支持,实现数据验证(包括客户端验证)
Metadata.cs
CategoryController.cs
Create.aspx
5、MVC 与 Dynamic Data 相结合的 Demo
相关的 DataAnnotations 就用上面的那个
Category/Edit.aspx
Category/Edit2.aspx
Category/Index.aspx
Shared/DisplayTemplates/MyDate.ascx
OK
[源码下载]
返璞归真 asp.net mvc (6) - asp.net mvc 2.0 新特性
作者: webabcd
介绍
asp.net mvc 之 asp.net mvc 2.0 新特性:如通过 DataAnnotations 实现数据验证及客户端验证,MVC 与 Dynamic Data 的结合,对异步 Controller 的支持,对 Area 的支持,新增的一些帮助方法等
示例
1、新特性总结
Index.aspx
代码
<%
@ Page Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Home Page
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > <% : ViewData[ " Message " ] %> </ h2 >
< p >
< a href ="Category" target ="_blank" > Demo </ a >
</ p >
< p >
1、 < a href ="Category/Create" target ="_blank" > 通过 DataAnnotations 实现数据验证;对客户端验证的支持 </ a >
</ p >
< p >
2、 < a href ="AsynchronousController" target ="_blank" > 对异步 Controller 的支持 </ a >
</ p >
< p >
3、MVC 与 Dynamic Data 的结合
< br />
< a href ="Category/Edit/21" target ="_blank" > 实现 Model 级别的 Dynamic Data </ a >
< br />
< a href ="Category/Edit2/21" target ="_blank" > 实现 Property 级别的 Dynamic Data </ a >
< br />
新增了对模板的支持(模板源自 Dynamic Data)
</ p >
< p >
4、新增的参数级的声明 DefaultValueAttribute - 用于为参数指定默认值public ActionResult View(int id, [DefaultValue(1)]int page) { }
</ p >
< p >
5、关于路由的新特性,参看:http://www.cnblogs.com/webabcd/archive/2010/05/20/1739750.html
</ p >
< p >
6、Html.Hidden() 增强 - 其可以用于保存二进制(Binary 类型或 byte[] 类型)数据
< br />
比如:
< br />
< %= Html.Hidden("Photo", Model.Photo) % >
< br />
生成的 html 为:
< br />
< input type="hidden" name="Photo" value="QVNQLk5FVCBNVkMgaXMgZnVuIQ................................." / >
</ p >
< p >
7、在 VS 2010 中增加了 asp.net mvc 相关的代码片段
< br />
组合键 ctrl+k ctrl+b 调出代码片段管理器后查看
</ p >
< p >
8、新增了一个名为 RequireHttpsAttribute 的 Action Filter - 其作用就是用于只允许 HTTPS 请求。默认情况下,如果是 HTTP 请求,则会自动跳转到 HTTPS 请求
</ p >
< p >
9、只有 HTTP POST 请求才能返回 JsonResult
</ p >
< p >
10、新增了 HttpPostAttribute HttpPutAttribute HttpGetAttribute HttpDeleteAttribute ,以前是类似这样写的 AcceptVerbs(HttpVerbs.Post)
</ p >
< p >
11、UrlParameter.Optional - 如果从url路由中无法获取某个参数的值,则从url参数中获取该参数的值。示例如下
< br />
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
< br />
< a href ="Category/?pageIndex=0" target ="_blank" > 使用 UrlParameter.Optional 的一个演示 </ a >
</ p >
< p >
12、对 Area 的支持 - 允许在一个应用程序内存在多套 MVC,在项目中单击右键 -> Add -> Area...(详见示例程序中的 Areas 目录)
</ p >
< p >
13、新增的一些帮助方法
< br />
Html.EditorFor(), Html.DisplayFor(), Html.DisplayTextFor(), Html.ValidationMessageFor(), Html.TextBoxFor(), Html.TextAreaFor(), Html.DropDownListFor(), Html.CheckboxFor(), Html.RadioButtonFor(), Html.ListBoxFor(), Html.PasswordFor(), Html.HiddenFor(), Html.LabelFor()
< br />
它们主要用于实现 Scaffold,以及为 Property 或 Model 指定显示模板或编辑模板
</ p >
</ asp:Content >
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Home Page
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > <% : ViewData[ " Message " ] %> </ h2 >
< p >
< a href ="Category" target ="_blank" > Demo </ a >
</ p >
< p >
1、 < a href ="Category/Create" target ="_blank" > 通过 DataAnnotations 实现数据验证;对客户端验证的支持 </ a >
</ p >
< p >
2、 < a href ="AsynchronousController" target ="_blank" > 对异步 Controller 的支持 </ a >
</ p >
< p >
3、MVC 与 Dynamic Data 的结合
< br />
< a href ="Category/Edit/21" target ="_blank" > 实现 Model 级别的 Dynamic Data </ a >
< br />
< a href ="Category/Edit2/21" target ="_blank" > 实现 Property 级别的 Dynamic Data </ a >
< br />
新增了对模板的支持(模板源自 Dynamic Data)
</ p >
< p >
4、新增的参数级的声明 DefaultValueAttribute - 用于为参数指定默认值public ActionResult View(int id, [DefaultValue(1)]int page) { }
</ p >
< p >
5、关于路由的新特性,参看:http://www.cnblogs.com/webabcd/archive/2010/05/20/1739750.html
</ p >
< p >
6、Html.Hidden() 增强 - 其可以用于保存二进制(Binary 类型或 byte[] 类型)数据
< br />
比如:
< br />
< %= Html.Hidden("Photo", Model.Photo) % >
< br />
生成的 html 为:
< br />
< input type="hidden" name="Photo" value="QVNQLk5FVCBNVkMgaXMgZnVuIQ................................." / >
</ p >
< p >
7、在 VS 2010 中增加了 asp.net mvc 相关的代码片段
< br />
组合键 ctrl+k ctrl+b 调出代码片段管理器后查看
</ p >
< p >
8、新增了一个名为 RequireHttpsAttribute 的 Action Filter - 其作用就是用于只允许 HTTPS 请求。默认情况下,如果是 HTTP 请求,则会自动跳转到 HTTPS 请求
</ p >
< p >
9、只有 HTTP POST 请求才能返回 JsonResult
</ p >
< p >
10、新增了 HttpPostAttribute HttpPutAttribute HttpGetAttribute HttpDeleteAttribute ,以前是类似这样写的 AcceptVerbs(HttpVerbs.Post)
</ p >
< p >
11、UrlParameter.Optional - 如果从url路由中无法获取某个参数的值,则从url参数中获取该参数的值。示例如下
< br />
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
< br />
< a href ="Category/?pageIndex=0" target ="_blank" > 使用 UrlParameter.Optional 的一个演示 </ a >
</ p >
< p >
12、对 Area 的支持 - 允许在一个应用程序内存在多套 MVC,在项目中单击右键 -> Add -> Area...(详见示例程序中的 Areas 目录)
</ p >
< p >
13、新增的一些帮助方法
< br />
Html.EditorFor(), Html.DisplayFor(), Html.DisplayTextFor(), Html.ValidationMessageFor(), Html.TextBoxFor(), Html.TextAreaFor(), Html.DropDownListFor(), Html.CheckboxFor(), Html.RadioButtonFor(), Html.ListBoxFor(), Html.PasswordFor(), Html.HiddenFor(), Html.LabelFor()
< br />
它们主要用于实现 Scaffold,以及为 Property 或 Model 指定显示模板或编辑模板
</ p >
</ asp:Content >
2、异步 Controller 的 Demo
Areas/AsynchronousController/Controllers/HomeController.cs
代码
/*
* ASP.NET MVC 2.0 - 异步 Controller
* 1、需要继承基类 AsyncController
* 2、在 Async 为后缀的方法中写发起异步操作的逻辑;在 Completed 为后缀的方法中写异步操作完成后的逻辑;此两个方法的前缀就是这个异步 Controller 的 Action
* 3、AsyncManager.OutstandingOperations.Increment() - 递增当前异步操作的计数器;AsyncManager.OutstandingOperations.Decrement(); - 递减当前异步操作的计数器。当异步操作的计数器为 0 时,则调用以 Completed 为后缀的方法
* 4、AsyncManager.Parameters[key] - 传递指定参数到以 Completed 为后缀的方法中
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;
namespace MVC20.Areas.AsynchronousController.Controllers
{
[HandleError]
public class HomeController : AsyncController
{
// IndexAsync() 以及 IndexCompleted() 是一对,其 Action 为 Index
// 开始一个异步操作
public void IndexAsync()
{
// 递增计数器
AsyncManager.OutstandingOperations.Increment();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( " http://www.cnblogs.com/webabcd/rss " );
request.BeginGetResponse( new AsyncCallback(OnGetRssFeedAsyncCompleted), request);
}
// 完成异步操作后
public ActionResult IndexCompleted(IEnumerable < SyndicationItem > items)
{
ViewData[ " Message " ] = " Welcome to ASP.NET MVC! " ;
ViewData[ " SyndicationItems " ] = items;
return View();
}
private void OnGetRssFeedAsyncCompleted(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
SyndicationFeed feed = SyndicationFeed.Load(reader);
// 传递指定参数到 IndexCompleted() 方法中
AsyncManager.Parameters[ " items " ] = feed.Items;
// 递减计数器,当计数器为 0 时,则调用 IndexCompleted()
AsyncManager.OutstandingOperations.Decrement();
}
}
}
}
* ASP.NET MVC 2.0 - 异步 Controller
* 1、需要继承基类 AsyncController
* 2、在 Async 为后缀的方法中写发起异步操作的逻辑;在 Completed 为后缀的方法中写异步操作完成后的逻辑;此两个方法的前缀就是这个异步 Controller 的 Action
* 3、AsyncManager.OutstandingOperations.Increment() - 递增当前异步操作的计数器;AsyncManager.OutstandingOperations.Decrement(); - 递减当前异步操作的计数器。当异步操作的计数器为 0 时,则调用以 Completed 为后缀的方法
* 4、AsyncManager.Parameters[key] - 传递指定参数到以 Completed 为后缀的方法中
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;
namespace MVC20.Areas.AsynchronousController.Controllers
{
[HandleError]
public class HomeController : AsyncController
{
// IndexAsync() 以及 IndexCompleted() 是一对,其 Action 为 Index
// 开始一个异步操作
public void IndexAsync()
{
// 递增计数器
AsyncManager.OutstandingOperations.Increment();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( " http://www.cnblogs.com/webabcd/rss " );
request.BeginGetResponse( new AsyncCallback(OnGetRssFeedAsyncCompleted), request);
}
// 完成异步操作后
public ActionResult IndexCompleted(IEnumerable < SyndicationItem > items)
{
ViewData[ " Message " ] = " Welcome to ASP.NET MVC! " ;
ViewData[ " SyndicationItems " ] = items;
return View();
}
private void OnGetRssFeedAsyncCompleted(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
SyndicationFeed feed = SyndicationFeed.Load(reader);
// 传递指定参数到 IndexCompleted() 方法中
AsyncManager.Parameters[ " items " ] = feed.Items;
// 递减计数器,当计数器为 0 时,则调用 IndexCompleted()
AsyncManager.OutstandingOperations.Decrement();
}
}
}
}
Areas/AsynchronousController/Views/Home/Index.aspx
代码
<%
@ Page Language
=
"
C#
"
Inherits
=
"
System.Web.Mvc.ViewPage<dynamic>
"
%>
<% @ Import Namespace = " System.ServiceModel.Syndication " %>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > Index </ title >
</ head >
< body >
< div >
< h2 >
<% : ViewData[ " Message " ] %> </ h2 >
< div >
<!--
调用异步 Controller 的 Demo
注意:Inherits="System.Web.Mvc.ViewPage<dynamic>",这里用了 dynamic 类型
-->
<% foreach (SyndicationItem item in (IEnumerable < SyndicationItem > )ViewData[ " SyndicationItems " ])
{ %>
< a href ="<%= item.Id %>" >
<% = item.Title.Text %> </ a >< br />
<% } %>
</ div >
</ div >
</ body >
</ html >
<% @ Import Namespace = " System.ServiceModel.Syndication " %>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > Index </ title >
</ head >
< body >
< div >
< h2 >
<% : ViewData[ " Message " ] %> </ h2 >
< div >
<!--
调用异步 Controller 的 Demo
注意:Inherits="System.Web.Mvc.ViewPage<dynamic>",这里用了 dynamic 类型
-->
<% foreach (SyndicationItem item in (IEnumerable < SyndicationItem > )ViewData[ " SyndicationItems " ])
{ %>
< a href ="<%= item.Id %>" >
<% = item.Title.Text %> </ a >< br />
<% } %>
</ div >
</ div >
</ body >
</ html >
3、Area 的 Demo
Areas/AsynchronousController/AsynchronousControllerAreaRegistration.cs
代码
/*
* ASP.NET MVC 2.0 - 对 Area 的支持,其允许在一个应用程序内实现多套 MVC
* 1、新建 Area:右键 -> Add -> Area...
* 2、继承 AreaRegistration,配置对应此 Area 的路由
* 3、在 Global 中通过 AreaRegistration.RegisterAllAreas(); 注册此 Area
* 4、有了 Area,就一定要配置路由的命名空间
*/
using System.Web.Mvc;
namespace MVC20.Areas.AsynchronousController
{
// 新建一个 Area 会自动生成这个继承自 AreaRegistration 的类
// 如果需要使用此 Area 下的 MVC, 需要在 Global 中 AreaRegistration.RegisterAllAreas();
public class AsynchronousControllerAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return " AsynchronousController " ;
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
// 在 Area 中配置路由的时候,要设置命名空间(即本例中的第 4 个参数)
context.MapRoute(
" AsynchronousController_default " ,
" AsynchronousController/{controller}/{action}/{id} " ,
new { controller = " Home " , action = " Index " , id = UrlParameter.Optional }, // Parameter defaults
new string [] { " MVC20.Areas.AsynchronousController.Controllers " }
);
}
}
}
* ASP.NET MVC 2.0 - 对 Area 的支持,其允许在一个应用程序内实现多套 MVC
* 1、新建 Area:右键 -> Add -> Area...
* 2、继承 AreaRegistration,配置对应此 Area 的路由
* 3、在 Global 中通过 AreaRegistration.RegisterAllAreas(); 注册此 Area
* 4、有了 Area,就一定要配置路由的命名空间
*/
using System.Web.Mvc;
namespace MVC20.Areas.AsynchronousController
{
// 新建一个 Area 会自动生成这个继承自 AreaRegistration 的类
// 如果需要使用此 Area 下的 MVC, 需要在 Global 中 AreaRegistration.RegisterAllAreas();
public class AsynchronousControllerAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return " AsynchronousController " ;
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
// 在 Area 中配置路由的时候,要设置命名空间(即本例中的第 4 个参数)
context.MapRoute(
" AsynchronousController_default " ,
" AsynchronousController/{controller}/{action}/{id} " ,
new { controller = " Home " , action = " Index " , id = UrlParameter.Optional }, // Parameter defaults
new string [] { " MVC20.Areas.AsynchronousController.Controllers " }
);
}
}
}
Global.asax
代码
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MVC20
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute( " {resource}.axd/{*pathInfo} " );
// 用于本项目中使用了 Area,所以在配置路由的时候,要设置命名空间(即本例中的第 4 个参数)
routes.MapRoute(
" Default " , // Route name
" {controller}/{action}/{id} " , // URL with parameters
new { controller = " Home " , action = " Index " , id = UrlParameter.Optional }, // UrlParameter.Optional - 如果从url路由中无法获取某个参数的值,则从url参数中获取该参数的值
new string [] { " MVC20.Controllers " }
);
}
protected void Application_Start()
{
// 注册本应用程序中的所有 Area
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MVC20
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute( " {resource}.axd/{*pathInfo} " );
// 用于本项目中使用了 Area,所以在配置路由的时候,要设置命名空间(即本例中的第 4 个参数)
routes.MapRoute(
" Default " , // Route name
" {controller}/{action}/{id} " , // URL with parameters
new { controller = " Home " , action = " Index " , id = UrlParameter.Optional }, // UrlParameter.Optional - 如果从url路由中无法获取某个参数的值,则从url参数中获取该参数的值
new string [] { " MVC20.Controllers " }
);
}
protected void Application_Start()
{
// 注册本应用程序中的所有 Area
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
4、对 DataAnnotations 的支持,实现数据验证(包括客户端验证)
Metadata.cs
代码
/*
* ASP.NET MVC 2.0 - 对 DataAnnotations 的支持,可以实现验证及 Scaffold
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVC20.Models
{
[MetadataType( typeof (ProductCategory_Metadata))]
public partial class ProductCategory
{
}
public class ProductCategory_Metadata
{
[Required(AllowEmptyStrings = false , ErrorMessage = " {0} 为必填字段 " )]
[NameValidation(ErrorMessage = " {0} 只能是数字 " )]
[Display(Name = " 名称 " )]
public string Name;
[ScaffoldColumn( false )]
public object ModifiedDate { get ; set ; }
// DisplayValue=true - 默认值。在显示模板中,用一个 lable 显示指定的值;在编辑模板中,用一个 lable 显示指定的值,并用一个 hidden input 保存该值
// DisplayValue=false - 在显示模板中,不做任何显示;在编辑模板中,不做任何显示,但会用一个 hidden input 保存该值
[System.Web.Mvc.HiddenInput(DisplayValue = true )]
public object rowguid { get ; set ; }
}
// 通过继承 RegularExpressionAttribute 实现自定义验证 Attribute
// 通过继承 ValidationAttribute 实现自定义验证 Attribute 的 Demo 可以参看 http://www.cnblogs.com/webabcd/archive/2009/02/23/1396212.html
public class NameValidationAttribute : RegularExpressionAttribute
{
public NameValidationAttribute()
: base ( " ^[0-9]*$ " )
{
}
}
}
* ASP.NET MVC 2.0 - 对 DataAnnotations 的支持,可以实现验证及 Scaffold
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVC20.Models
{
[MetadataType( typeof (ProductCategory_Metadata))]
public partial class ProductCategory
{
}
public class ProductCategory_Metadata
{
[Required(AllowEmptyStrings = false , ErrorMessage = " {0} 为必填字段 " )]
[NameValidation(ErrorMessage = " {0} 只能是数字 " )]
[Display(Name = " 名称 " )]
public string Name;
[ScaffoldColumn( false )]
public object ModifiedDate { get ; set ; }
// DisplayValue=true - 默认值。在显示模板中,用一个 lable 显示指定的值;在编辑模板中,用一个 lable 显示指定的值,并用一个 hidden input 保存该值
// DisplayValue=false - 在显示模板中,不做任何显示;在编辑模板中,不做任何显示,但会用一个 hidden input 保存该值
[System.Web.Mvc.HiddenInput(DisplayValue = true )]
public object rowguid { get ; set ; }
}
// 通过继承 RegularExpressionAttribute 实现自定义验证 Attribute
// 通过继承 ValidationAttribute 实现自定义验证 Attribute 的 Demo 可以参看 http://www.cnblogs.com/webabcd/archive/2009/02/23/1396212.html
public class NameValidationAttribute : RegularExpressionAttribute
{
public NameValidationAttribute()
: base ( " ^[0-9]*$ " )
{
}
}
}
CategoryController.cs
代码
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC20.Models;
using System.ComponentModel;
namespace MVC20.Controllers
{
public class CategoryController : Controller
{
// DefaultValueAttribute - 用于为参数指定默认值。当路由或url参数中无此参数时,则会使用此默认值
public ActionResult Index([DefaultValue( 2 )] int pageIndex)
{
int pageSize = 10 ;
var categories = new Models.CategorySystem().GetCategory(pageIndex, pageSize);
return View( " Index " , categories);
}
public ActionResult Edit( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Edit " , category);
}
// 用于演示实现 Model 级别的 Dynamic Data
[HttpPost]
public ActionResult Edit( int id, FormCollection formValues)
{
var cs = new Models.CategorySystem();
var category = cs.GetCategory(id);
TryUpdateModel < ProductCategory > (category);
cs.Save();
return RedirectToAction( " Index " );
}
public ActionResult Edit2( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Edit2 " , category);
}
// 用于演示实现 Property 级别的 Dynamic Data
[HttpPost]
public ActionResult Edit2( int id, FormCollection formValues)
{
var cs = new Models.CategorySystem();
var category = cs.GetCategory(id);
TryUpdateModel < ProductCategory > (category);
cs.Save();
return RedirectToAction( " Index " );
}
public ActionResult Details( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Details " , category);
}
public ActionResult Create()
{
ProductCategory category = new ProductCategory()
{
};
return View(category);
}
// 用于演示通过 DataAnnotations 实现数据验证
[HttpPost]
public ActionResult Create(ProductCategory category)
{
if ( ! ModelState.IsValid)
{
return View(category);
}
else
{
var cs = new Models.CategorySystem();
cs.AddCategory(category);
cs.Save();
return View( " Details " , category);
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC20.Models;
using System.ComponentModel;
namespace MVC20.Controllers
{
public class CategoryController : Controller
{
// DefaultValueAttribute - 用于为参数指定默认值。当路由或url参数中无此参数时,则会使用此默认值
public ActionResult Index([DefaultValue( 2 )] int pageIndex)
{
int pageSize = 10 ;
var categories = new Models.CategorySystem().GetCategory(pageIndex, pageSize);
return View( " Index " , categories);
}
public ActionResult Edit( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Edit " , category);
}
// 用于演示实现 Model 级别的 Dynamic Data
[HttpPost]
public ActionResult Edit( int id, FormCollection formValues)
{
var cs = new Models.CategorySystem();
var category = cs.GetCategory(id);
TryUpdateModel < ProductCategory > (category);
cs.Save();
return RedirectToAction( " Index " );
}
public ActionResult Edit2( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Edit2 " , category);
}
// 用于演示实现 Property 级别的 Dynamic Data
[HttpPost]
public ActionResult Edit2( int id, FormCollection formValues)
{
var cs = new Models.CategorySystem();
var category = cs.GetCategory(id);
TryUpdateModel < ProductCategory > (category);
cs.Save();
return RedirectToAction( " Index " );
}
public ActionResult Details( int id)
{
var category = new Models.CategorySystem().GetCategory(id);
return View( " Details " , category);
}
public ActionResult Create()
{
ProductCategory category = new ProductCategory()
{
};
return View(category);
}
// 用于演示通过 DataAnnotations 实现数据验证
[HttpPost]
public ActionResult Create(ProductCategory category)
{
if ( ! ModelState.IsValid)
{
return View(category);
}
else
{
var cs = new Models.CategorySystem();
cs.AddCategory(category);
cs.Save();
return View( " Details " , category);
}
}
}
}
Create.aspx
代码
<%
@ Page Title
=
""
Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage<MVC20.Models.ProductCategory>
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Create
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
<!--
为了实现客户端验证,需要引用以下两个 JavaScript
-->
< script src ="http://www.cnblogs.com/Scripts/MicrosoftAjax.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/MicrosoftMvcValidation.js" type ="text/javascript" ></ script >
< h2 > Create </ h2 >
<!-- 启用客户端验证功能 -->
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<!-- Html.ValidationSummary Helper Method Can Display Model-Level Errors -->
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
< fieldset >
< legend > Fields </ legend >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ProductCategoryID) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.ProductCategoryID) %>
<!--
验证的错误信息来自 DataAnnotations,也可以通过 ValidationMessageFor() 来指定需要显示的错误信息
-->
<% : Html.ValidationMessageFor(model => model.ProductCategoryID, " * " ) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ParentProductCategoryID) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.ParentProductCategoryID) %>
<% : Html.ValidationMessageFor(model => model.ParentProductCategoryID) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.Name) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.Name) %>
<% : Html.ValidationMessageFor(model => model.Name) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.rowguid) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.rowguid) %>
<% : Html.ValidationMessageFor(model => model.rowguid) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ModifiedDate) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBox( " ModifiedDate " , DateTime.Now.ToString( " yyyy-MM-dd " )) %>
<% : Html.ValidationMessageFor(model => model.ModifiedDate) %>
</ div >
< p >
< input type ="submit" value ="Create" />
</ p >
</ fieldset >
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Create
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
<!--
为了实现客户端验证,需要引用以下两个 JavaScript
-->
< script src ="http://www.cnblogs.com/Scripts/MicrosoftAjax.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/MicrosoftMvcValidation.js" type ="text/javascript" ></ script >
< h2 > Create </ h2 >
<!-- 启用客户端验证功能 -->
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<!-- Html.ValidationSummary Helper Method Can Display Model-Level Errors -->
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
< fieldset >
< legend > Fields </ legend >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ProductCategoryID) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.ProductCategoryID) %>
<!--
验证的错误信息来自 DataAnnotations,也可以通过 ValidationMessageFor() 来指定需要显示的错误信息
-->
<% : Html.ValidationMessageFor(model => model.ProductCategoryID, " * " ) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ParentProductCategoryID) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.ParentProductCategoryID) %>
<% : Html.ValidationMessageFor(model => model.ParentProductCategoryID) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.Name) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.Name) %>
<% : Html.ValidationMessageFor(model => model.Name) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.rowguid) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBoxFor(model => model.rowguid) %>
<% : Html.ValidationMessageFor(model => model.rowguid) %>
</ div >
< div class ="editor-label" >
<% : Html.LabelFor(model => model.ModifiedDate) %>
</ div >
< div class ="editor-field" >
<% : Html.TextBox( " ModifiedDate " , DateTime.Now.ToString( " yyyy-MM-dd " )) %>
<% : Html.ValidationMessageFor(model => model.ModifiedDate) %>
</ div >
< p >
< input type ="submit" value ="Create" />
</ p >
</ fieldset >
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
5、MVC 与 Dynamic Data 相结合的 Demo
相关的 DataAnnotations 就用上面的那个
Category/Edit.aspx
代码
<%
@ Page Title
=
""
Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage<MVC20.Models.ProductCategory>
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Edit
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 >
Edit </ h2 >
<% using (Html.BeginForm()) { %>
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
<% = Html.EditorFor(category => category) %>
< input type ="submit" value ="Save" />
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Edit
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 >
Edit </ h2 >
<% using (Html.BeginForm()) { %>
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
<% = Html.EditorFor(category => category) %>
< input type ="submit" value ="Save" />
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
Category/Edit2.aspx
代码
<%
@ Page Title
=
""
Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage<MVC20.Models.ProductCategory>
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Edit2
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > Edit2 </ h2 >
<% using (Html.BeginForm()) { %>
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
< fieldset >
< legend > Fields </ legend >
<% = Html.LabelFor(c => c.ParentProductCategoryID) %> : <% = Html.EditorFor(c => c.ParentProductCategoryID) %>
</ br >
<% = Html.LabelFor(c => c.Name) %> : <% = Html.EditorFor(c => c.Name) %>
< p >
< input type ="submit" value ="Save" />
</ p >
</ fieldset >
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Edit2
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 > Edit2 </ h2 >
<% using (Html.BeginForm()) { %>
<% : Html.ValidationSummary( " 错误信息如下: " ) %>
< fieldset >
< legend > Fields </ legend >
<% = Html.LabelFor(c => c.ParentProductCategoryID) %> : <% = Html.EditorFor(c => c.ParentProductCategoryID) %>
</ br >
<% = Html.LabelFor(c => c.Name) %> : <% = Html.EditorFor(c => c.Name) %>
< p >
< input type ="submit" value ="Save" />
</ p >
</ fieldset >
<% } %>
< div >
<% : Html.ActionLink( " Back to List " , " Index " ) %>
</ div >
</ asp:Content >
Category/Index.aspx
代码
<%
@ Page Title
=
""
Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage<IEnumerable<MVC20.Models.ProductCategory>>
"
%>
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Index
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 >
Index </ h2 >
< table >
< tr >
< th >
</ th >
< th >
ProductCategoryID
</ th >
< th >
ParentProductCategoryID
</ th >
< th >
名称
</ th >
< th >
rowguid
</ th >
< th >
ModifiedDate
</ th >
</ tr >
<% foreach (var item in Model)
{ %>
< tr >
< td >
<% : Html.ActionLink( " Edit " , " Edit " , new { id = item.ProductCategoryID }) %>
|
<% : Html.ActionLink( " Details " , " Details " , new { id = item.ProductCategoryID }) %>
|
<% : Html.ActionLink( " Delete " , " Delete " , new { id = item.ProductCategoryID }) %>
</ td >
< td >
<% : item.ProductCategoryID %>
</ td >
< td >
<% : item.ParentProductCategoryID %>
</ td >
< td >
<% : Html.DisplayTextFor(c => item.Name) %>
</ td >
< td >
<% : item.rowguid %>
</ td >
< td >
<!--
Html.DisplayFor() - 可以指定显示模板(可以指定 Property 级模板,也可以指定 Model 级模板),本例的模板地址为 Views/Shared/DisplayTemplates/MyDate.ascx ,这种实现方式来自 Dynamic Data
-->
<% = Html.DisplayFor(Product => item.ModifiedDate, " MyDate " ) %>
</ td >
</ tr >
<% } %>
</ table >
< p >
<% = Html.RouteLink( " 上一页 " , " Default " , new { pageIndex = Convert.ToInt32(Request.QueryString[ " pageIndex " ] ?? " 2 " ) - 1 }) %>
|
<% = Html.RouteLink( " 下一页 " , " Default " , new { pageIndex = Convert.ToInt32(Request.QueryString[ " pageIndex " ] ?? " 2 " ) + 1 }) %>
</ p >
< p >
<% : Html.ActionLink( " Create New " , " Create " ) %>
</ p >
</ asp:Content >
< asp:Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server" >
Index
</ asp:Content >
< asp:Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server" >
< h2 >
Index </ h2 >
< table >
< tr >
< th >
</ th >
< th >
ProductCategoryID
</ th >
< th >
ParentProductCategoryID
</ th >
< th >
名称
</ th >
< th >
rowguid
</ th >
< th >
ModifiedDate
</ th >
</ tr >
<% foreach (var item in Model)
{ %>
< tr >
< td >
<% : Html.ActionLink( " Edit " , " Edit " , new { id = item.ProductCategoryID }) %>
|
<% : Html.ActionLink( " Details " , " Details " , new { id = item.ProductCategoryID }) %>
|
<% : Html.ActionLink( " Delete " , " Delete " , new { id = item.ProductCategoryID }) %>
</ td >
< td >
<% : item.ProductCategoryID %>
</ td >
< td >
<% : item.ParentProductCategoryID %>
</ td >
< td >
<% : Html.DisplayTextFor(c => item.Name) %>
</ td >
< td >
<% : item.rowguid %>
</ td >
< td >
<!--
Html.DisplayFor() - 可以指定显示模板(可以指定 Property 级模板,也可以指定 Model 级模板),本例的模板地址为 Views/Shared/DisplayTemplates/MyDate.ascx ,这种实现方式来自 Dynamic Data
-->
<% = Html.DisplayFor(Product => item.ModifiedDate, " MyDate " ) %>
</ td >
</ tr >
<% } %>
</ table >
< p >
<% = Html.RouteLink( " 上一页 " , " Default " , new { pageIndex = Convert.ToInt32(Request.QueryString[ " pageIndex " ] ?? " 2 " ) - 1 }) %>
|
<% = Html.RouteLink( " 下一页 " , " Default " , new { pageIndex = Convert.ToInt32(Request.QueryString[ " pageIndex " ] ?? " 2 " ) + 1 }) %>
</ p >
< p >
<% : Html.ActionLink( " Create New " , " Create " ) %>
</ p >
</ asp:Content >
Shared/DisplayTemplates/MyDate.ascx
<%
@ Control Language
=
"
C#
"
Inherits
=
"
System.Web.Mvc.ViewUserControl<dynamic>
"
%>
<% = Html.Encode( String .Format( " {0:yyyy-MM-dd} " , Model)) %>
<% = Html.Encode( String .Format( " {0:yyyy-MM-dd} " , Model)) %>
OK
[源码下载]