json - دورة - كتاب asp net mvc عربي




كيف يمكنني الحصول على واجهة برمجة تطبيقات ASP.NET Web لإرجاع JSON بدلاً من XML باستخدام Chrome؟ (20)

MVC4 سريع تلميح # 3 - إزالة XML منسق من ASP.Net Web API

في 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();
}

باستخدام واجهة برمجة تطبيقات الويب ASP.NET الأحدث ، أرى في Chrome XML - كيف يمكنني تغييره لطلب JSON حتى أتمكن من مشاهدته في المتصفح؟ أعتقد أنها مجرد جزء من رؤوس الطلبات ، هل يمكنني تصحيح ذلك؟


WebApiConfig هو المكان الذي يمكنك من خلاله تكوين ما إذا كنت تريد الإخراج في json أو xml. افتراضيا هو XML. في وظيفة التسجيل يمكننا استخدام HttpConfiguration Formatters لتنسيق الإخراج. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") يتطلب الحصول على الإخراج بتنسيق json.


أنا مندهش لرؤية العديد من الردود التي تتطلب الترميز لتغيير حالة استخدام واحدة (GET) في واجهة برمجة تطبيقات واحدة بدلاً من استخدام أداة مناسبة يجب تثبيتها مرة واحدة ويمكن استخدامها لأي واجهة برمجة تطبيقات (خاصة أو طرف ثالث) وجميع استخدم حالات.

لذا فإن الجواب الجيد هو:

  1. إذا كنت تريد فقط طلب json أو نوع محتوى آخر تثبيت Requestly أو أداة مشابهة وتعديل رأس Accept.
  2. إذا كنت ترغب في استخدام POST أيضًا وقمت باستخدام json منسق بشكل جيد ، xml ، إلخ. استخدم ملحق اختبار API مناسب مثل Postman أو ARC .

إذا قمت بذلك في WebApiConfig ، WebApiConfig على JSON افتراضيًا ، ولكنها ستظل تسمح لك بإرجاع XML إذا قمت بتمرير text/xml مثل الطلب Accept header

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 وبالتالي لم يكن لديك هذا الفصل للبدء به ، فراجع هذه الإجابة للحصول على تفاصيل حول كيفية دمجها.


إليك الطريقة الأسهل التي استخدمتها في تطبيقاتي. أضف ما يلي 3 أسطر من الكود في App_Start\\WebApiConfig.cs في وظيفة Register

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

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

ستقوم واجهة برمجة تطبيقات الويب Asp.net تلقائيًا بتسلسل الكائن العائدين إلى JSON ومع إضافة application/json في الرأس حتى يفهم المتصفح أو جهاز الاستقبال أنك تعرض نتيجة JSON.


استخدمت فلتر إجراءً عامًا لإزالة Accept: application/xml عندما يحتوي رأس User-Agent على "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();
    }
}

يبدو أنه يعمل.


خيار واحد سريع هو استخدام التخصص MediaTypeMapping. هذا مثال على استخدام QueryStringMapping في الحدث Application_Start:

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

الآن عندما يحتوي عنوان url على querystring؟ a = b في هذه الحالة ، سيتم عرض استجابة Json في المستعرض.


في Global.asax أنا أستخدم الرمز أدناه. My URI to get JSON is 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"));
}

لا تستخدم متصفحك لاختبار API الخاص بك.

بدلاً من ذلك ، حاول استخدام عميل HTTP الذي يسمح لك بتحديد طلبك ، مثل CURL ، أو حتى Fiddler.

تكمن المشكلة في هذه المشكلة في العميل ، وليس في واجهة برمجة التطبيقات. تتصرف واجهة برمجة تطبيقات الويب بشكل صحيح ، وفقًا لطلب المتصفح.


لقد مر بعض الوقت منذ طرح هذا السؤال (والإجابة عليه) ولكن هناك خيار آخر هو تجاوز رأس قبول على الخادم أثناء معالجة الطلب باستخدام MessageHandler على النحو التالي:

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;
    }
}

ما عليك سوى إضافة هذين السطرين من الشفرة على صف WebApiConfig

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 و AngularJS (حوالي 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();
    }

يجب أن يكون التيار ، حاولت ذلك وعملت.


من غير الواضح بالنسبة لي سبب وجود كل هذا التعقيد في الإجابة. بالتأكيد هناك الكثير من الطرق التي يمكنك القيام بها ، مع QueryStrings ، رؤوس وخيارات ... ولكن ما أعتقد أنه أفضل الممارسات بسيط. طلب عنوان URL عادي (مثال: http://yourstartup.com/api/cars ) وفي المقابل تحصل على JSON. يمكنك الحصول على JSON باستخدام رأس الرد المناسب:

Content-Type: application/json

في البحث عن إجابة على هذا السؤال نفسه ، وجدت هذا الخيط ، واضطررت إلى الاستمرار لأن هذه الإجابة المقبولة لا تعمل بالضبط. لقد وجدت إجابة أشعر أنها بسيطة للغاية بحيث لا تكون الأفضل:

اضبط منسق WebAPI الافتراضي

سأضيف نصيحتي هنا أيضًا.

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 ، أو ربما تم إنشاؤها في مكان آخر (بواسطة شخص آخر في مشروعي). Anways ، آمل أن يساعد هذا.


هنا هو حل مماثل ل jayson.centeno's والإجابات الأخرى ، ولكن باستخدام تمديد المضمنة من 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
 }

تم توجيه الحل بشكل أساسي لدعم تنسيق $ OData في الإصدارات المبكرة من WebApi ، ولكنه ينطبق أيضًا على تنفيذ غير OData ، ويعرض Content-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8 header في الاستجابة.

يسمح لك &$format=json أو &$format=xml إلى نهاية uri الخاص بك عند الاختبار باستخدام متصفح. لا يتداخل مع السلوك المتوقع الآخر عند استخدام عميل غير متصفح حيث يمكنك تعيين الرؤوس الخاصة بك.


وفقًا لأحدث إصدار من ASP.net WebApi 2 ،

ضمن WebApiConfig.cs ، سيعمل هذا

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

يجعل هذا الرمز 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"));

شكرا لكم جميعا!


يعمل استخدام RequestHeaderMapping بشكل أفضل ، لأنه يقوم أيضًا بتعيين Content-Type = application / json في عنوان الاستجابة ، والذي يسمح لـ Firefox (مع إضافة JSONView) بتنسيق الاستجابة كـ JSON.

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

أنا فقط إضافة ما يلي في فئة App_Start / WebApiConfig.cs في مشروع MVC Web API.

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

يضمن ذلك الحصول على json في معظم طلبات البحث ، ولكن يمكنك الحصول على xml عند إرسال text/xml .

إذا كنت بحاجة إلى الحصول على استجابة Content-Type application/json يرجى التحقق من إجابة Todd أدناه .

يستخدم System.Net.Http.Headers ؛


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






asp.net-web-api