4

まず第一に、私の英語について申し訳ありません。私の自然言語ではありません。

Category以下のコードのような名前のクラスがあります。このコードにはCategory、父親のカテゴリを参照できるプロパティもあることに注意してください。これは、クラス内で宣言されたものとまったく同じクラスです。インセプションのように。したがって、このFather Categoryオブジェクトには、「彼を宣言したクラス」と同じプロパティがあります。

プロパティNameは必須です。このプロパティを覚えておいてください。

public class Category
{
    public int? Id{ get; set; }

    [DisplayName("Father Category")] //NOT REQUIRED
    public Category Father { get; set; }

    [DisplayName("Category")]
    [Required(ErrorMessage = "Name is required")] //REMEMBER THIS REQUIRED PROPERTY!!
    public string Name { get; set; }

    [DisplayName("Status")]
    public bool Status { get; set; }

    [DisplayName("Description")]
    public string Description { get; set; }
}

それが私のクラスです。

したがって、カテゴリビューでは、次のようなことができます。

注:CompleteEditorForCompleteDropDownListForは、レイアウトを調整するためだけに、各フィールドにHTMLを追加する拡張メソッドです。

@using (Html.BeginForm(null, null, FormMethod.Post))
{

    @Html.CompleteEditorFor(x => x.Name)
    @Html.CompleteEditorFor(x => x.Description)
    @Html.CompleteEditorFor(x => x.Status)

    @Html.CompleteDropDownListFor(x => x.Father.Id, ViewData["Categories"], "Id", "Name", "Select...")

    @Html.SubmitButton()
}

上記のコードは問題なく実行されます。

今問題があります:

[保存]ボタンをクリックすると、が作成されます。HttpPostこれはそのActionためのものです。

(以下のコードには、いくつかの変更されたメッセージ文字列と拡張メソッドがあります。)(CategoriesBLLデータベースからカテゴリを取得するクラスです。)

    [HttpPost]
    public ActionResult New(Category item)
    {
        ViewData.Add("Categories", CategoriesBLL.select());
        try
        {
            if (ModelState.IsValid)//PROBLEM IS HERE!!!!!!!!!
            {
                if (CategoryBLL.insert(item) != 0)
                {

                    ViewData.AddSuccess("Some Success Message");


                    return View(new Category());
                }
                else
                {
                    ModelState.AddError("Some error message");
                    return View(item);
                }
            }
            else
            {
                ModelState.AddError("Some SERIOUS error message");
                return View(item);
            }
        }
        catch (Exception ex)
        {
            ModelState.AddError("Some EVEN MORE SERIOUS message");
            return View(item);
        }

    }

問題はif (ModelState.IsValid)ラインにあります。

なんで?

私のCategoryクラスには。という必須のプロパティがあるためですName。私がしていることをするのにこのプロパティは必要ありません。必要なのIdFatherプロパティのだけです。Idビューのこの行でこれを取得できます:

@Html.CompleteDropDownListFor(x => x.Father.Id, ViewData["Categories"], "Id", "Name", "Select...")

そしてそれはうまくいきます。

ただし、Nameプロパティはnullであり、必須ですが、Childクラスに通知する場合にのみ必須です。父のクラスではありません。

GoogleやStackOverflowで検索する方法すら知りません...

誰か助けてもらえますか?

4

4 に答える 4

2

プロパティデコレータの代わりに、モデルでクラスIValidatableObjectインターフェイスを作成することを検討することをお勧めします。あなたが本当にプロパティデコレータを使いたいのなら、あなたはカスタムデコレータを正しく持っているかもしれません。

于 2013-03-22T20:11:48.897 に答える
2

ビューモデルを使用する必要があります。ビューモデルには、Fatherプロパティを除いて、ビューに必要なすべてのフィールドが含まれている必要があります。次に、コントローラーで、ビューモデルをモデルにマップする必要があります。Automapperを使用してこれを簡単に行うことができます。(ただし、ビューからドメインモデルへの直接マッピングはお勧めしませんが、後で整理します)

最初はこれはドラッグのように見えるかもしれませんが、私を信じてください。あなたの見解はあなたのドメインモデルと同じではありません。次に知っておくべきことは、ビューにある種のドロップダウンと、ドメインモデルにはないその他の追加のチェックボックスが必要になることです。また、ビューモデルを使用すると、セキュリティが向上します。興味があれば、それについての情報をお届けします。

于 2013-03-22T20:26:01.907 に答える
1
public class Category : IValidatableObject
{
    public int? Id{ get; set; }

    [DisplayName("Father Category")] //NOT REQUIRED
    public Category Father { get; set; }

    [DisplayName("Category")]
    [Required(ErrorMessage = "Name is required")] //REMEMBER THIS REQUIRED PROPERTY!!
    public string Name { get; set; }

    [DisplayName("Status")]
    public bool Status { get; set; }

    [DisplayName("Description")]
    public string Description { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var results = new List<ValidationResult>();
        if (this.Enable)
        {
            Validator.TryValidateProperty(this.Name ,
                new ValidationContext(this, null, null) { MemberName = "Name" },
                results);
            Validator.TryValidateProperty(this.Status,
                new ValidationContext(this, null, null) { MemberName = "Status" },
                results);
        }
        return results;
    }
}

public void Validate()
{
        var toValidate = new Category()
        {
            Name = "Just a name",
            Status = true
        };

        bool validateAllProperties = false;

        var results = new List<ValidationResult>();

        bool isValid = Validator.TryValidateObject(
            toValidate,
            new ValidationContext(toValidate, null, null),
            results,
            validateAllProperties);
}
于 2013-03-22T20:21:13.360 に答える
1
ModelState.Remove("PropertyNameInModel");

また

ModelState.Remove<ViewModel>(x => x.SomeProperty);
于 2017-10-05T20:00:29.027 に答える