我正在考虑将现有的 JSON api 从 hacky MVC3 实现转换为最新的 MVC4 Web Api。MVC3 实现使用 JSON.NET 来完成所有的序列化,这将使升级顺利而顺利。
我坚持自定义某些操作的结果如何序列化。例如,我希望某些操作仅返回输出对象的几个属性,而其他操作可能会进行相当深度的序列化。在我当前的实现中,一个动作可以通过在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
}));
}
}
在 Web 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
并在那里工作吗?我还有什么其他选择?