2012-05-29 3 views
1

WebAPI에 의해 자동으로 직렬화되는 개체가 있지만 데이터에 컨텍스트를 제공하기 위해 포장하고 싶습니다. 예제는 다음과 같습니다동적 일반 클래스 입력

이 직렬화
public class SecureModel<T> 
{ 
    public string Info { get; set; } 
    public T Data { get; set; } 
} 

은/내 JSON 요청과 문제를 직렬화 복원하지 않고 모두 잘있다. 그러나 요청 완료를 허용하기 전에 해당 Info를 확인하고 싶습니다. 그래서 POST의 매개 변수를 가져 오는 ActionFilter를 추가했습니다. 내가 인수를 검토 할 때, 정확히 내가 필요하지만 내가 약하게 실제 제네릭 형식을 지정하지 않고 SecureModel에 입력하는 방법을 알아낼 수 없습니다입니다

public class MyAuth : System.Web.Http.Filters.ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
    var arg = actionContext.ActionArguments.FirstOrDefault().Value; 
    // arg: get the Info? 
    // if the info isn't correct, return a specific Response. 
    } 
} 

. 나는 SecureModel < 객체 >에이 문제를 해결할 수 있어야하고 루트에 제대로 액세스 할 수 있어야한다고 생각하지만 허용하지 않습니다.

var notStrongEnough = arg.GetType().GetProperty("Info"); 

그러나, 나는 이것에 대한 반사를 사용하지 않으려는 내가 대답없이 전진 힘든 시간을 보내고 있어요 : 지금까지, 난 단지 내가 사용하여 필요한 데이터를 얻을 수 있습니다. 이 상황에서 내 대안은 데이터를 문자열로 변경하고 JSON 객체를 수동으로 직렬화/비 직렬화하는 것이지만 MVC3을 통해 Web API를 사용하는 목적을 일부 상쇄합니다.

참고 : SecureModel을 기본 클래스로 사용하도록 디자인을 변경하면 데이터에서 수행중인 일부 해싱 문제가 추가되어 해당 경로로 이동하지 않는 것이 좋습니다.

감사합니다.

편집 : 잘린 제목.

+0

동적 arg = actionContext.ActionArguments.FirstOrDefault(). 값 –

+0

C#에는 generics가 있지만 템플릿은 없습니다. 그것들은 다른 프로그래밍 모델입니다. –

답변

3

C#의 이런 종류의 문제에 대한 일반적인 해결책은 제네릭 형식이 구현하는 비 제네릭 인터페이스를 만드는 것입니다. 예를 들어, 클래스 :

public class SecureModel<T> 
{ 
    public string Info { get; set; } 
    public T Data { get; set; } 
} 

당신은 인터페이스, ISecureModel 정의 할 수 있습니다 :

public interface ISecureModel 
{ 
    string Info { get; } 
    object Data { get; } 
} 

을 그리고 지금 당신은 당신의 데이터 클래스를 구현할 수 있습니다

public class SecureModel<T> : ISecureModel 
{ 
    public string Info { get; set; } 
    public T Data { get; set; } 

    object ISecureModel.Data { 
     get { return Data; } 
    } 
} 

우리는 명시 적으로 사용 (object) 및 일반용 (T) 버전이 Data 인 공동 작업을 수행하기 때문에 인터페이스 구현이 여기에 포함됩니다. 라이드.

이제 정보를 얻으려면 ISecureModel으로 전송하면됩니다.

+0

정확히 내가 제안하려고했던 것. :) – ivowiblo

1

개인적으로 별도의 유형이 지정되지 않은 인터페이스를 생성하고 실행을 선택합니다 :

interface IObjectTypeSercureModel 
{ 
    object GetData(); 
    string GetInfo(); 
} 

을하지만, 그것은 당신이 별도의 인터페이스로 getter 및 setter를 분할 할 수 있습니다, C#을 템플릿을 co-variance 기능을 사용 할 수있을 것입니다 :

public interface IReadModel<out T> 
{ 
    T Data {get;} 
    string Info { get; } 
} 
public interface IWriteModel<in T> 
{ 
    T Data { set; } 
    string Info { set; } 
} 
public class SecureModel<T> : IReadModel<T>, IWriteModel<T> 
{ 
    public string Info { get; set; } 
    public T Data { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var m = new SecureModel<string>(); 
     m.Data = "test"; 

     IReadModel<object> genericRead = (IReadModel<object>)m; 
     Console.WriteLine(genericRead.Data); 
    } 
}