2012-08-01 5 views
6

hacky MVC3 구현에서 기존 JSON API를 최신 MVC4 Web API로 변환하는 방법을 찾고 있습니다. MVC3 구현은 JSON.NET을 사용하여 모든 직렬화 작업을 수행하므로 업그레이드가 원활하고 원활합니다.Action이 호출되는 ASP 웹 API Json serialization 사용자 정의

일부 동작의 결과가 어떻게 serialize되는지 맞춤 설정해야합니다. 예를 들어 출력 객체의 몇 가지 속성 만 반환하는 액션을 원하지만 다른 것들은 다소 복잡한 직렬화를 수행 할 수 있습니다. 현재 구현에서 액션은 HttpContext에 적절한 설정을 지정하여 일련 번호를 재정의 할 수 있습니다. 이들은 나중에 JsonResult에서 파생 된 클래스를 통해 사용자 지정 직렬화를 위해 선택됩니다. 사용자 지정 JsonConverters을 추가하는 주된 용도는 직렬화되는 키/값의 수를 제어하고 줄이고 작업에 따라 serialize 할 매개 변수를 변경하는 것입니다 (특정 작업은 다른 개체 매개 변수보다 많은 개체 매개 변수를 반환해야 함).

컨트롤러와 내 현재 MVC3 구현의 클래스 제어 JSON 직렬화의 응축 예 : 내가이 구성에서 JSON 포매터를 취득하고 전 세계적으로 직렬화를 변경할 수 있음을 참조 웹 API의

public class TestController : JsonController { 
    public JsonResult Persons() { 
     ControllerContext.HttpContext.Items[typeof(IEnumerable<JsonConverter>)] = new JsonConverter[] { 
      new InterfaceExtractorJsonConverter<IPersonForList>(), 
      new StringEnumConverter() 
     }; 

     ControllerContext.HttpContext.Items[typeof(IContractResolver)] = new SpecialCamelCasePropertyNamesContractResolver(); 
    } 
} 

public class JsonNetResult : JsonResult { 
    public override void ExecuteResult(ControllerContext context) { 
     var response = context.HttpContext.Response; 

     var additionalConverters = context.HttpContext.Items[typeof(IEnumerable<JsonConverter>)] as IEnumerable<JsonConverter> ?? Enumerable.Empty<JsonConverter>(); 

     var contractResolver = context.HttpContext.Items[typeof(IContractResolver)] as IContractResolver ?? new JsonContractResolver(); 

     var typeNameHandling = TypeNameHandling.None; 
     if (context.HttpContext.Items.Contains(typeof(TypeNameHandling))) 
      typeNameHandling = (TypeNameHandling)context.HttpContext.Items[typeof(TypeNameHandling)]; 

     response.Write(JsonConvert.SerializeObject(Data, Formatting.Indented, new JsonSerializerSettings { 
      ContractResolver = contractResolver, 
      ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
      Converters = additionalConverters, 
      TypeNameHandling = typeNameHandling 
     })); 
    } 
} 

.

var config = new HttpSelfHostConfiguration("http://localhost:8080"); 

var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().Single(); 

jsonFormatter.SerializerSettings.ContractResolver = new SpecialCamelCasePropertyNamesContractResolver(); 
jsonFormatter.SerializerSettings.Converters = new[] { new InterfaceExtractorJsonConverter<ITesting>() }; 

그러나, 나는 사용할 JsonConverter's 지정하는 일부 속성을 추가하여 개별적으로 (또는 컨트롤러 당)에 대한 작업의 직렬화를 제어 계획되었다. 따라서 Json serializer가 호출 된 action/controller에게 주어진 관련 속성을 찾아 그에 따라 serialization을 변경하고 싶습니다. 나는 어디서 어떻게해야하는지 잘 모르겠습니다. 내가 JsonMediaTypeFormatter에서 상속해야하고 어떻게 든 그곳에서 일을해야합니까? 다른 옵션은 무엇입니까?

답변

2

그런 식으로 직렬화를 제어하고 싶지 않은 사람은 본 적이 없습니다.

class JsonNetFormatter : MediaTypeFormatter { 
    public override bool CanWriteType(Type t) { 
     return typeof(JsonNetResponse).IsAssignableFrom(t); 
    } 
    // TODO WriteToStreamAsync which is basically a copy of your original JsonNetResult 
} 
: 해당 개체를 처리 할 수있는 것보다

class JsonNetResponse { 
    public IContractResolver ContractResolver { get;set; } 
    // Other Json.Net bits 
    public object Value { get; set; } 
} 

내가 다음 사용자 정의 포맷터를 만들 것이다 : 그러나 재 작업의 최소 금액 당신의 목표를 달성하기 위해, 내가 직접 방법에서 그 모든 정보를 반환