我读过很多关于它的文章,而且似乎都是非常复杂的解决方案。 但我相信应该有一个简单的方法来解决我的问题。
我已经使用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);
}
}
答案 0 :(得分:2)
最简单的方法是捕获DbEntityValidationException
并将其转换为所需类型的FaultException
。我将描述一个简单的版本。首先创建一个自定义错误:
[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
上EntityValidationErrors
列表中的DbEntityValidationException
数据。在这种情况下,您必须使用字段PropertyName
和ErrorMessage
定义另一个数据协定,并且必须编写一些复制每个错误消息的代码。
当然,烦人的部分是你必须为每个服务操作编写相同的包装器代码。您很快就会发现需要将包装器代码移动到辅助类,但您仍需要每次都编写try-catch代码。在我工作的地方,我们使用PostSharp使用面向方面的编程以一种通用的方式解决了这个和类似的问题。我们创建了一个名为ValidationFaultAspect
的方面,它在应用于方法时自动转换异常。我认为使用PostSharp的免费版本可以做到这一点,但我不是百分百肯定。