2013-08-22 3 views
1

Я читал много статей об этом, и все это кажется очень сложным решением. Но я считаю, что должен быть простой способ решить мою проблему.Как пройти проверку достоверности От EntityFramework до WCF?

Я сделал проверку структуры Entity Framework для своих объектов с помощью атрибутов, которые возвращают сообщение об ошибке из ресурсов (но неважно, что это то же самое, что и 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); 
    } 
} 

ответ

2

Самый простой способ поймать DbEntityValidationException и преобразовать его в FaultException из желаемый тип. Я опишу простую версию этого. Сначала нужно создать пользовательскую ошибку:

[DataContract] 
public class ValidationFault 
{ 
} 

Modify договор на обслуживание, чтобы указать, что ошибка может быть выброшен:

[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, но я не уверен на 100%.

 Смежные вопросы

  • Нет связанных вопросов^_^