HTML5技术

玩转Asp.net MVC 的八个扩展点 - richiezhang(2)

字号+ 作者:H5之家 来源:博客园 2016-02-05 09:45 我要评论( )

有了上面的扩展,就可以这样使用了: h2Product list using htmlHelper/h2divdiv@Html.ListGroup().Info(Model.SportProducts,x=x.Name)/divdiv@Html.ListGroup().Warning(Model.BookProducts,x = x.Name)/div/divd

有了上面的扩展,就可以这样使用了:

<h2>Product list using htmlHelper</h2> <div> <div>@Html.ListGroup().Info(Model.SportProducts,x=>x.Name)</div> <div>@Html.ListGroup().Warning(Model.BookProducts,x => x.Name)</div> </div> <div> <div>@Html.ListGroup().Danger(Model.FoodProducts,x => x.Name)</div> </div>

效果:

四、RazorViewEngine

通过自定义RazorViewEngine可以实现同一份后台代码对应不同风格的View。利用这一扩展能够实现不同的Theme风格切换。再比如站点可能需要在不同的语言环境下切换到不同的风格,也可以通过自定义RazorViewEngine来实现。

下面就让我们来实现一个Theme切换的功能,首先自定义一个ViewEngine:

public class ThemeViewEngine: RazorViewEngine { public ThemeViewEngine(string theme) { ViewLocationFormats = new[] { "~/Views/Themes/" + theme + "/{1}/{0}.cshtml", "~/Views/Themes/" + theme + "/Shared/{0}.cshtml" }; PartialViewLocationFormats = new[] { "~/Views/Themes/" + theme + "/{1}/{0}.cshtml", "~/Views/Themes/" + theme + "/Shared/{0}.cshtml" }; AreaViewLocationFormats = new[] { "~Areas/{2}/Views/Themes/" + theme + "/{1}/{0}.cshtml", "~Areas/{2}/Views/Themes/" + theme + "/Shared/{0}.cshtml" }; AreaPartialViewLocationFormats = new[] { "~Areas/{2}/Views/Themes/" + theme + "/{1}/{0}.cshtml", "~Areas/{2}/Views/Themes/" + theme + "/Shared/{0}.cshtml" }; } }

当我们启用这一ViewEngine时,Razor就会在/Views/Themes/文件夹下去找View文件。为了启用自定义的ViewEngine,需要将ThemeViewEngine加入到ViewEngines

public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["Theme"])) { var activeTheme = ConfigurationManager.AppSettings["Theme"]; ViewEngines.Engines.Insert(0, new ThemeViewEngine(activeTheme)); }; //... } }

接下来就开始编写不同风格的View了,重点在于编写的View文件夹组织方式要跟ThemeViewEngine中定义的路径要一致,以ServiceController为例,我们编写ocean和sky两种风格的View:

最后在web.config制定一种Theme:<add key="Theme" value="ocean"/>,ocean文件夹下的View将会被优先采用:

五、Validator

通过在Model属性上加Attribute的验证方式是MVC提倡的数据验证方式,一方面这种方式使用起来比较简单和通用,另一方面这种统一的方式也使得代码很整洁。使用ValidationAttribute需要引入System.ComponentModel.DataAnnotations命名空间。

但是有时候现有的ValidationAttribute可能会不能满足我们的业务需求,这就需要我们自定义自己的Attribute,例如我们自定义一个AgeValidator:

public class AgeValidator: ValidationAttribute { public AgeValidator() { ErrorMessage = "Please enter the age>18"; } public override bool IsValid(object value) { if (value == null) return false; int age; if (int.TryParse(value.ToString(), out age)) { if (age > 18) return true; return false; } return false; } }

自定义的AgeValidator使用起来跟MVC内置的ValiatorAttribute没什么区别:

[Required] [AgeValidator] public int? Age { get; set; }

不过我们有时候可能有这种需求:某个验证规则要针对Model中多个属性联合起来判断,所以上面的方案无法满足需求。这时候只需Model实现IValidatableObject接口即可:

public class UserViewModel:IValidatableObject { public string Name { get; set; } [Required] [AgeValidator] public int? Age { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if(string.IsNullOrEmpty(Name)) yield return new ValidationResult("the name can not be empty"); if (Name.Equals("lucy")) { if(Age.Value<25) yield return new ValidationResult("lucy's age must greater than 25"); } } }

六、ModelBinder

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数中。

public ActionResult InputAge(UserViewModel user) { //... return View(); }

对于这样的一个Action,如果是Post请求,MVC会尝试将Form中的值赋值到user参数中,如果是get请求,MVC会尝试将QueryString的值赋值到user参数中。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

  • ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    2017-04-24 08:04

  • ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    2017-04-14 13:04

网友点评