Improve [verification mechanism ASP.NET MVC use article] through the expansion o

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

ASP.NET MVC provides a verification method based on metadata is that we can apply validation characteristics corresponding to the Model entity types or attributes / field, but it still has many deficiencies. In this article, I combined with EntLib VAB (Validation Application Block) some of the ideas by extending the ASP.NET MVC provides a more verification mechanism. [source code download from here.


An extended to solve the verification problem, how

Two, a simple message maintenance component

Three, multi language support

Four, to validate a validation rule based

Five, consistency validation rules

An extended to solve the verification problem, how

The validation of the extended based on can achieve the following several ASP.NET MVC cannot realize the verification problem:

Two, a simple message maintenance component

The separation mechanism in order to demonstrate message, we define a simple message maintenance component MessageManager. As shown in the following code, the abstract class MessageManager has only FormatMessage method is used to obtain a after the final message text, formatted parameters category, ID and args respectively represent the type corresponding to the message bar, ID and as a parameter to replace the placeholder.

   1: public abstract  class MessageManager
   2: {
   3:     public abstract string FormatMessage(string category, string id, params object[] args);
   4: }

We define the following a default DefaultMessageManager, which maintains a group representing the message to the MessageEntry list, and the MessageEntry is multi language support. In the overridden FormatMessage method, direct through type and ID to find the corresponding MessageEntry in the list, and transfer the placeholder parameters according to the current thread's CurrentUICulture format of news text. The following code can be seen, we only define a representation for “ a required field ” news, text in the en-US and zh-CN of the two languages culture were “ {0} is mandatory! ” and “ please input{0}!”. The MessageEntry type and ID are “ Validation” and“MandatoryField”.

   1: public class DefaultMessageManager : MessageManager
   2: {
   3:     public DefaultMessageManager()
   4:     {
   5:         var messages = new List<MessageEntry>();
   6:         var messageEntry = new MessageEntry("Validation", "MandatoryField");
   7:         messageEntry.AddMessageText("{0} is mandatory!", new CultureInfo("en-US"));
   8:         messageEntry.AddMessageText("Please input{0}!", new CultureInfo("zh-CN"));
   9:         messages.Add(messageEntry);
  10:         this.Messages = messages;
  11:     }
  13:     public IEnumerable<MessageEntry> Messages { get; private set; } 
  14:     public override string FormatMessage(string category, string id, params object[] args)
  15:     {
  16:         MessageEntry messageEntry = (from message in this.Messages
  17:                                      where message.Category == category && message.Id == id
  18:                                      select message).FirstOrDefault();
  19:         if (null == messageEntry)
  20:         {
  21:             throw new Exception("...");
  22:         }
  24:         return messageEntry.Format(args);
  25:     }
  26: }

We are not listed in the definition of MessageEntry, interested friends can download the example source code. Finally we define the following static factory MessageManagerFactory to create the corresponding MessageManager, simplicity, we create the DefaultMessageManager.

   1: public static class MessageManagerFactory
   2: {
   3:     public static MessageManager GetMessageManager()
   4:     {
   5:         return new DefaultMessageManager();
   6:     }
   7: }

Three, multi language support

We are not in this article on the specific implementation, only talk about the use of specific methods. We have to login scenario as an example, as shown by the LoginInfo type that contains represents the username and password of Model type. RequiredValidatorAttribute application on the property is our custom ValidationAttribute, it realizes the authentication function RequiredAttribute. The application in the UserName attribute on the case of RequiredValidatorAttribute ([RequiredValidator ("Validation", "MandatoryField", "user name", Name = "RequiredValidator", Culture = "zh-CN")]), Constructor parameters representing the type corresponding to the maintenance of a message MessageManager (Validation), ID (MandatoryField) as well as the placeholder parameters (username). The Culture property represents the corresponding language culture, if not explicitly specified on the property, represents “ culture and language neutral &rdquo validator;.

   1: public class LoginInfo
   2: {
   3:     [Display(ResourceType = typeof(Resources), Name = "UserName")]
   4:     [RequiredValidator("Validation", "MandatoryField", "User Name")]
   5:     [RequiredValidator("Validation", "MandatoryField", "User name", Culture = "zh-CN")]
   6:     public string UserName { get; set; }
   8:     [RequiredValidator("Validation", "MandatoryField", "Password")]
   9:     [RequiredValidator("Validation", "MandatoryField", "Cipher", Culture = "zh-CN")]
  10:     [DataType(DataType.Password)]
  11:     [Display(ResourceType = typeof(Resources), Name = "Password")]
  12:     public string Password { get; set; }
  13: }

Process the validator selection, always validator according to the current thread CurrentUICulture match. If you can't find the authenticator match, will choose the language culture neutral verifier (this validator is allowed to have only one). For this example, if the current language and culture for zh-CN, then only the application in UserName and Password attributes on the Culture attribute is zh-CN RequiredValidatorAttribute, while in the other language and culture environment will choose no explicit RequiredValidatorAttribute type set to Culture attributes. We come to have a look for the definition of user login AccountController:

   1: public class AccountController : BaseController
   2:     {
   3:         public ActionResult SignIn()
   4:         {
   5:             return View(new LoginInfo());
   6:         }
   7:         [HttpPost]
   8:         public ActionResult SignIn(LoginInfo logInfo)
   9:         {
  10:             if (ModelState.IsValid)
  11:             {
  12:                 return this.View();
  13:             }
  14:             else
  15:             {
  16:                 return this.View();
  17:             }
  18:         }
  19:     }

Here are all the contents of SignIn operation by View:

   1: @using Artech.Mvc.Validation.Properties
   2: @using Artech.Mvc.Validation.Models
   3: @model LoginInfo
   5: @{
   6:     ViewBag.Title = "SignIn";
   7: }
   8: @Html.ValidationSummary()
   9: @using(Html.BeginForm())
  10: {
  11:     @Html.EditorForModel()
  12:     <input type="submit" value="@Resources.SignIn"/>
  13: }

In our example language setting is represented by URL, in order to we are routing mapping follows in Global.asax, namely controller prior to the partial representative language code, the default is zh-CN.

   1: public class MvcApplication : System.Web.HttpApplication
   2: {
   3:     public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   4:     {
   5:         filters.Add(new HandleErrorAttribute());
   6:     }
   8:     public static void RegisterRoutes(RouteCollection routes)
   9:     {
  10:          //...
  11:          routes.MapRoute(
  12:             "Default", // Route name
  13:             "{culture}/{controller}/{action}/{id}", // URL with parameters
  14:             new {culture="zh-CN", controller = "Account", action = "SignIn", id = UrlParameter.Optional } // Parameter defaults
  15:         );
  17:     }
  19:     protected void Application_Start()
  20:     {   
  21:         //...
  22:         RegisterRoutes(RouteTable.Routes);
  23:     }
  24: }

Our program and run in with en-US and zh-CN home page, will get a validation message follows in the absence of input user name and password of the case.


Four, to validate a validation rule based

We now demonstrate a validation rule checking method. For this, we should have such experience, in the development stage in order to test the time avoid to enter a user name and password, we will set a default password. Here we can define the validation rules to shield the password verification. Therefore we used in the Password attribute LoginInfo on RequiredValidatorAttribute characteristics of little change, the RuleName property is explicitly set (RuleName = "Production"), means that only the current validation rules for “ Production” (product phase) when they take effect, verification based on.

   1: public class LoginInfo
   2: {
   3:     //...
   4:     [RequiredValidator("Validation", "MandatoryField", "Password",RuleName = "Production")]
   5:     [RequiredValidator("Validation", "MandatoryField", "Cipher", Culture = "zh-CN", RuleName = "Production")]
   6:     [DataType(DataType.Password)]
   7:     [Display(ResourceType = typeof(Resources), Name = "Password")]
   8:     public string Password { get; set; }
   9: }

And how to present the validation rules, you can apply our custom Controller or Action method in the RuleNameAttribute to set the. As in the following code snippets, we directly in AccountController using the RuleNameAttribute characteristics and the verification rules for the current settings for the “ Dev” (development stage).

   1: [ValidationRule("Dev")]
   2: public class AccountController : BaseController
   3: {
   4:     //...
   5: }

Then in the running time is not the password any verification, it can be seen through the following screenshot:


If we through the application of AccountController in the RuleNameAttribute will validate the rule set“Production”

   1: [ValidationRule("Production")]
   2: public class AccountController : BaseController
   3: {
   4:     //...
   5: }

Then the password verification will take effect.:


Five, consistency validation rules

It is worth mentioning that: we extend the verification system is also for client authentication to provide support, but in the verification validation based on rules is really a small organ. Also in two SignIn AccountController for example, client-side validation rules is the first SignIn based operations (HttpGet) generation, the server for validation is the second SignIn operation based on (HttpPost) validation rules, if we apply RuleNameAttribute to two SignIn operation, for example, to ensure that their rule name in order to ensure the consistency of consistent client authentication and server authentication.

   1: public class AccountController : BaseController
   2: {
   3:     [ValidationRule("Production")]
   4:     public ActionResult SignIn()
   5:     {
   6:         //...
   7:     }
   8:     [HttpPost]
   9:     [ValidationRule("Production")]
  10:     public ActionResult SignIn(LoginInfo logInfo)
  11:     {
  12:          //...
  13:     }
  14: }


Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Melody at November 15, 2013 - 1:01 AM