1

我读过很多关于它的文章,而且似乎都是非常复杂的解决方案。但我相信应该有一个简单的方法来解决我的问题。

我已经使用 Attributes 对我的对象进行了实体框架验证,该属性从资源返回错误消息(但它与 ErrorMessage = ... 相同并不重要)。

[MetadataType(typeof(UserMetadata))]
public partial class User
{
     internal sealed class UserMetadata
     {
         [Required(AllowEmptyStrings = false, ErrorMessageResourceName = "UserNameRequired", ErrorMessageResourceType = typeof(ErrorMessage))]
         [StringLength(150, ErrorMessageResourceName = "UserNameLength", ErrorMessageResourceType = typeof(ErrorMessage))]
         public string UserName { get; set; }
     }
}

在我的 WCF 服务中,我有合同:

[ServiceContract]
public interface IUser
{
    [OperationContract]
    User AddUser(User user);
}

和实施:

public class UserService: IUser
{
    public User AddUser(User user)
    {
        //Here I think I should throw the ErrorMessage with a FaultException
        //and to catch it in the client side, but how to do it !?

        IUserRepository _user = new UserRepository(); //I've used EF Repository Pattern.
        return _user.Add(user);
    }
}
4

1 回答 1

2

最简单的方法是捕获DbEntityValidationException并将其转换为FaultException所需类型的 a。我将描述一个简单的版本。首先创建一个自定义故障:

[DataContract]
public class ValidationFault
{
}

修改服务契约,指明可能会抛出故障:

[ServiceContract]
public interface IUser
{
    [OperationContract]
    [FaultContract(typeof(ValidationFault))]
    User AddUser(User user);
}

并修改服务代码转换异常:

public class UserService: IUser
{
    public User AddUser(User user)
    {
        try
        {
            IUserRepository _user = new UserRepository(); //I've used EF Repository Pattern.
            return _user.Add(user);
        }
        catch (DbEntityValidationException ex)
        {
            throw new FaultException<ValidationFault>(new ValidationFault(), ex.Message);
        }
    }
}

您可能还想从 上的列表中复制DbEntityValidationResult数据。在这种情况下,您必须使用字段和定义另一个数据协定,并且您必须编写一些代码来复制每个错误消息。EntityValidationErrorsDbEntityValidationExceptionPropertyNameErrorMessage

当然,烦人的部分是您必须为每个服务操作编写相同的包装代码。您很快就会发现您需要将包装器代码移动到帮助器类中,但您仍然需要每次都编写 try-catch 代码。在我工作的地方,我们通过PostSharp使用面向方面的编程,以一种通用的方式解决了这个问题和类似的问题。我们创建了一个称为 的切面ValidationFaultAspect,它会在将异常应用于方法时自动转换异常。我认为可以使用 PostSharp 的免费版本来做到这一点,但我不能 100% 确定。

于 2013-08-22T10:36:52.360 回答