Làm cách nào để có được API Web ASP.NET để trả về JSON thay vì XML bằng Chrome?


1220

Sử dụng API Web ASP.NET mới hơn , trong Chrome tôi đang thấy XML - làm cách nào tôi có thể thay đổi nó để yêu cầu JSON để tôi có thể xem nó trong trình duyệt? Tôi tin rằng nó chỉ là một phần của tiêu đề yêu cầu, tôi có đúng trong đó không?


8
Có một cuộc thảo luận ở đây để làm cho JSON chỉ trả về hành vi mặc định: github.com/aspnet/Mvc/issues/1765
Natan

Câu trả lời:


1738

Tôi chỉ cần thêm các mục sau trong App_Start / WebApiConfig.cslớp trong dự án API Web MVC của mình .

config.Formatters.JsonFormatter.SupportedMediaTypes
    .Add(new MediaTypeHeaderValue("text/html") );

Điều đó đảm bảo bạn nhận được JSON trên hầu hết các truy vấn, nhưng bạn có thể nhận được XMLkhi gửi text/xml.

Nếu bạn cần phải có những phản ứng Content-Typenhư application/jsonhãy kiểm tra câu trả lời của Todd dưới đây .

NameSpaceđang sử dụng System.Net.Http.Headers.


115
Đây là một câu trả lời đáng ngạc nhiên bị bỏ qua và mặc dù câu hỏi ban đầu không hoàn toàn rõ ràng, nhưng điều này trực tiếp làm cho JSON trở thành câu trả lời mặc định cho trình duyệt web (gửi Chấp nhận: text / html). Làm tốt lắm.
gregmac

16
+1 Câu trả lời xa và tốt nhất. Tôi tưởng tượng có rất nhiều người đã chọn loại bỏ hoàn toàn XML chỉ vì họ không thấy JSON trong trình duyệt.
Derek Hunziker

3
Tôi đã tìm thấy khi tôi làm điều này rằng dữ liệu được cung cấp bởi bên thứ ba với các thẻ ngắt HTML trong đó kết thúc với lợi nhuận vận chuyển. JSON sau đó không hợp lệ. Tốt hơn để sử dụng câu trả lời được chấp nhận nếu điều này ảnh hưởng đến bạn.
Stonetip

23
Lưu ý rằng Content-Typetiêu đề của phản hồi sẽ vẫn còn text/html.
Ông trùm

78
Điều này thật kinh khủng. Tiêu đề loại nội dung phản hồi phải là application / json. "Giải pháp" này làm cho nó thành văn bản / html.
tham gia

501

Nếu bạn làm điều này trong WebApiConfigmặc định, bạn sẽ nhận được JSON theo mặc định, nhưng nó vẫn cho phép bạn trả về XML nếu bạn chuyển qua text/xmllàm Accepttiêu đề yêu cầu

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
    }
}

Nếu bạn không sử dụng loại dự án MVC và do đó không có lớp này để bắt đầu, hãy xem câu trả lời này để biết chi tiết về cách kết hợp nó.


51
Chỉ cần lưu ý, hành vi ban đầu là chính xác. Các yêu cầu Chrome application/xmlcó mức độ ưu tiên là 0,9 và */*mức độ ưu tiên là 0,8. Bằng cách loại bỏ, application/xmlbạn loại bỏ khả năng API Web trả về XML nếu máy khách yêu cầu cụ thể. ví dụ: nếu bạn gửi "Chấp nhận: application / xml", bạn vẫn sẽ nhận được JSON.
porges

11
Là tôi, hay là câu đầu tiên không chính xác? Mã dường như loại bỏ hoàn toàn XML, không chỉ đơn giản là thay đổi mặc định.
NickG

6
@NickG: một giải pháp bị bỏ qua ở đây và IMHO là một lựa chọn tốt hơn nhiều (giữ ứng dụng / xml) là giải pháp được đề xuất bởi Felipe Leusin thấp hơn trên trang này. Sử dụng config.Formatters.XmlFormatter.SupportedMediaTypes.Add (new MediaTypeHeaderValue ("text / html"));
Cohen

1
Vậy, làm thế nào để chúng tôi làm điều đó thông qua cấu hình web để chúng tôi nhận được json theo mặc định và XML nếu được yêu cầu?
Kyle

4
@Felipse Câu trả lời của Leusin dưới đây thực sự ngắn hơn và hoạt động tốt hơn.
Ken Smith

314

Sử dụng RequestHeaderMapping thậm chí còn hoạt động tốt hơn, bởi vì nó cũng đặt Content-Type = application/jsontiêu đề phản hồi, cho phép Firefox (có bổ trợ JSONView) định dạng phản hồi dưới dạng JSON.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));

6
Đây là giải pháp tinh gọn và đơn giản nhất và Fiddler cũng phát hiện loại nội dung được trả về là josn.
Steve Johnson

4
Đẹp! Nơi nào bạn sẽ đề nghị đặt điều này trong mã?
Tim Abell

9
Nó sẽ xuất hiện trong WebApiConfig.cs
Animesh

9
Đã làm cho tôi. Tôi cần phải thêm một System.Net.Http.Formatted;
bbsimonbb

1
Liên kết để thuận tiện cho riêng tôi: Câu trả lời này chơi độc đáo với một bước thiết lập khác mà tôi thường thực hiện: stackoverflow.com/a/28337589/398630 .
BrainSlugs83

309

Tôi thích cách tiếp cận tốt nhất của Felipe Leusin - đảm bảo các trình duyệt có JSON mà không ảnh hưởng đến việc đàm phán nội dung từ các khách hàng thực sự muốn XML. Phần còn thiếu duy nhất đối với tôi là các tiêu đề phản hồi vẫn chứa kiểu nội dung: text / html. Tại sao đó là một vấn đề? Vì tôi sử dụng tiện ích mở rộng JSON Formatter Chrome , kiểm tra loại nội dung và tôi không nhận được định dạng đẹp mà tôi đã sử dụng. Tôi đã sửa lỗi đó bằng một trình định dạng tùy chỉnh đơn giản chấp nhận các yêu cầu văn bản / html và trả về các phản hồi của ứng dụng / json:

public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
    public BrowserJsonFormatter() {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        this.SerializerSettings.Formatting = Formatting.Indented;
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

Đăng ký như vậy:

config.Formatters.Add(new BrowserJsonFormatter());

24
Trong constructor thêm this.SerializerSettings.Formatting = Formatting.Indented;nếu bạn muốn nó được in đẹp mà không có phần mở rộng trình duyệt.
Alastair Maw

10
Tại sao bạn muốn nó in đẹp qua dây?
tham gia

8
Không phải câu trả lời của @ dmit77 tốt hơn (ngắn gọn hơn) câu trả lời này sao?
H.Wolper

8
@eddiegroves bạn không muốn in đẹp qua dây. Bạn muốn máy chủ gửi số lượng bit ít nhất qua dây (tức là: không có khoảng trắng). Sau đó, bạn muốn trình duyệt định dạng độc đáo, với addons và như vậy. Javascript cần phân tích cú pháp JSON thường xuyên, tại sao làm cho nó chậm hơn bằng cách giới thiệu định dạng không cần thiết
meffect 12/2/2015

13
Đối với những người làm việc đang tìm kiếm: đừng quên thêm using System.Net.Http.Formattingusing Newtonsoft.Json
Berriel

186

Mẹo nhanh về MVC4 # 3, Loại bỏ Trình định dạng XML khỏi API Web của ASP.Net

Trong Global.asaxthêm dòng:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

như vậy

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

9
Hoạt động - đẹp hơn nhiều khi có JSON là mặc định thay vì XML.
whitneyland

5
nhưng bạn vẫn có thể trả lại xml chứ?
Thomas Stock

99
Tôi đã thử nó, và bạn không thể. Vì vậy, điều này đang loại bỏ hỗ trợ XML .. Bạn sẽ được cảnh báo, những người google thân yêu
Thomas Stock

3
Nếu bạn xem câu trả lời của tôi dưới đây, điều này sẽ cho phép xml vẫn được trả về nếu bạn muốn nhưng cho phép trang web trả lời bằng JSON cho trình duyệt
Glenn Slaven

3
@GlennSlaven yeah câu trả lời của bạn phải là câu trả lời đúng.
radu florescu

114

Trong WebApiConfig.cs , thêm vào cuối chức năng Đăng ký :

// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);

Nguồn .


XmlFormatter có mới trong MVC4 không?
Glenn Slaven

1
Trong MVC5, điều này có thể được thực hiện bằng cách thay thế cấu hình bằng GlobalConfiguration.Configuration
Steven

4
Đối với một dự án phải chỉ hỗ trợ JSON và trong mọi trường hợp không được phép phát ra XML, đây là tùy chọn tốt nhất.
Luc C

1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem

3
Đó là khủng khiếp. - Điều này sẽ luôn trả về JSON bất kể là gì, ngay cả khi máy khách yêu cầu cụ thể XML trong tiêu đề Kiểu nội dung.
BrainSlugs83

94

Trong Global.asax tôi đang sử dụng mã dưới đây. URI của tôi để nhận JSON làhttp://www.digantakumar.com/api/values?json=true

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new  QueryStringMapping("json", "true", "application/json"));
}

2
Tuyệt vời Phương pháp của bạn mong đợi một tham số là gì? như localhost: 61044 / api / value / getdate? json = true, date = 2012-08-01
LT.Nolo

Những loại định dạng của dữ liệu web api trở lại theo mặc định. là json hay webapi? cảm ơn
Thomas

54

Có một cái nhìn về đàm phán nội dung trong WebAPI. Những bài viết này ( Phần 1 & Phần 2 ) tuyệt vời chi tiết và kỹ lưỡng các bài đăng trên blog giải thích cách thức hoạt động của nó.

Nói tóm lại, bạn đã đúng và chỉ cần đặt tiêu đề Accepthoặc Content-Typeyêu cầu. Do Hành động của bạn không được mã hóa để trả về một định dạng cụ thể, bạn có thể đặt Accept: application/json.


6
"vì vậy tôi có thể xem nó trong trình duyệt"
Spongman

1
@Spongman, vâng, bạn có thể. Nhưng sử dụng một tiện ích mở rộng như REST Client - hầu hết các trình duyệt đều có một tiện ích giống như vậy. Việc gõ url trực tiếp trong trình duyệt là 1. Quá giới hạn (không kiểm soát các tiêu đề, không thể đăng dữ liệu và v.v.); 2. Không chính xác - Trình duyệt không tiêu thụ api web như dự định sẽ được tiêu thụ - bạn không thể dựa vào nó để kiểm tra nó đúng cách. Vì vậy, một lần nữa, một tiện ích khách REST tốt sẽ khắc phục điều đó.
Ivaylo Slavov

45

Vì câu hỏi dành riêng cho Chrome, bạn có thể nhận tiện ích mở rộng Postman cho phép bạn đặt loại nội dung yêu cầu.

Người phát thơ


Trong Firefox, chỉ cần truy cập about: config, tìm kiếm accept.default và thay đổi nội dung của network.http.accept.defaultcấu hình thành text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.
Bjartur Thorlacius

Hoặc tốt hơn nữa, chỉ text/html,application/xhtml+xml;q=1.0,*/*;q=0.7để tránh các máy chủ có lỗi như Bitbucket vô tình phục vụ JSON trình duyệt của bạn thay cho HTML.
Bjartur Thorlacius

URL đã chết. Một cái mới là chrome.google.com/webstore/detail/postman/ .
Falcon Momot

35

Một tùy chọn nhanh là sử dụng chuyên môn MediaTypeMapping. Dưới đây là một ví dụ về việc sử dụng QueryStringMapping trong sự kiện Application_Start:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Bây giờ bất cứ khi nào url chứa chuỗi truy vấn? A = b trong trường hợp này, phản hồi Json sẽ được hiển thị trong trình duyệt.


2
Điều này rất hữu ích. Bạn cũng có thể sử dụng UriPathExtensionMapping thay vì QueryStringMapping nếu bạn muốn sử dụng path.to/item.json
nuzzolilo

32

Mã này làm cho json mặc định của tôi và cũng cho phép tôi sử dụng định dạng XML. Tôi sẽ chỉ nối thêm xml=true.

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

Cảm ơn mọi người!


1
Đây là câu trả lời linh hoạt nhất (và thực sự nên là cấu hình mặc định ngày nay). Để thêm vào câu trả lời này, JSON là mặc định, bao gồm từ trình duyệt. Để xem XML, hãy thêm chuỗi truy vấn :? Xml = true
raider33 30/03/2016

Đã thử một số chiến lược. Có một thử nghiệm đơn giản cho cả XML và JSON và điều này đã có hiệu quả
pat capozzi

23

Đừng sử dụng trình duyệt của bạn để kiểm tra API của bạn.

Thay vào đó, hãy thử sử dụng ứng dụng khách HTTP cho phép bạn chỉ định yêu cầu của mình, chẳng hạn như CURL hoặc thậm chí Fiddler.

Vấn đề với vấn đề này là ở máy khách, không phải trong API. API web hoạt động chính xác, theo yêu cầu của trình duyệt.


30
Tại sao không sử dụng trình duyệt? Nó là một công cụ rõ ràng cho nó.
Anders Lindén

4
Tôi nghĩ rằng vấn đề ở đây là chính xác và quan trọng - chúng ta không nên vượt quá một phần hoạt động của ứng dụng (cơ sở hạ tầng MVC WebAPI) nếu sự cố do máy khách gây ra. Trường hợp sử dụng thực sự cho một Api là được sử dụng đúng cách (bằng cách cung cấp các tiêu đề chính xác), đây là trách nhiệm của ứng dụng. Mặc dù vậy, tôi không đồng ý với việc loại bỏ hoàn toàn trình duyệt - để thử nghiệm, có rất nhiều công cụ cho hầu hết mọi trình duyệt (Phần mở rộng giống như ứng dụng khách bắt đầu).
Ivaylo Slavov

6
Đây có lẽ nên là một bình luận.
bonh

17

Hầu hết các câu trả lời trên có ý nghĩa hoàn hảo. Vì bạn đang thấy dữ liệu được định dạng theo định dạng XML, điều đó có nghĩa là định dạng XML được áp dụng, SO bạn có thể thấy định dạng JSON chỉ bằng cách xóa XMLFormatter khỏi tham số HttpConfiguration như

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );                
            config.Formatters.Remove(config.Formatters.XmlFormatter);                
            config.EnableSystemDiagnosticsTracing();
        }

vì JSON là định dạng mặc định


12

Tôi đã sử dụng bộ lọc hành động toàn cầu để xóa Accept: application/xmlkhi User-Agenttiêu đề chứa "Chrome":

internal class RemoveXmlForGoogleChromeFilter : IActionFilter
{
    public bool AllowMultiple
    {
        get { return false; }
    }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        var userAgent = actionContext.Request.Headers.UserAgent.ToString();
        if (userAgent.Contains("Chrome"))
        {
            var acceptHeaders = actionContext.Request.Headers.Accept;
            var header =
                acceptHeaders.SingleOrDefault(
                    x => x.MediaType.Contains("application/xml"));
            acceptHeaders.Remove(header);
        }

        return await continuation();
    }
}

Có vẻ để làm việc.


11

Tôi thấy ứng dụng Chrome "Advanced REST Client" hoạt động tuyệt vời với các dịch vụ REST. Bạn có thể đặt Kiểu nội dung thành application/jsonmột số thứ khác: Máy khách REST nâng cao


10

Việc trả lại định dạng đúng được thực hiện bởi trình định dạng loại phương tiện. Như những người khác đã đề cập, bạn có thể làm điều này trong WebApiConfiglớp:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...

        // Configure Web API to return JSON
        config.Formatters.JsonFormatter
        .SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));

        ...
    }
}

Để biết thêm, hãy kiểm tra:

Trong trường hợp các hành động của bạn đang trả về XML (theo trường hợp theo mặc định) và bạn chỉ cần một phương thức cụ thể để trả về JSON, thì bạn có thể sử dụng một ActionFilterAttributevà áp dụng nó cho hành động cụ thể đó.

Thuộc tính bộ lọc:

public class JsonOutputAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
        var value = content.Value;
        Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0];

        var httpResponseMsg = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            RequestMessage = actionExecutedContext.Request,
            Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null)
        };

        actionExecutedContext.Response = httpResponseMsg;
        base.OnActionExecuted(actionExecutedContext);
    }
}

Áp dụng cho hành động:

[JsonOutput]
public IEnumerable<Person> GetPersons()
{
    return _repository.AllPersons(); // the returned output will be in JSON
}

Lưu ý rằng bạn có thể bỏ qua từ Attributetrên trang trí hành động và chỉ sử dụng [JsonOutput]thay vì [JsonOutputAttribute].


7
        config.Formatters.Remove(config.Formatters.XmlFormatter);

3
Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời. Vui lòng đọc stackoverflow.com/help/how-to-answer
SR

6

theo phiên bản mới nhất của ASP.net WebApi 2,

dưới WebApiConfig.cs, điều này sẽ làm việc

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);

6

Tôi không rõ tại sao có tất cả sự phức tạp này trong câu trả lời. Chắc chắn có rất nhiều cách bạn có thể làm điều này, với QueryStrings, tiêu đề và tùy chọn ... nhưng điều tôi tin là cách thực hành tốt nhất là đơn giản. Bạn yêu cầu một URL đơn giản (ví dụ http://yourstartup.com/api/cars:) và đổi lại bạn nhận được JSON. Bạn nhận được JSON với tiêu đề phản hồi thích hợp:

Content-Type: application/json

Khi tìm kiếm một câu trả lời cho câu hỏi tương tự này, tôi đã tìm thấy chủ đề này và phải tiếp tục vì câu trả lời được chấp nhận này không hoạt động chính xác. Tôi đã tìm thấy một câu trả lời mà tôi cảm thấy quá đơn giản để không phải là câu trả lời hay nhất:

Đặt trình định dạng WebAPI mặc định

Tôi sẽ thêm mẹo của tôi ở đây là tốt.

WebApiConfig.cs

namespace com.yourstartup
{
  using ...;
  using System.Net.Http.Formatting;
  ...
  config.Formatters.Clear(); //because there are defaults of XML..
  config.Formatters.Add(new JsonMediaTypeFormatter());
}

Tôi có một câu hỏi về mặc định (ít nhất là những cái tôi đang thấy) đến từ đâu. Chúng có mặc định .NET hay có thể được tạo ở một nơi khác (bởi người khác trong dự án của tôi). Anways, hy vọng điều này sẽ giúp.


5

Đây là một giải pháp tương tự như câu trả lời của jayson.centeno và các câu trả lời khác, nhưng sử dụng tiện ích mở rộng tích hợp từ System.Net.Http.Formatting.

public static void Register(HttpConfiguration config)
{
    // add support for the 'format' query param
    // cref: http://blogs.msdn.com/b/hongyes/archive/2012/09/02/support-format-in-asp-net-web-api.aspx
    config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
    config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");

    // ... additional configuration
 }

Giải pháp chủ yếu hướng đến việc hỗ trợ định dạng $ cho OData trong các bản phát hành đầu tiên của WebApi, nhưng nó cũng áp dụng cho việc triển khai không phải OData và trả về Content-Type: application/json; charset=utf-8tiêu đề trong phản hồi.

Nó cho phép bạn giải quyết &$format=jsonhoặc &$format=xmlkết thúc uri của bạn khi thử nghiệm với trình duyệt. Nó không can thiệp vào hành vi dự kiến ​​khác khi sử dụng máy khách không có trình duyệt nơi bạn có thể đặt tiêu đề của riêng mình.


5

Bạn có thể sử dụng như dưới đây:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

Nếu bạn đang tạo một ứng dụng WebAPI chỉ để truyền các thông báo JSON, hãy xem xét câu trả lời này.
allen1

4

Chỉ cần thêm hai dòng mã đó vào lớp WebApiConfig của bạn

public static class WebApiConfig
{
     public static void Register(HttpConfiguration config)
     {
          //add this two line 
          config.Formatters.Clear();
          config.Formatters.Add(new JsonMediaTypeFormatter());


          ............................
      }
}

3

Bạn chỉ cần thay đổi App_Start/WebApiConfig.csnhư thế này:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();
        //Below formatter is used for returning the Json result.
        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        //Default route
        config.Routes.MapHttpRoute(
           name: "ApiControllerOnly",
           routeTemplate: "api/{controller}"
       );
    }

Loại bỏ một định dạng nói chung không phải là một ý tưởng tốt, bạn đang loại bỏ chức năng.
naspinski 8/2/2016

Trên thực tế trong trường hợp này, nó hoạt động tốt với tôi, cũng có nhiều người khác đề xuất một cách như thế này. Tôi đã học được nó từ cuốn sách myview.rahulnivi.net/building-spa-angular-mvc-5 !
vaheed

2

Từ MSDN Xây dựng ứng dụng một trang với ASP.NET và AngularJS (khoảng 41 phút).

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // ... possible routing etc.

        // Setup to return json and camelcase it!
        var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
        formatter.SerializerSettings.ContractResolver =
            new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
    }

Nó nên là hiện tại, tôi đã thử nó và nó hoạt động.


2

Đã một thời gian trôi qua kể từ khi câu hỏi này được hỏi (và trả lời) nhưng một tùy chọn khác là ghi đè tiêu đề Chấp nhận trên máy chủ trong khi xử lý yêu cầu bằng MessageHandler như dưới đây:

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

Trường hợp someOtherConditioncó thể là bất cứ thứ gì, kể cả loại trình duyệt, v.v. Điều này sẽ dành cho các trường hợp có điều kiện mà đôi khi chúng tôi chỉ muốn ghi đè lên cuộc đàm phán nội dung mặc định. Mặt khác, theo các câu trả lời khác, bạn chỉ cần loại bỏ một định dạng không cần thiết khỏi cấu hình.

Tất nhiên bạn sẽ cần phải đăng ký nó. Bạn có thể làm điều này trên toàn cầu:

  public static void Register(HttpConfiguration config) {
      config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
  }

hoặc trên một tuyến đường theo cơ sở tuyến đường:

config.Routes.MapHttpRoute(
   name: "SpecialContentRoute",
   routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
   defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
   constraints: null,
   handler: new ForceableContentTypeDelegationHandler()
);

Và vì đây là một trình xử lý tin nhắn, nó sẽ chạy trên cả hai yêu cầu và kết thúc phản hồi của đường ống giống như một HttpModule. Vì vậy, bạn có thể dễ dàng thừa nhận ghi đè bằng tiêu đề tùy chỉnh:

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var wasForced = false;
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
            wasForced = true;
        }

        var response =  await base.SendAsync(request, cancellationToken);
        if (wasForced){
          response.Headers.Add("X-ForcedContent", "We overrode your content prefs, sorry");
        }
        return response;
    }
}

2

Đây là cách dễ nhất mà tôi đã sử dụng trong các ứng dụng của mình. Thêm vào dưới 3 dòng mã App_Start\\WebApiConfig.cstrong Registerchức năng

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

API web Asp.net sẽ tự động tuần tự hóa đối tượng trả về của bạn thành JSON và như application/jsonđược thêm vào trong tiêu đề để trình duyệt hoặc người nhận sẽ hiểu rằng bạn đang trả về kết quả JSON.


1

WebApiConfig là nơi bạn có thể định cấu hình cho dù bạn muốn xuất ra trong json hay xml. theo mặc định nó là xml. trong chức năng đăng ký, chúng ta có thể sử dụng Trình định dạng httpConfiguration để định dạng đầu ra. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") được yêu cầu để có được đầu ra ở định dạng json. nhập mô tả hình ảnh ở đây


1

Sử dụng câu trả lời của Felipe Leusin trong nhiều năm, sau một bản cập nhật gần đây của các thư viện cốt lõi và của Json.Net, tôi đã gặp phải một System.MissingMethodException: SupportMediaTypes . Giải pháp trong trường hợp của tôi, hy vọng hữu ích cho những người khác gặp phải ngoại lệ bất ngờ tương tự, là cài đặt System.Net.Http. NuGet rõ ràng loại bỏ nó trong một số trường hợp. Sau khi cài đặt thủ công, vấn đề đã được giải quyết.


-3

Tôi rất ngạc nhiên khi thấy rất nhiều câu trả lời yêu cầu mã hóa để thay đổi một trường hợp sử dụng (GET) trong một API thay vì sử dụng một công cụ thích hợp phải cài đặt một lần và có thể được sử dụng cho bất kỳ API nào (của riêng hoặc bên thứ 3) và tất cả trường hợp sử dụng.

Vì vậy, câu trả lời tốt là:

  1. Nếu bạn chỉ muốn yêu cầu json hoặc loại nội dung khác cài đặt Requestly hoặc một công cụ tương tự và sửa đổi tiêu đề Chấp nhận.
  2. Nếu bạn cũng muốn sử dụng POST và có định dạng độc đáo json, xml, v.v., hãy sử dụng tiện ích mở rộng kiểm tra API thích hợp như Postman hoặc ARC .

Một số thích làm việc mà không cần thêm sự phình to dưới dạng các công cụ và thư viện bổ sung.
tno2007

Vẫn chỉ sai khi thay đổi API vì ai đó đang sử dụng công cụ sai cho công việc. Trình duyệt web không được thiết kế để kiểm tra API, thậm chí không xem đầu ra của API mà để xem tài liệu. Thậm chí còn tệ hơn nếu ai đó nghĩ rằng một công cụ kiểm tra API đang phình to thay vì một phần của bộ công cụ bắt buộc đối với bất kỳ nhà phát triển API nào và thành thật tôi cũng sẽ thêm các nhà phát triển giao diện người dùng vì họ cũng cần phải tương tác và thử nghiệm API. Điều đó có lẽ vẫn chưa đủ vì trình duyệt không có addins không cho phép đặt tiêu đề, đăng lên API hoặc thậm chí kiểm tra các tiêu đề phản hồi.
dùng3285954

Tôi hiểu những gì bạn nói và bạn không sai. Nhưng chỉ ngoài chủ đề, lý do tại sao bạn đang bị bỏ phiếu là giai điệu mà bạn trả lời câu hỏi. Bạn có vẻ rất hiếu chiến và tình cờ phát hiện ra rằng nhà phát triển nghĩ rằng họ biết tất cả mọi thứ và điều đó rất khó chịu. Tôi chắc chắn bạn là một nhà phát triển tuyệt vời, đánh giá bằng phản hồi của bạn. Nhưng, bạn phải học, đặc biệt là trong môi trường QA chuyên nghiệp như thế này, để giải quyết và thuyết phục mọi người theo cách thân thiện và nhân văn hơn. Có lẽ, trước tiên hãy đưa ra câu trả lời họ muốn, sau đó giải thích một cách tốt hơn và thúc đẩy lý do tại sao nó tốt hơn.
tno2007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.