1

我有三個提交按鈕的視圖。第一個按鈕必須驗證一些字段,第二個按鈕必須驗證其他字段,第三個按鈕不驗證任何內容。 如何在客戶端(不顯眼)和服務器端執行此操作?ASP.NET MVC 3 - 選擇每個提交按鈕驗證哪個模型屬性

+0

http://tpeczek.blogspot.com/2010/06/partial-forms-validation-in-aspnet-mvc。html Tomasz做了和MVC2類似的事情 – Eduardo

+0

你可以有單獨的表單,或者它們全都是相同的形式嗎? –

回答

0

最有可能與很多手滾用法,特別是如果你希望它是不顯眼的。你需要創建一些類似於<input data-validationgroup="group1"...的東西,然後點擊你的JavaScript代碼將會驗證你想要的動作。我會想象jQuery Validate有一些類型的規則集支持,但你必須弄清楚。

您將不得不在服務器端執行類似的順序,並創建規則集類型驗證類/塊/方法,以便將提交操作解釋爲相關規則集。我會在這個部分看像FluentValidation這樣的庫。

爲了達到您想要的效果,您將無法使用模型類上的DataAnnotations屬性來實現此功能。

+0

如果我不需要重新創建像Required,Range,StringLength等所有現有的驗證器,那將會很好。 – Eduardo

+0

這就是爲什麼我建議像FluentValidation這樣的庫,這些都是內置的。 –

0

就我個人而言,我一直很喜歡在所有項目中使用FluentValidation.NET庫。不僅如此,它在表達驗證規則方面非常強大,但是這個庫與ASP.NET MVC很好的集成。所以我會嘗試使用它爲這個問題提供一個示例解決方案(目前只有服務器端驗證,如果需要,稍後我們可以討論不引人注意的客戶端驗證)。

因此,使用默認模板啓動一個新的ASP.NET MVC 3項目並安裝FluentValidation.MVC3 NuGet包(當前穩定版本爲2.0.0.0)。

然後讓我們定義一個視圖模型:

public class MyViewModel 
{ 
    public string Field1 { get; set; } 
    public string Field2 { get; set; } 
} 

現在我們可以假設,如果button1點擊Field1是必需的,如果button2點擊Field2是必需的,如果被點擊button3需要他們沒有。虛構的場景,但非常接近您的要求。

現在,讓我們定義兩個不同的流利驗證對應每到button1button2這種模式:

public class MyModelValidator1 : AbstractValidator<MyViewModel> 
{ 
    public MyModelValidator1() 
    { 
     RuleFor(x => x.Field1) 
      .NotEmpty(); 
    } 
} 

public class MyModelValidator2 : AbstractValidator<MyViewModel> 
{ 
    public MyModelValidator2() 
    { 
     RuleFor(x => x.Field2) 
      .NotEmpty(); 
    } 
} 

現在,因爲只有在運行時,我們知道被點擊的按鈕,我們需要採用基於正確的驗證在請求中的值。所以,讓我們寫一個自定義的驗證提供者工廠:

public class MyFactory : IValidatorFactory 
{ 
    private readonly Func<HttpContextBase> _contextProvider; 
    public MyFactory(Func<HttpContextBase> contextProvider) 
    { 
     _contextProvider = contextProvider; 
    } 

    public IValidator GetValidator(Type type) 
    { 
     if (type == typeof(MyViewModel)) 
     { 
      var context = _contextProvider(); 
      if (!string.IsNullOrEmpty(context.Request["button1"])) 
      { 
       return new MyModelValidator1(); 
      } 
      if (!string.IsNullOrEmpty(context.Request["button2"])) 
      { 
       return new MyModelValidator2(); 
      } 
     } 
     return null; 
    } 

    public IValidator<T> GetValidator<T>() 
    { 
     return (IValidator<T>)GetValidator(typeof(T)); 
    } 
} 

Application_Start註冊它:

ModelValidatorProviders.Providers.Add(
    new FluentValidationModelValidatorProvider(
     new MyFactory(() => new HttpContextWrapper(HttpContext.Current)) 
    ) 
); 

,這就是幾乎所有。現在剩下的是微不足道的。

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 
     return Content("Thanks for submitting", "text/plain"); 
    } 
} 

和一個觀點:

@model MyViewModel 

@using (Html.BeginForm()) 
{ 
    <div> 
     @Html.LabelFor(x => x.Field1) 
     @Html.EditorFor(x => x.Field1) 
     @Html.ValidationMessageFor(x => x.Field1) 
    </div> 

    <div> 
     @Html.LabelFor(x => x.Field2) 
     @Html.EditorFor(x => x.Field2) 
     @Html.ValidationMessageFor(x => x.Field2) 
    </div> 

    <input type="submit" value="Submit with button 1" name="button1" /> 
    <input type="submit" value="Submit with button 2" name="button2" /> 
    <input type="submit" value="Submit with button 3" name="button3" /> 
}