Làm cách nào để buộc ASP.NET Web API luôn trả về JSON?


103

ASP.NET Web API thực hiện thương lượng nội dung theo mặc định - sẽ trả về XML hoặc JSON hoặc kiểu khác dựa trên Accepttiêu đề. Tôi không cần / muốn điều này, có cách nào (như thuộc tính hoặc thứ gì đó) để yêu cầu API Web luôn trả về JSON không?


Bạn có thể làm điều này loại bỏ tất cả và định dạng trừ json từGlobalConfiguration.Configuration.Formatters
Claudio Redi

Câu trả lời:


75

Chỉ hỗ trợ JSON trong API Web ASP.NET - CÁCH ĐÚNG

Thay thế IContentNegotiator bằng JsonContentNegotiator:

var jsonFormatter = new JsonMediaTypeFormatter();
//optional: set serializer settings here
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

Triển khai JsonContentNegotiator:

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _jsonFormatter;

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter) 
    {
        _jsonFormatter = formatter;    
    }

    public ContentNegotiationResult Negotiate(
            Type type, 
            HttpRequestMessage request, 
            IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(
            _jsonFormatter, 
            new MediaTypeHeaderValue("application/json"));
    }
}

4
Phần đầu tiên của mã cũng được cắt và dán ở đâu? Tôi không thấy đối tượng "config" trong Global.asax của mình. Biến đó đến từ đâu? bài báo cũng không giải thích.
BuddyJoe

3
Kiểm tra tĩnh public void Register (HttpConfiguration config) {...} phương pháp trong tập tin WebApiConfig.cs đã được gererated bởi VS2012 trên dự án sáng tạo
Dmitry Pavlov

Điều này có buộc JSON theo nghĩa là máy khách nhập AcceptXML sẽ nhận được JSON và sẽ không nhận được 406 không?
Luke Puplett,

1
Tôi có thể trả lời nhận xét / câu hỏi của riêng mình: nó trả về XML bất kể Accepttiêu đề.
Luke Puplett,

2
Điều này phá vỡ tích hợp swashbuckle của tôi và có vẻ như nó liên quan đến vấn đề này trên github ( github.com/domaindrivendev/Swashbuckle/issues/219 ). Tôi muốn sử dụng phương pháp này nhưng phương pháp sử dụng bên dưới GlobalConfiguration...Clear()thực sự hoạt động.
seangwright

167

Xóa tất cả các bộ định dạng và thêm lại bộ định dạng Json.

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

BIÊN TẬP

Tôi đã thêm nó vào Global.asax bên trong Application_Start().


và trong tệp nào .. ?? global.ascx .. ??
shashwat

Trong phương thức Application_Start () của bạn
Jafin

6
Filip W chỉ có cách tốt hơn bây giờ :), nhìn thấy nó ở đây strathweb.com/2013/06/...
Tiến Đỗ

7
@TienDo - liên kết đến blog của Filip?
Phill

10

Philip W đã có câu trả lời đúng nhưng để rõ ràng và có giải pháp hoạt động hoàn chỉnh, hãy chỉnh sửa tệp Global.asax.cs của bạn để trông giống như sau: (Lưu ý rằng tôi phải thêm tham chiếu System.Net.Http.Formatting vào tệp được tạo sẵn)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace BoomInteractive.TrainerCentral.Server {
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

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

            //Force JSON responses on all requests
            GlobalConfiguration.Configuration.Formatters.Clear();
            GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
        }
    }
}

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

Thao tác này sẽ xóa định dạng XML và do đó mặc định là định dạng JSON.


Hoàn thiện tất cả những gì cần thiết
tfa

4

Lấy cảm hứng từ câu trả lời xuất sắc của Dmitry Pavlov, tôi đã sửa đổi nó một chút để có thể bổ sung bất kỳ định dạng nào mà tôi muốn thực thi.

Tín dụng cho Dmitry.

/// <summary>
/// A ContentNegotiator implementation that does not negotiate. Inspired by the film Taken.
/// </summary>
internal sealed class LiamNeesonContentNegotiator : IContentNegotiator
{
    private readonly MediaTypeFormatter _formatter;
    private readonly string _mimeTypeId;

    public LiamNeesonContentNegotiator(MediaTypeFormatter formatter, string mimeTypeId)
    {
        if (formatter == null)
            throw new ArgumentNullException("formatter");

        if (String.IsNullOrWhiteSpace(mimeTypeId))
            throw new ArgumentException("Mime type identifier string is null or whitespace.");

        _formatter = formatter;
        _mimeTypeId = mimeTypeId.Trim();
    }

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue(_mimeTypeId));
    }
}

2

Nếu bạn chỉ muốn làm điều đó cho một phương thức, hãy khai báo phương thức của bạn là trả về HttpResponseMessagethay vì IEnumerable<Whatever>và thực hiện:

    public HttpResponseMessage GetAllWhatever()
    {
        return Request.CreateResponse(HttpStatusCode.OK, new List<Whatever>(), Configuration.Formatters.JsonFormatter);
    }

mã này là khó khăn cho thử nghiệm đơn vị nhưng điều đó cũng có thể xảy ra như thế này:

    sut = new WhateverController() { Configuration = new HttpConfiguration() };
    sut.Configuration.Formatters.Add(new Mock<JsonMediaTypeFormatter>().Object);
    sut.Request = new HttpRequestMessage();

Nếu bạn muốn một cái gì đó cho một phương pháp duy nhất tạo ra một msdn.microsoft.com/en-us/library/...
Elisabeth


0

Bạn có thể sử dụng trong WebApiConfig.cs:

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

0

cho những người sử dụng OWIN

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

trở thành (trong Startup.cs):

   public void Configuration(IAppBuilder app)
        {
            OwinConfiguration = new HttpConfiguration();
            ConfigureOAuth(app);

            OwinConfiguration.Formatters.Clear();
            OwinConfiguration.Formatters.Add(new DynamicJsonMediaTypeFormatter());

            [...]
        }
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.