![](/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.