簡體   English   中英

ASP.NET Web API中的內容協商

[英]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種選擇:

  1. 創建一個具有適當名稱的類,然后返回該對象而不是匿名類型。
  2. 或者,如果您想返回匿名實例,則應刪除XML格式化程序,因為XML格式化程序不支持匿名類型。

  3. MediaTypeFormatterBufferedMediaTypeFormatter繼承創建自己的格式化程序

您可以通過以下代碼進行操作:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM