新しい ASP.NET Web APIを使用する 、 Chrome XMLを見ている - request _ json _ に変更するにはどうすればよいですか。ブラウザ?私はそれがリクエストヘッダの一部に過ぎないと信じています、それで正しいですか?
MVC Web APIプロジェクトのApp_Start / WebApiConfig.cs
クラスに次のコードを追加しただけです。
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
これでほとんどのクエリで確実にjsonを取得できますが、text/xml
を送信するとxml
を取得できます。
あなたがContent-Type
としての応答application/json
を持つ必要があるならば、 以下をチェックしてください - Toddの答え 。
NameSpace
はSystem.Net.Http.Headers
を使用しています。
WebApiConfig
でこれを行うと、デフォルトでJSONが得られますが、request Accept
ヘッダーとしてtext/xml
を渡すと、XMLを返すことができます。
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);
}
}
MVCプロジェクトタイプを使用していないため、最初にこのクラスがなかった場合は、 この回答を参照してください を組み込む方法の詳細については/ /を参照してください。
私は好きです Felipe Leusinのアプローチ 最高 - 実際にXMLを望んでいるクライアントからのコンテンツネゴシエーションを妥協することなくブラウザがJSONを取得するようにします。私にとって唯一欠けている部分は、レスポンスヘッダがまだcontent-type:text/htmlを含んでいるということでした。なぜそれが問題だったのでしょうか。私は、コンテンツタイプを検査する JSON Formatter Chrome拡張機能 を使用しているので、私が慣れ親しんでいるようなきれいなフォーマットは得られません。 text/htmlリクエストを受け付け、application/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");
}
}
以下のように登録してください。
config.Formatters.Add(new BrowserJsonFormatter());
RequestHeaderMappingを使用すると、レスポンスヘッダーにContent-Type = application/json
も設定されるため、Firefoxの(JSONViewアドオンを使用)レスポンスをJSONとしてフォーマットできるため、RequestHeaderMappingの使用がさらに効果的です。
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
"text/html",
StringComparison.InvariantCultureIgnoreCase,
true,
"application/json"));
MVC4クイックヒント#3 - ASP.Net Web APIからのXMLフォーマッターの削除
Global.asax
に次の行を追加します。
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
そのようです:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}
WebApiConfig.cs で、 Register 関数の最後に追加します。
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
ソース 。
Global.asax 私は以下のコードを使っています。 JSONを取得するための私のURIは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"));
}
質問はChrome固有のものであるため、リクエストのコンテンツタイプを設定できる Postman拡張子 を取得できます。
手っ取り早い方法の1つは、MediaTypeMapping特殊化を使用することです。以下は、Application_StartイベントでQueryStringMappingを使用する例です。
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
この場合、URLにクエリ文字列?a = bが含まれるたびに、Jsonの応答がブラウザに表示されます。
このコードはjsonを私のデフォルトとし、私にもXMLフォーマットを使用することを可能にします。 xml=true
を追加します。
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
みんな、ありがとう!
APIをテストするためにブラウザを使用しないでください。
代わりに、CURLやFiddlerなど、リクエストを指定できるHTTPクライアントを使用してください。
この問題の問題は、APIではなくクライアントにあります。 Web APIは、ブラウザの要求に従って正しく動作します。
上記の答えのほとんどは完全に理にかなっています。データがXMLフォーマットでフォーマットされているのを見ているので、それはXMLフォーマッターが適用されていることを意味します。つまり、HttpConfigurationパラメーターからXMLFormatterを削除するだけでJSONフォーマットを見ることができます。
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();
}
jSONがデフォルトのフォーマットなので
Accept: application/xml
ヘッダーに "Chrome"が含まれている場合は、グローバルアクションフィルターを使用してUser-Agent
を削除しました。
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();
}
}
動作しているようです。
私はChromeアプリ "Advanced REST Client"がRESTサービスと連携するのに優れていることを見つけました。 Content-Typeをapplication/json
に設定することができます。 Advanced REST client
正しい形式を返すことは、メディアタイプフォーマッタによって行われます。他の人が言ったように、あなたはWebApiConfig
クラスでこれをすることができます:
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"));
...
}
}
詳しくは、
アクションがXMLを返す場合(デフォルト)、JSONを返すための特定のメソッドだけが必要な場合は、ActionFilterAttribute
を使用してその特定のアクションに適用できます。
フィルター属性:
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);
}
}
行動に適用する:
[JsonOutput]
public IEnumerable<Person> GetPersons()
{
return _repository.AllPersons(); // the returned output will be in JSON
}
アクションの装飾でWordのAttribute
を省略して、[JsonOutput]
の代わりに[JsonOutputAttribute]
だけを使用できることに注意してください。
答えにこのような複雑さのすべてがあるのはなぜかは私には分かりません。 QueryStrings、ヘッダー、およびオプションを使って、これを実行できる方法はたくさんあります。ただし、ベストプラクティスと考えるのは簡単です。プレーンなURL(例:http://yourstartup.com/api/cars
)をリクエストすると、JSONが返されます。適切なレスポンスヘッダを付けてJSONを取得します。
Content-Type: application/json
これとまったく同じ質問に対する答えを探していると、私はこのスレッドを見つけました。そして、この受け入れられた答えは正確には機能しないので、続けなければなりませんでした。私は答えを見つけましたが、それは単純すぎて最高の答えではないと感じました。
ここに私のヒントを追加します。
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());
}
私はデフォルト(少なくとも私が見ているもの)がどこから来たのかという疑問を抱いています。それらは.NETのデフォルトですか、それとも他の場所で(私のプロジェクトの他の誰かによって)作成されたのでしょうか。さて、これが役立つことを願っています。
config.Formatters.Remove(config.Formatters.XmlFormatter);
aSP.net WebApi 2の最新バージョンによれば、
WebApiConfig.cs
の下では、これはうまくいくでしょう
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
これは jayson.centenoの や他の答えに似た解決策ですが、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
}
このソリューションは、WebApiの初期リリースでODataの$フォーマットをサポートすることを主な目的としていましたが、OData以外の実装にも適用され、応答にContent-Type: application/json; charset=utf-8
ヘッダーを返します。
ブラウザでテストするときに、&$format=json
または&$format=xml
をあなたのURIの最後まで付けることができます。独自のヘッダを設定できるブラウザ以外のクライアントを使用している場合は、他の予想される動作を妨げることはありません。
あなたは以下のように使うことができます:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
WebApiConfig クラスにこれらの2行のコードを追加するだけです。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
App_Start/WebApiConfig.cs
を次のように変更するだけです。
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}"
);
}
_ msdn _ ASP.NETとAngular JSを使用した単一ページアプリケーションの構築 (約41分)。
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();
}
それは最新であるべきです、私はそれを試みました、そして、それは働きました。
この質問が行われてから回答が得られてからしばらく時間が経っていますが、次のようにMessageHandlerを使用してリクエスト処理中にサーバーのAcceptヘッダーをオーバーライドすることもできます。
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);
}
}
someOtherCondition
はブラウザの種類などを含む何でも構いません。これは、デフォルトのコンテンツネゴシエーションをオーバーライドしたい場合があるという条件付きの場合のためのものです。そうでなければ他の答えに従って、あなたは単に設定から不要なフォーマッタを削除するでしょう。
もちろん登録する必要があります。グローバルにこれを行うことができます。
public static void Register(HttpConfiguration config) {
config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
}
またはルートごとのルートで:
config.Routes.MapHttpRoute(
name: "SpecialContentRoute",
routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
constraints: null,
handler: new ForceableContentTypeDelegationHandler()
);
これはメッセージハンドラなので、パイプラインの要求側と応答側の両方でHttpModule
のように実行されます。そのため、カスタムヘッダーを使用して簡単に上書きを確認できます。
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;
}
}
これが私のアプリケーションで使用した最も簡単な方法です。以下の3行のコードをRegister
関数のApp_Start\\WebApiConfig.cs
に追加
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Asp.net Web APIは自動的に戻りオブジェクトをJSONにシリアル化し、application/json
がヘッダーに追加されるので、ブラウザまたは受信側はJSON結果を返すことを認識します。
Felipe Leusin の答えを使って何年もの間、最近コアライブラリとJson.Netを更新した後、私はSystem.MissingMethodException
:SupportedMediaTypesに出会いました。私の場合の解決策は、同じ予想外の例外を経験している他の人たちに役立つと思いますが、System.Net.Http
をインストールすることです。 NuGetは明らかに状況によってはそれを削除します。手動インストールの後、問題は解決しました。