gpt4 book ai didi

c# - 自定义调用 Action 的 ASP Web API Json 序列化

转载 作者:太空狗 更新时间:2023-10-29 19:46:03 25 4
gpt4 key购买 nike

我正在考虑将现有的 JSON API 从 Hacky MVC3 实现转换为最新的 MVC4 Web Api。 MVC3 实现使用 JSON.NET 进行所有序列化,这将使升级更加顺利。

我坚持自定义某些操作的结果如何序列化。例如,我希望某些操作仅返回输出对象的一些属性,而其他操作可能会进行相当深度的序列化。在我当前的实现中,一个操作可以通过在 HttpContext 中设置适当的设置来添加一堆序列化覆盖。这些稍后会通过派生自 JsonResult 的类进行自定义序列化。添加自定义 JsonConverters 的主要用途是控制和减少序列化的键/值的数量,并根据操作改变要序列化的参数(某些操作应返回比其他操作更多的对象参数)。

在我当前的 MVC3 实现中 Controller 和控制 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 的,以单独(或每个 Controller )控制操作的序列化。因此,我希望 Json 序列化程序找到提供给调用的操作/ Controller 的相关属性,并相应地更改序列化。我不确定在哪里以及如何执行此操作。我应该从 JsonMediaTypeFormatter 继承并以某种方式在那里完成工作吗?我还有哪些其他选择?

最佳答案

我从未见过有人想以这种方式控制序列化。但是为了以最少的返工量实现您的目标,我会直接从您的方法返回所有这些信息:

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

然后我会创建一个可以处理这些对象的自定义 Formatter:

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
}

关于c# - 自定义调用 Action 的 ASP Web API Json 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11758152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com