![](/img/trans.png)
[英]ASP.NET Web API XmlFormatter does not work, falls back to JsonFormatter
[英]Change JsonFormatter for a single request in ASP.NET Web API
我有一个如下定义的动作过滤器,在我的Web API项目中全局注册:
public class ResultCasingFilter : IActionFilter
{
private static JsonMediaTypeFormatter _pascalCasingFormatter;
private static JsonMediaTypeFormatter _camelCasingFormatter;
// Constructor that initializes formatters left out for brevity
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
actionContext.RequestContext.Configuration.Formatters.Clear();
actionContext.RequestContext.Configuration.Formatters.Add(
ResponseShouldBePascalCased(actionContext)
? _pascalCasingFormatter
: _camelCasingFormatter);
return continuation();
}
private static bool ResponseShouldBePascalCased(HttpActionContext actionContext)
{
return actionContext.ActionDescriptor
.GetCustomAttributes<PascalCasedResultAttribute>().Any();
}
public bool AllowMultiple { get { return false; } }
}
这很有效,但我似乎在请求之间受到干扰; 如果我一次向一个具有PascalCasedResultAttribute
但没有一个的动作方法发出一个请求,一切都按预期工作 - 但如果我发出两个非常接近彼此,两者有时最终都会使用相同的大小写。
我将此行为解释为对actionContext.RequestContext.Configuration.Formatters
的更改确实更改了整个应用程序的配置,而不仅仅是当前请求,有时请求重叠。 基本上,我的解决方案基于以下一系列事件:
请注意,如果第二步和第三步更改顺序,则会更改行为。 我想要的是相当的
我(或框架)可以在不改变行为的情况下切换2和3的顺序。
我怎样才能做到最好?
问题是你正在改变一个全局变量,它在排序时显然不一致。
您可以做的是在操作中手动序列化,并根据需要返回字符串。
然后,您可以提供一个标志来选择在您的请求中使用哪个序列化程序,或者使用cookie来记住客户的选择。
我最终做了以下事情:
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
// Let the action method execute, resulting in a serialized response
var responseMessage = await continuation();
if (responseMessage.Content is ObjectContent)
{
// Get the message content in its unserialized form, and choose formatter
var content = responseMessage.Content as ObjectContent;
var formatter = ResponseShouldBePascalCased(actionContext)
? _pascalCasingFormatter
: _camelCasingFormatter;
// Re-serialize content, with the correctly chosen formatter
responseMessage.Content = new ObjectContent(content.ObjectType, content.Value,
formatter);
}
// Return the (possibly) re-serialized message
return responseMessage;
}
在我得到这个解决方案之前,我跳过的主要障碍是意识到我可以await continuation()
让action方法执行,然后使用响应。
这种方法仍有缺点,如果客户端要求例如XML,它仍将获得JSON,因为我手动选择序列化程序而不查看Accepts
标头。 在我的用例中,我完全没问题,因为我们只是使用JSON,但是如果它对你很重要,那么你需要更复杂的东西代替我选择格式化器的三元语句。 (如果有一种简单的方法只针对已经序列化为给定格式的内容,我很乐意了解它!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.