2

カスタムエラーハンドラを少し実行しようとしています。(JQueryタブを使用して)4つのタブがあり、それらはすべて1つの大きなモデルから構築されています。簡単にするために、モデルは次のようになります。

myModel.HomeInfo
myModel.PhoneNumbers
myModel.Addresses
myModel.PersonalDetails

各部分は、さまざまな情報を持つオブジェクトです。それらはすべて属性を持ち、メッセージを検証します。

ページの上部(タブの上)に、いくつかのトップレベルのエラーを表示したいと思います。つまり、「myModel」オブジェクトの属性のエラーを意味します。これは、次の場合に機能します。

foreach (ModelState state in viewData.ModelState.Values)

私がする時:

@Html.ValidationSummary(false)

私の見解では、4つのオブジェクトのそれぞれとそのすべての子(10以上)からすべてのエラーが発生します。しかし、自分自身のエラー(上記のコード)を実行すると、2つのエラーしか発生しません(「myModel」のエラーのみであり、その子プロパティではありません)。

ILSPYを使用して、検証の概要が何を行っているかを確認し、それを複製しようとしました。私はコードをほぼ一行ずつ持っていたと信じていますが、それでも2つのエラーしかありませんでした。

@ Html.ValidationSummary()を使用すると、どのような魔法が起こっているのかわかりません。

私が知りたいのは、オブジェクト全体のすべてのエラーを自分で取得して、各タブにいくつかのエラーを表示できるようにする方法です。

明確にするために、ここに私の基本的なモデルがあります:

public class MemberProfileModel
{
    [CompanyTabValid]
    public CompanyInformationModel CompanyInformation { get; set; }
    [ContactTabValid]
    public ContactInformationModel ContactInformation { get; set; }
    [InvoiceTabValid]
    public InvoiceInformationModel InvoiceInformation { get; set; }
    [TabProductIdentificationMarkValid]
    public ProductIdentificationMarkModel ProductIdentificationMark { get; set; }
 }

public class CompanyTabValid : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        var model = value as CompanyInformationModel;
        if(model == null) throw new ArgumentNullException("value");

        var failed = new ValidationResult("Company information incomplete.");

        return model.IsValid ? ValidationResult.Success : failed;
    }
}

public class ContactInformationModel : BaseModel
{
    public ContactInformationModel()
    {
        PrimarySiteAddress = new AddressInformation();
        PrimarySiteContact = new ContactInformation();
        RegisteredOfficeAddress = new AddressInformation();
        RegisteredOfficeContact = new ContactInformation();

    }
    public override void Validate()
    {
        IsValid = PrimarySiteAddress.IsValid &&
                  PrimarySiteContact.IsValid &&
                  RegisteredOfficeAddress.IsValid &&
                  RegisteredOfficeContact.IsValid;
    }
    public AddressInformation PrimarySiteAddress { get; set; }
    public ContactInformation PrimarySiteContact { get; set; }
    public AddressInformation RegisteredOfficeAddress { get; set; }
    public ContactInformation RegisteredOfficeContact { get; set; }

}

public class AddressInformation : BaseModel
{
    public int Id { get; set; }
    public Guid MemberId { get; set; }
    /// <summary>
    /// This property is only here to make EF happy, do not use
    /// </summary>
    public int LocationTypeValue { get; set; }
    public LocationType LocationType { get { return (LocationType) LocationTypeValue; }  set { LocationTypeValue = (int) value;  } }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Address Line 1 required.")]
    [Display(Name = "Address Line 1 *")]
    public string AddressLine1 { get; set; }

    [Display(Name = "Address Line 2")]
    public string AddressLine2 { get; set; }

    [Display(Name = "Address Line 3")]
    public string AddressLine3 { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Town required.")]
    [Display(Name = "Town *")]
    public string Town { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "County required.")]
    [Display(Name = "County *")]
    public string County { get; set; }

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

    [RequiredOneOfTwo("InterationalPostCode", ErrorMessage="PostCode or international PostCode are required.")]
    [Display(Name = "Post Code *")]
    public string PostCode { get; set; }

    [RequiredOneOfTwo("PostCode", ErrorMessage = "International PostCode or PostCode are required.")]
    [Display(Name = "International Post Code *")]
    public string InterationalPostCode { get; set; }

    public override void Validate()
    {

        if (string.IsNullOrEmpty(AddressLine1))
        {
            this.IsValid = false;
            return;
        }
        else if (string.IsNullOrEmpty(Town))
        {
            this.IsValid = false;
            return;
        }
        else if (string.IsNullOrEmpty(County))
        {
            this.IsValid = false;
            return;
        }
        else if (string.IsNullOrEmpty(Country))
        {
            this.IsValid = false;
            return;
        }
        else if (string.IsNullOrEmpty(PostCode) && string.IsNullOrEmpty(InterationalPostCode))
        {
            this.IsValid = false;
            return;
        }

        this.IsValid = true;
        return;
    }
}

検証属性の例(カスタムのものもあれば、通常のものもあります)を示しました。この例では、最上位のMemberProfileModel = myModelであり、ContactInformationModelはその子の1つであり、AddressInformationなどの独自のオブジェクトがあります。

ありがとう

4

3 に答える 3

1

なぜこれがうまくいかなかったのかがわかりました。いつものように、私はばかげていました。モデルには複数のレイヤー/レベルがあるため、つまりmodel.someobject.someotherobject.somepropertyは、tryValidateModelを呼び出すと、最上位レベルを検証しますが、内部レイヤーは検証しません。

これに対する解決策は、それらがすべて呼び出されるようにすることでした。

            TryValidateModel(mp);
            TryValidateModel(mp.ContactInformation.PrimarySiteAddress);
            TryValidateModel(mp.ContactInformation.RegisteredOfficeAddress);

したがって、私の解決策は、各オブジェクトレベルでtry validateを呼び出すメソッドを作成するか、それを実行するためのrefelctiveメソッドを作成することです。

于 2012-08-29T10:35:28.523 に答える
0

ページのポストイベントで、コントローラーに次を追加します。

[HttpPost]
public ActionResult Create(TestViewModel testViewModel)
{
// If not Valid
if (!ModelState.IsValid)
{
   return this.View(testViewModel)
}
...
}

また、必要な検証やその他の検証をビューモデルアクセスメソッドに追加することを忘れないでください。

[Required(ErrorMessageResourceType = typeof(Resources.MyProject), ErrorMessageResourceName = "validation_Test")]
public virtual string HomeInfo { get; set; }

そしてあなたの見解では:

<div class="editor-row">
        <div class="editor-label">
            @Html.LabelFor(model => model.HomeInfo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.HomeInfo)
            @Html.ValidationMessageFor(model => model.HomeInfo)
        </div>
</div>
于 2012-08-24T12:26:58.237 に答える
0

私はここからこれを入手しました:http: //www.unknownerror.org/opensource/aspnet/Mvc/q/stackoverflow/1352948/how-to-get-all-errors-from-asp-net-mvc-modelstate

public static List<string> GetErrorListFromModelState
                                              (ModelStateDictionary modelState)
{
      var query = from state in modelState.Values
                  from error in state.Errors
                  select error.ErrorMessage;

      var errorList = query.ToList();
      return errorList;
}
于 2016-06-18T02:34:27.690 に答える