基于EF4的WCF作为后端的MVC3 CRUD应用程序的验证方法

时间:2011-10-25 21:49:51

标签: asp.net-mvc wcf asp.net-mvc-3 validation wcf-client

我开发了一个简单的MVC3 CRUD应用程序 - 简单的控制器/视图,它使用WCF服务进行CRUD数据访问。

WCF使用EF4.1和DbContext,以及简单的CRUD样式方法:ListEntities,GetEntity(ID),AddEntity(entity),DeleteEntity(ID)

如果我直接使用EF开发MVC应用程序,首先是代码,我可以使用验证属性在实体类中注释属性,并且当我尝试保存时,MVC应用程序将自动识别验证错误并在UI中报告它们发生验证错误(例如,未设置必填字段)。

但在我的应用程序中,我不使用这种方法,我面临两个问题:

  1. 我在WCF中的实体是从EDMX生成的,而EDMX也是从数据库生成的。所以我实际上无法向它们添加任何数据验证注释属性,因为只要实体从EDMX重新生成它们就会消失。这有什么解决方案吗?

  2. 由于我的客户端(MVC app)不与WCF共享数据契约类(用于明确分离),而是从服务引用生成,即使我找到了向服务器添加数据注释属性的方法在客户端创建数据合同代理类时,是否会识别并重新创建数据合同类? 那么,当绑定到WCF服务公开的实体作为数据契约时,我怎样才能使MVC应用程序使用客户端验证和错误消息报告来验证失败?

  3. 我的一个想法是,在客户端,为作为数据契约公开的所有实体创建派生类,并将注释属性应用于所需的属性。但这对我来说看起来不是一个好的解决方案,因为有了这个,我在UI客户端和WCF服务/数据层之间创建了一个逻辑“耦合”(迫使UI更多地了解数据 - 通过放置BL逻辑在客户)。

    有谁能就如何处理这种情况给我一些建议?

    由于

3 个答案:

答案 0 :(得分:2)

1:是的,您可以使用System.ComponentModel.DataAnnotations.MetaDataType添加验证。

我在MVC Partial Model Updates

回答了这个问题

2a:你可以做的是创建一个单独的类库程序集,它包含所有接口(带或不带其他MetaDataTypes),并在WCF服务和MVC应用程序上使用它。将引用添加到MVC应用程序后,在添加WCF服务引用时,可以将WCF服务DataContacts直接与Assembly中的接口进行匹配。一个警告是WCF服务和MVC应用程序都依赖于程序集(有些可能认为这紧密耦合)但这应该没问题,因为你只是在接口级别紧密耦合,以及你是否选择允许VS重新创建它自己的接口/类或重用你在Assembly中创建的东西,它在我看来归结为同样的东西。

2b:如果您决定不使用类库,我很确定服务引用类是部分的,您可以简单地创建另一个带有部分类的.cs文件,并按照第1部分中的描述添加接口到部分班级。

<强>更新

我目前正在使用Entity Framework来访问我的数据库。实体框架,如WCF引用,类是自动生成的类看起来类似于:

[EdmEntityTypeAttribute(NamespaceName="MyNameSpace", Name="Info ")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Info : EntityObject
{
    public static Info CreateInfo (global::System.Int32 id)
    {
        Info info= new Info ();
        info.Id = id;
        return info;
    }

    public string Name { get; set; }
    public string FavoriteColor { get; set; }       

    // etc etc

}

在一个与前一个分部类具有相同名称空间的单独文件中,我创建了:

[SomeAttribute1]
[AnotherAttribute2]
public partial class Info: IInfo
{
}

所以现在我的自动生成的类不仅基于我创建的接口IInfo,因此实际的方法没有公开(因为我的MVC数据层返回接口),但它也有属性(用于数据注释)或者其他)。

我建议不要将数据注释直接放在WCF服务引用类上,而是使用MetedataType DataAnnotations。这允许您将实际数据对象与数据注释验证分开。如果您希望根据任何内容使用具有不同验证的相同数据类(管理员不必具有有效的收藏颜色),则特别有用。

例如:

public interface NormalUser
{
  [Required]
  string Name { get; set; }
  [Required]
  string FavoriteColor { get; set; }
}

public interface AdminUser
{
  [Required]
  string Name { get; set; }
  string FavoriteColor { get; set; }
}

[MetadataType(typeof(INormalUser))
public class NormalUserInfo : Info { }

[MetadataType(typeof(IAdminUser))
public class AdminUserInfo : Info { }

在此示例中,我们有两个不同的类NormaUserInfoAdminUserInfo,它们都有不同的验证。它们中的每一个都继承自Info,因此它们是可以传递到WCF服务的有效模型。

答案 1 :(得分:1)

出于我的想法,因为我现在无法测试它......

假设您的自动生成代码是这样的:

public partial class Employee
{
//some code here
}

您可以添加一个新的Employee类,也可以是部分的,而且这个类不会自动生成

[you can annotate here]
public partial class Employee
{
//somecode here
}

试试吧

答案 2 :(得分:1)

至于验证,您可以使用:http://fluentvalidation.codeplex.com/