2011-08-01 4 views
2

ASP MVC3 용 Protobuf ValueProviderFactory를 작성하려고합니다. 나는 how to add the factories을 해결할 수 있었지만 지금은 더 긴급한 문제를 발견했습니다. 현재의 직렬화는 직렬화가 모든 종류의 정보없이 수행됩니다 그래서형식 정보가 필요한 MVC3 ValueProviderFactories 만들기

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
    object jsonData = serializer.DeserializeObject(bodyText); 
    return jsonData; 

JsonValueProviderFactory.cs에서 일어나는 곳 여기 은? DeserializeObject은 어떤 종류의 물체를 반환합니까? 동적? 데이터 유형을 어떻게 알 수 있습니까? 여기에 protobuf-net을 삽입하기를 바랬지 만 분명히 마술을하기위한 유형이 필요합니다!

모든 MVC3 소스를 조사하지는 않았지만 유형에 대한 매핑이 최종 단계에서 발생한다고 생각합니다. ValueProviderFactories의 유형을 알 수있는 방법이 없습니다.

작업을 포기하고 변환해야합니까?

+1

재 유형은 - 그것이'Type' 인스턴스를 필요가 있습니다,하지만 당신은 일반적인 API를 사용할 필요가 없습니다. 이것은'ParameterInfo'와 같은 것에서'Type'을 유추 할 수 있다면 가능하다는 것을 의미합니다. –

답변

2

여기에 몇 가지 질문이 있습니다.

JavaScriptSerializer의 작동 방법은 documentation입니다. 이 클래스는 기본 유형 (int, bool, date 등)에 대한 유형을 추측하려고 시도하며보다 복잡한 경우에는 Dictionary<string, object>을 반환합니다. 또한 JSON BLOB에 "__type"이라는 특수 속성이 포함 된 경우 디시리얼라이저는 해당 유형의 객체를 만들려고 시도합니다.

이제 MVC에서 어떻게 작동하는지 살펴 보겠습니다. 요청에서 컨트롤러에 사용 된 객체 인스턴스에 값을 매핑하는 프로세스를 모델 바인딩이라고합니다. 이것은 두 개의 컴포넌트 인 ModelBinder와 ValueProviders로 나뉩니다. 모델 바인더는 대상 유형 (예 : Product)을 알고 인스턴스를 만들고 속성의 속성을 요청의 값으로 채 웁니다. ValueProviders에게 요청하면됩니다. 예를 들어, Product 인스턴스의 Name 속성을 설정하기 위해 값 공급자에게 "Name"값을 요청합니다. 값 공급자는 순서대로 쿼리되고 쿼리 문자열, 게시 데이터, JSON 요청 본문 등에서 일치 항목을 반환합니다.

웹상에서 이에 대한 많은 자료가 있지만 짧은 값 공급자는 실제로 유형과 관련해서는 안됩니다.

+0

몇 가지 이유로 저는 ModelBinders를 할인했지만 훨씬 더 의미가 있습니다 ... – Tim

1

여기는 marcind에서 제안한 ModelBinder를 사용하는 솔루션의 빠른 찌르기입니다. 테스트되지 않았지만 시작일뿐입니다. 이 경우 FromProtobuf<T>은 오브젝트 확장 메소드에 대한 간단한 byte[]입니다.

public class ProtobufModelBinder<T> : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/x-protobuf", StringComparison.OrdinalIgnoreCase)) 
      return null; 

     using (MemoryStream ms = new MemoryStream()) 
     { 
      controllerContext.HttpContext.Request.InputStream.CopyTo(ms); 
      return ms.ToArray().FromProtobuf<T>(); 
     } 
    } 
} 

이것은 다음과 같이 설정 될 수있다 :

ModelBinders.Binders.Add(typeof(MyClass), new ProtobufModelBinder<MyClass>());