使用实体框架在asp.net MVC 3中进行服务器端验证

时间:2011-10-19 09:35:35

标签: asp.net-mvc-3 validation entity-framework-4 required

我正在使用带有Enitity frameword的asp.net MVC3。两者都通过WCF Web服务进行通信。

问题在于,在服务器端,DB开发人员不希望将[Required] / [Range]属性设置为Entity类中的属性。但我想在mvc3应用程序中验证我的结果。我在哪里添加了WCF webservice引用。哪个生成了代理。

我不想根据客户端策略使用Jquery / javascript。所以我需要在我的控制器/模型级别执行此操作。怎么管理这个?一些我如何需要从mvc 3 aaplication动态地将所需属性添加到每个实体的属性。需要正确的方向加快。

忘记添加:Db开发人员严格避免用户需要。还没有在实体和映射中生成db。

4 个答案:

答案 0 :(得分:2)

您必须write a code to validate your entities。即使开发人员在实体上使用了这些属性,您也不会拥有它们,因为您通过WCF生成的代理访问DAL,并且这些属性不是由您的工具生成的。

添加服务引用生成的所有类都应该是部分的,这样您就可以添加自定义部分部分并实现验证(通过实现IValidatableObject接口)。

答案 1 :(得分:2)

我同意Ladislav Mrnka,但如果您无法更改实体类的属性,则必须将其取消:

[MetadataType(typeof(YourOwnClassForValidation))]
public partial class ClassOfYourDbDeveloper
{
    // db developer doesn't allow you to change this
    public string Title { get; set; }
}

public class YourOwnClassForValidation
{
    // here you can use your data annotations
    // important to use object
    [Required]
    public object Title { get; set; }
}

仅用于设置属性,请在底部阅读更多相关内容:http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs

答案 2 :(得分:1)

您可以注册一个类,用作模型的元数据/验证提供程序。

拥有无法更改的实体:

public class MyModel 
{
    public int IntProperty { get; set; }

    public DateTime DateProperty { get; set; }
}

您可以在MVC端拥有它的元数据,您可以验证并提供元数据,就像它是原始类一样:

[ValidationAttribute(...)]
[ValidationAttribute(...)]
public class MyModelValidator
{
    [Required]
    [Display("My Integer")]
    public int IntProperty { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime DateProperty { get; set; }
}

最后,您只需将Metadata / Validator类附加到对应的基类,例如Global.asax:

protected void Application_Start()
{
    AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider;

    typeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(
            typeof(MyModel),
            typeof(MyModelValidator));

    TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, typeof(MyModel));

    // register other metadata classes
}

您可以为所需的每个实体执行此操作。

答案 3 :(得分:1)

使用视图模型。他们的预期目的之一是从视图中抽象出模型(作为MV中的M)对象。

在视图模型中放置验证属性,并使用映射器(如automapper)将信息复制到数据库实体或从数据库实体复制信息。

在控制器操作中使用ModelState.IsValid来检查视图模型是否有效。

我的POST动作方法通常看起来有点谎言:

[HttpPost]
public virtual ActionResult Edit(EditModel model)
{
    if (!ModelState.IsValid)
        return View(model);

    try
    {
        // fetch db entity
        var template = _templateService.Get(model.Id);

        // copy info from view model to db entity
        Mapper.Map(model, template);

        // save db entity
        templateService.Save(template);

        return RedirectToAction("Details", new { id = template.Id });
    }
    catch (Exception err)
    {
        Logger.Error("Failed to save template", err);
        ModelState.AddModelError("", err);
        return View(model);
    }
}