[英]Content Negotiation in ASP.NET Web API
我正在將Web服務遷移到ASP.NET Web Api 2,幾乎遇到了第一道障礙。
我想做這個:
public class SomeController : ApiController
{
[Route("some\url")]
public object Get()
{
return { Message = "Hello" };
}
}
並能夠向服務請求“ application / json”或“ application / xml”(或者實際上是任何其他可能的格式,例如Message Pack),並獲得序列化的響應。 但似乎它僅適用於JSON。
我已經看過這篇文章,並且看過文檔 ,其中清楚地指出該框架無法(嚴重)處理將匿名類型序列化為XML,並且解決方案是不使用XML(嚴重)。
當我嘗試調用此方法並請求XML作為響應類型時,我得到
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
我不會刪除對希望使用XML的客戶的支持-但是我真的找不到解決方法-我該怎么辦?
編輯
我添加了這些:
System.Web.Http.GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
config.Formatters.Insert(0, new System.Net.Http.Formatting.XmlMediaTypeFormatter());
按照Dalorzo的回答,但這沒什么區別。
為了澄清起見,當我使用application/json
的accept報頭調用該服務時,該服務絕對正常,但是當我使用application/xml
的accept報頭對其進行調用時,則炸彈。
您有3種選擇:
或者,如果您想返回匿名實例,則應刪除XML格式化程序,因為XML格式化程序不支持匿名類型。
從MediaTypeFormatter或BufferedMediaTypeFormatter繼承創建自己的格式化程序
您可以通過以下代碼進行操作:
public HttpResponseMessage GetTestData()
{
var testdata = (from u in context.TestRepository.Get().ToList()
select
new Message
{
msgText = u.msgText
});
return ActionContext.Request.CreateResponse(HttpStatusCode.OK, testdata);
}
// This Code Is Used To Change Contents In Api
public HttpResponseMessage GetAllcarDetails( string formate)
{
CarModel ST = new CarModel();
CarModel ST1 = new CarModel();
List<CarModel> li = new List<CarModel>();
ST.CarName = "Maruti Waganor";
ST.CarPrice = 400000;
ST.CarModeles = "VXI";
ST.CarColor = "Brown";
ST1.CarName = "Maruti Swift";
ST1.CarPrice = 500000;
ST1.CarModeles = "VXI";
ST1.CarColor = "RED";
li.Add(ST);
li.Add(ST1);
// return li;
this.Request.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/xml"));
//For Json Use "application/json"
IContentNegotiator negotiator =
this.Configuration.Services.GetContentNegotiator();
ContentNegotiationResult result = negotiator.Negotiate(
typeof(List<CarModel>), this.Request, this.Configuration.Formatters);
if (result == null) {
var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
throw new HttpResponseException(response);
}
return new HttpResponseMessage() {
Content = new ObjectContent<List<CarModel>>(
li, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
)
};
}
請在Chrome上瀏覽您的API路由。 Chrome默認情況下以XML格式顯示輸出。 如果這沒有發生,則意味着您的服務正在使用媒體格式阻止XML格式。
在這種情況下,您應該搜索WebApiConfig。 如果沒有任何內容,請將此文件添加到您的項目中
using System.Net.Http.Formatting;
using System.Collections.Generic;
using System.Net.Http;
using System;
using System.Linq;
using System.Net.Http.Headers;
namespace ExampleApp.Infrastructure
{
public class CustomNegotiator : DefaultContentNegotiator
{
public override ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
{
if(request.Headers.UserAgent.Where(x=>x.Product!=null&& x.Product.Name.ToLower().Equals("chrome")).Count() > 0)
{
return new ContentNegotiationResult(new JsonMediaTypeFormatter(), new MediaTypeHeaderValue("application/xml"));
}
else
{
return base.Negotiate(type, request, formatters);
}
}
}
}
並在WebApiConfig.cs
中添加:
config.Services.Replace(typeof(IContentNegotiator), new CustomNegotiator());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.