4

首先,对不起我的英语。不是我的自然语言。

我有一个名为Category如下代码的类。请注意,在此代码中,我还有一个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()
}

上面的代码运行得很好。

现在问题来了:

当我单击 Save 按钮时,它会生成一个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. 我不需要这个属性来做我正在做的事情,我只需要Id这个Father属性。我可以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

您需要使用View Models。您的视图模型应该包含您在视图上需要的所有字段,减去父亲属性。然后在您的控制器中,您需要将视图模型映射到您的模型。您可以使用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 回答