4

私はMVC 3 +邪魔にならない検証を使用しています。.NET MVC 3モデルステートのエラーを繰り返し、ModelStateを強制する方法。特定のエラーを有効または無効にしますか?

一部のフィールドでは、リモート検証も使用しています。リモートの検証では、エラーを返すか、の警告だけを返します。(エラーをブロックするだけでなく、警告を与えるためにAjax検証を利用したいと思います)。 説明文の中に "Info"という接頭辞が付いた検証エラーによる警告を区別しました。

したがって、すべての検証エラーを繰り返し、表示された警告だけを表示し、表示されたテキストに従ってエラーをオフにする方法は存在しますか?

私は

はここで、私のリモート検証ルーチンのエキスです... ActionFilterAttributeを使用して、またはサイクリングの後、真ModelState.Valid =を強制するために、すべての検証エラーをチェックすることを考えていました。 WarningCheck属性:

[WarningCheck] 
    public JsonResult CheckMyField(string myfield) 
    { 

     //....some check...if ok I do `return Json(true, JsonRequestBehavior.AllowGet);` 
     //...if just a warning, I do the follow... 

     string warn = String.Format(CultureInfo.InvariantCulture, 
      "Info: some info...."); 
     ModelState.AddModelError(TicketHD, esiste); 
     return Json(warn, JsonRequestBehavior.AllowGet); 

    } 

    [AttributeUsage(AttributeTargets.All)] 
    public class WarningCheckAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      //.... here I'd like to cycle my warnings and if possible maintaining just the text display and set errors off...is it possible? 
     } 
    } 

EDIT(特定の警告のためのクライアント側の検証を無効にする方法)

@CDSmith(@Alfalfastrange)のサーバー側の提案に続いて、特定のテキストが各検証エラーの中に含まれている場合、クライアント側の検証も無効にします。特に、私の必要性は、エラーが "Info:"テキストを含んでいたときだけ、クライアント&サーバ側の検証エラーを無効にすることでした。ここ は、私は、クライアント側の動作のために使用していたコードです:

 .... 
        $("#ticketfrm").submit(); 
        var isvalid = true; 
        var errmark = $("#ticketfrm .field-validation-error span"); 
        $(errmark).each(function() { 
         var tst = $(this).text(); 
         if (!(tst.indexOf("Info") != -1)) 
          isvalid = false; //if the val error is not a warn, the it must be a real error! 
         }); 

        if (isvalid) { 
         var form = $('#ticketfrm').get(0); //because I'm inside a jquery dialog 
         $.removeData(form, 'validator'); 
         jQuery('#ticketfrm').unbind('submit').submit(); 
        } 

        $("#ticketfrm").submit(); 
       } 
      ..... 

私はこれが多くの人々を助けるかもしれない...私はこの作業を取得するために多くの時間を働いていた願っています!私はそれがよりエレガントな解決策でなければならないとは思わないが、ITは機能する! :) サーバー側の検証では、表示されている解決策をお読みください。

これが便利な場合は、マークを付けてください。ありがとうございました!

答えて

6

私は、あなたが説明しているだけでなく、あなたが言っていることをよく理解していませんが、ModelStateのエラーをループしてエラーのテキスト値を維持する方法エラーとして?それはあなたが言っていることですか?

まあ、ModelStateは問題なく繰り返し処理できるDictionaryListです。

public ActionResult SomeAction(SomeModel model) { 
    if(ModelState.IsValid) { 
     // do cool stuff with model data 
    } 
    var errorMessages = GetModelStateErrors(ModelState); 
    foreach (var errorMessage in errors) { 
     // do whatever you want with the error message string here 
    } 
} 

ModelErrorが

internal static List<string> GetModelStateErrors(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary) { 
    var errors = new List<ModelError>(); 
    errors = modelStateDictionary.SelectMany(item => item.Value.Errors).ToList(); 
} 

ないこのことができますかどう確認ErrorMessageプロパティと例外プロパティが含まれていますが、それは右方向にあなたを指している場合:このような

何かがそれを行うことができますクール:-)

更新

ここで私が思いついたのは私のテストアプリで私のために働いています。

最初に私はあなたが

をコピーして複製することができたものをここに私のモデルは

public class EmployeeViewModel { 

    public int ID { get; set; } 

    [Display(Name = "First Name")] 
    [Required(ErrorMessage = "Error")] 
    public string FirstName { get; set; } 

    [Display(Name = "Last Name")] 
    [Required(ErrorMessage = "Error")] 
    public string LastName { get; set; } 

    [Display(Name = "Username")] 
    public string Username { get; set; } 

    [Display(Name = "Email Address")] 
    public string EmailAddress { get; set; } 
} 

です。ここ

@model TestApp.Models.EmployeeViewModel 

<h2>Test</h2> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>EmployeeViewModel</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.FirstName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.FirstName) 
      @Html.ValidationMessageFor(model => model.FirstName) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.LastName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.LastName) 
      @Html.ValidationMessageFor(model => model.LastName) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Username) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Username) 
      @Html.ValidationMessageFor(model => model.Username) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.EmailAddress) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.EmailAddress) 
      @Html.ValidationMessageFor(model => model.EmailAddress) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 
このモデルを使用して単純なビューだレイアウトしましょう

私が使用したコントローラとアクションは以下の通りです

using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 
using TestApp.Models; 

namespace TestApp.Controllers { 

    public class HomeController : Controller { 

     public ActionResult Index() { 
      return RedirectToAction("Test"); 
     } 

     public ActionResult Test() { 
      var model = new EmployeeViewModel(); 
      return View(model); 
     } 

     [HttpPost] 
     public ActionResult Test(EmployeeViewModel model) { 
      // Force an error on this property - THIS should be the only real error that gets returned back to the view 
      ModelState.AddModelError("", "Error on First Name"); 

      if(model.EmailAddress == null) // Add an INFO message 
       ModelState.AddModelError("", "Email Address Info"); 
      if (model.Username == null) // Add another INFO message 
       ModelState.AddModelError("", "Username Info"); 

      // Get the Real error off the ModelState 
      var errors = GetRealErrors(ModelState); 

      // clear out anything that the ModelState currently has in it's Errors collection 
      foreach (var modelValue in ModelState.Values) { 
       modelValue.Errors.Clear(); 
      } 
      // Add the real errors back on to the ModelState 
      foreach (var realError in errors) { 
       ModelState.AddModelError("", realError.ErrorMessage); 
      } 
      return View(model); 
     } 

     private IEnumerable<ModelError> GetRealErrors(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary) { 
      var errorMessages = new List<ModelError>() ; 
      foreach (var keyValuePair in modelStateDictionary) { 
       if (keyValuePair.Value.Errors.Count > 0) { 
        foreach (var error in keyValuePair.Value.Errors) { 
         if (!error.ErrorMessage.Contains("Info")) { 
          errorMessages.Add(error); 
         } 
        } 
       } 

      } 
      return errorMessages; 
     } 
    } 
} 

あなたが好む代わり場合LINQとしてGetRealErrorsを書くことができます。

private IEnumerable<ModelError> GetRealErrors(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary) { 
    var errorMessages = new List<ModelError>() ; 
    foreach (var keyValuePair in modelStateDictionary.Where(keyValuePair => keyValuePair.Value.Errors.Count > 0)) { 
     errorMessages.AddRange(keyValuePair.Value.Errors.Where(error => !error.ErrorMessage.Contains("Info"))); 
    } 
    return errorMessages; 
} 

私はそれは私が、私はあなたが望んでいたことを理解して考えるように動作し、それはあなたが探していたものをあなたに与えます願っています。私に教えてください

+0

THX @CDスミス。あなたが正しい。私は "ModelStateのエラーを処理してエラーのテキスト値を維持しますが、エラーとして表示しない"ようにループしたいのですが...いくつかのエラーのためだけにしたいと思います。特に、私はテキスト内の文字列 "Info"を除いてすべてのエラーをmaintaingしたいと思います...可能ですか? 私の詳細に基づいて、より具体的な回答をしてください。 ありがとうございます。 – Larry

+1

ああ、はい、今何を意味するか分かります。私は答えを更新します –

+1

私は私の答えを更新しました。それを見て、あなたの考えを見てください。 –

関連する問題