2015-01-07 2 views
0

[이것은 명백한 질문의 종류하지만 난 그것에 대해 아무것도 찾을 수 없습니다 - 누군가가 저를 참조 할 수 있다면, 그것은 그랜드 수 있습니다.]는 WebAPI 프로젝트에서검증 직렬화 복원 객체는 계약합니다

:

public class MyObject 
{ 
    [PostSharp.Patterns.Contract.Required] 
    public string Name {get;set;} 
} 

public class MyController : ApiController 
{ 
    public HttpResponseMessage Post([FromBody]MyObject obj) 
    { 
     /// ... 
    } 
} 

컴파일하는 동안, 나는 PostSharp의 검증은 호텔의 세터에 자신을 넣어 것 같아요, 그래서 obj이 요청의 몸에서 직렬화 복원 될 때, 그 필드는 검증되지 않습니다.

그래서 그 개체의 유효성을 검사하는 가장 좋은 방법은 무엇입니까?

건배

답변

0

다니엘 발라스 (Daniel Balas)가 썼듯이, OnDeserialized 메서드를 구현하는 것 이외에는 객체를 비 직렬화 한 후 PostSharp의 유효성 검사를 트리거하는 간단한 해결책은 없습니다. ISerializationCallback 인터페이스입니다. 그래서 저는 Aspect에 글을 쓴 적이 있습니다. 객체의 공개 속성을 리플렉션을 통해 하나씩 깊이 복사하여 설정자의 유효성 검사를 활성화한다고 썼습니다.

[Serializable] 
    public sealed class ArgsValidationAspect : MethodInterceptionAspect 
    { 
     public override bool CompileTimeValidate(MethodBase method) 
     { 
      if (!method.GetParameters().Any(p => p.ParameterType.IsClass)) 
      { 
       Message.Write(method, SeverityType.Error, "MY001", "Cannot apply HttpObjectValidationAspect to method '{0}'.", method); 
       return false; 
      } 

      return true; 
     } 


     public override void OnInvoke(MethodInterceptionArgs args) 
     { 
      foreach (var arg in args.Arguments) 
      { 
       try 
       { 
        RecursiveCopyInstance(arg); 
       } 
       catch (Exception e) 
       { 
        throw e.InnerException ?? e; 
       } 
      } 

      base.OnInvoke(args); 
     } 

     private static object RecursiveCopyInstance(object origin) 
     { 
      var type = origin.GetType(); 
      var instance = Activator.CreateInstance(type); 

      foreach (var prop in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) 
      { 
       var val = prop.GetValue(origin); 
       if (val != null && !prop.PropertyType.IsPrimitive && !prop.PropertyType.Equals(typeof(string))) 
       { 
        val = RecursiveCopyInstance(val); 
       } 

       prop.SetValue(instance, val); 
      } 

      return instance; 
     } 
    } 
0

가 한번 직렬화 된 객체가 이미 유효한 것으로 추정되는 등의 검증을 달성하기 위해 더 깨끗한 방법은 현재 없습니다.

유효성 검사 논리를 적용하려면 ISerializationCallback 인터페이스의 OnDeserialized 메서드를 사용해야하며 속성을 확인한 다음 유효성 검사를 시행하기 위해 강제로 현재 값으로 설정해야합니다.

이 작업은 PostSharp 측면에서 수행 할 수 있지만 확실히 중요하지는 않습니다. 다른 가능성은 같은 것을 달성하기 위해 reflection/expression tree를 사용하는 것입니다.

이것이 PostSharp의 멋진 기능이라고 생각하면 PostSharp's UserVoice page에 투표 할 수 있습니다.