我正在寻找将现有的JSON API从hacky MVC3实现转换为最新的MVC4 Web Api。 MVC3实现使用JSON.NET来完成所有序列化操作,这将使升级更加流畅。自定义ASP Web API通过其调用Action的Json序列化
我被困在定制某些动作的结果如何被序列化。例如,我想要一些操作只返回输出对象的一些属性,而其他操作可能会做很深的序列化。在我目前的实现中,一个动作可以通过在HttpContext
中设置适当的设置来添加一堆序列化覆盖。稍后通过从JsonResult
派生的类来获取这些自定义序列化。添加自定义JsonConverters
的主要用途是控制和减少获取序列化的键/值的数量,并根据动作改变要序列化的参数(某些动作应该返回比其他动作更多的对象参数)。
控制器和我目前MVC3实现的类控制JSON序列化的简明例如:
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
}));
}
}
在网页API我看到,我可以从配置JSON的格式化和全球改变序列化。
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序列化程序能够找到为调用的操作/控制器提供的相关属性,并相应地更改序列化。我不确定在哪里以及如何做到这一点。我应该从JsonMediaTypeFormatter
继承,并在那里做某些工作?我还有什么其他选择?