asp.NET MVC 2 DataAnnotations UpdateModel;验证

发布于 2024-08-20 06:58:01 字数 2135 浏览 2 评论 0原文

我正在尝试使用 DataAnnotations 在 asp.NET MVC 2 RC2 中向我的模型添加验证,使用 TryUpdateModel

        var user = UserManager.Find(id);

        this.TryUpdateModel<IProvisioningObject>(user, form.ToValueProvider());

这会更新模型,但从未调用验证。我也尝试使用TryUpdateModel(这是用户的直接类型),不使用表单值提供程序,直接使用ProvisioningObject(其中具有验证元数据),但无济于事。

谷歌搜索示例仅提供了通过参数绑定来使用 DataAnnotations 的方法,

public ActionResult Update(User user)

而我不喜欢更新场景。

有什么提示和/或解决方案吗?

编辑 我的对象是从 WCF 服务自动生成的对象。

我制作了部分以便能够添加数据注释。 我调用 TryUpdateModel 三次,因为它显然不支持继承,我认为这也是我的 DataAnnotations 问题。我指定了 ProvisioningObject 的验证属性,并且绑定不会查找类似的继承内容。

[MetadataType(typeof(ProvisioningObjectMetadata))]
public partial class ProvisioningObject : IProvisioningObject
{
    public string DisplayNameInvariant { get { return string.IsNullOrEmpty(this.DisplayName) ? this.Name : this.DisplayName; } }
}


[MetadataType(typeof(UserMetadata))]
public partial class User : IUser
{
}


public class ProvisioningObjectMetadata
{
    [DisplayName("Country")]
    public string CountryIsoCode { get; set; }

    [Required(ErrorMessageResourceType = typeof(Properties.Validation), ErrorMessageResourceName = "DisplayNameIsRequired")]
    [TempValidator]
    public string DisplayName { get; set; }
}


public class UserMetadata
{
    [DisplayName("Username")]
    public string Name { get; set; }
}


// Controller action
    public ActionResult Update(string id, FormCollection form)
    {
        var user = UserManager.Find(id);

        this.TryUpdateModel<IUser>(user.User, form.ToValueProvider());
        this.TryUpdateModel<IPerson>(user.User, form.ToValueProvider());
        this.TryUpdateModel<IProvisioningObject>(user.User, form.ToValueProvider());

        if (ModelState.IsValid) // always true
        {
            return Redirect;
        }
        else
        {
            return View();
        }
    }

如果我在 UserMetadata 中添加 DisplayName 的元数据,它会按预期工作,但这似乎非常多余。这意味着我还必须复制/粘贴所有继承的接口,以便 TryUpdateModel 行为适当。

我想我正在寻找一种不需要我将验证属性复制并粘贴到继承的类中的方法。

I'm trying to use DataAnnotations to add validation to my models in asp.NET MVC 2 RC2, using TryUpdateModel

        var user = UserManager.Find(id);

        this.TryUpdateModel<IProvisioningObject>(user, form.ToValueProvider());

This updates the model, but the validation is never called. I tried using TryUpdateModel as well (which is the direct type of user), not using the form value provider, using ProvisioningObject directly (which has the validation metadata), to no avail.

Googling for examples only gives me ways to use DataAnnotations by binding through a parameter

public ActionResult Update(User user)

Which I dislike for update scenarios.

Any tips and/or solutions?

EDIT
My objects are auto-generated objects from a WCF service.

I made partials to be able to add DataAnnotations.
I call TryUpdateModel three times because it apparently doesn't support inheritance, which I think is also my problem with DataAnnotations. I specify the validation attributes for ProvisioningObject, and the binding doesn't look for inherited stuff like that.

[MetadataType(typeof(ProvisioningObjectMetadata))]
public partial class ProvisioningObject : IProvisioningObject
{
    public string DisplayNameInvariant { get { return string.IsNullOrEmpty(this.DisplayName) ? this.Name : this.DisplayName; } }
}


[MetadataType(typeof(UserMetadata))]
public partial class User : IUser
{
}


public class ProvisioningObjectMetadata
{
    [DisplayName("Country")]
    public string CountryIsoCode { get; set; }

    [Required(ErrorMessageResourceType = typeof(Properties.Validation), ErrorMessageResourceName = "DisplayNameIsRequired")]
    [TempValidator]
    public string DisplayName { get; set; }
}


public class UserMetadata
{
    [DisplayName("Username")]
    public string Name { get; set; }
}


// Controller action
    public ActionResult Update(string id, FormCollection form)
    {
        var user = UserManager.Find(id);

        this.TryUpdateModel<IUser>(user.User, form.ToValueProvider());
        this.TryUpdateModel<IPerson>(user.User, form.ToValueProvider());
        this.TryUpdateModel<IProvisioningObject>(user.User, form.ToValueProvider());

        if (ModelState.IsValid) // always true
        {
            return Redirect;
        }
        else
        {
            return View();
        }
    }

If I add the metadata for DisplayName in UserMetadata, it works as expected, but that seems very redundant for nothing. And it would mean I would also have to copy/paste all my inherited interfaces so TryUpdateModel behaves appropriately.

I guess I'm looking for a way that doesn't require me to copy and paste my validation attributes to inherited classes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你在我安 2024-08-27 06:58:02

新答案:

“我的对象是从 WCF 服务自动生成的对象。”

自动生成的对象不会有任何属性。您是在服务器端还是在客户端定义对象及其属性?

旧答案:
如果您的元数据不在 IProvisioningObject 上,则不会调用任何验证。 MVC2 默认模型绑定器只知道如何查找“额外”[MetadataType(buddyClass)] 验证信息。

对于更新场景,如果 IsValid() 到您的主模型类,则绑定 DTO,然后映射 DTO。

New Answer:

"My objects are auto-generated objects from a WCF service."

Autogenerated objects won't have any attributes on them. Are you defining your objects and their attributes on the server side or on the client side?

Old Answer:
If your metadata is not on IProvisioningObject then no validation will be called. The MVC2 default model binder only knows how to find "extra" [MetadataType(buddyClass)] validation information.

For update scenarios bind against DTOs and then map the DTOs, if IsValid() to your main model classes.

欢你一世 2024-08-27 06:58:02

在您的分部类中实现 IDataErrorInfo 接口
您必须为每个字段编写自定义验证(您可以使用数据注释类来验证每个必需的属性)

如果您需要代码示例,请告诉我。我给你写吧!

来源: http://www.asp .net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/mvc/tutorial-37-cs.aspx

Implement IDataErrorInfo interface in your partial class
You will have to write custom validation for each field(where you can use data annotation class to validate each required property)

If you need code example then let me know. I will write it for you!

source: http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/mvc/tutorial-37-cs.aspx

小耗子 2024-08-27 06:58:02

你怎么知道验证没有被调用?您是否在更新控制器中检查 ModelState.IsValid 并发现它错误地返回 true?

典型的更新模式是:

UpdateModel(model);
if(!ModelState.IsValid) return View(model);
return RedirectToAction("Index");

如果您期望模型上的某些“IsValid”自动被调用,那么这种情况不会发生。数据注释通过 Controller 基类上的 ModelState 字典在幕后工作。

How do you know that the validation is not being called? Are you checking ModelState.IsValid in your update controller and finding that it is erroneously coming back true?

A typical update pattern is:

UpdateModel(model);
if(!ModelState.IsValid) return View(model);
return RedirectToAction("Index");

If you are expecting some "IsValid" on your model to automatically be called, that will not happen. The data annotations work behind the scenes with the ModelState dictionary on the Controller base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文