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?
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?
Câu trả lời:
Tôi chỉ cần thêm các mục sau trong App_Start / WebApiConfig.cs
lớ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 XML
khi gửi text/xml
.
Nếu bạn cần phải có những phản ứng Content-Type
như application/json
hãy kiểm tra câu trả lời của Todd dưới đây .
NameSpace
đang sử dụng System.Net.Http.Headers
.
Content-Type
tiêu đề của phản hồi sẽ vẫn còn text/html
.
Nếu bạn làm điều này trong WebApiConfig
mặ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/xml
làm Accept
tiê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ó.
application/xml
có 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/xml
bạ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.
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/json
tiê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"));
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());
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.
using System.Net.Http.Formatting
vàusing Newtonsoft.Json
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.asax
thê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();
}
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 .
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"));
}
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 đề Accept
hoặc Content-Type
yê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
.
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.
network.http.accept.default
cấu hình thành text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7
.
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.
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.
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!
Đừ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.
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
Tôi đã sử dụng bộ lọc hành động toàn cầu để xóa Accept: application/xml
khi User-Agent
tiê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.
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/json
một số thứ khác:
Máy khách REST nâng cao
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 WebApiConfig
lớ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 ActionFilterAttribute
và á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ừ Attribute
trên trang trí hành động và chỉ sử dụng [JsonOutput]
thay vì [JsonOutputAttribute]
.
config.Formatters.Remove(config.Formatters.XmlFormatter);
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.
Đâ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-8
tiêu đề trong phản hồi.
Nó cho phép bạn giải quyết &$format=json
hoặc &$format=xml
kế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.
Bạn có thể sử dụng như dưới đây:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
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());
............................
}
}
Bạn chỉ cần thay đổi App_Start/WebApiConfig.cs
như 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}"
);
}
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.
Đã 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 someOtherCondition
có 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;
}
}
Đâ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.cs
trong Register
chứ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.
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.
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.
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à: