json - मैं क्रोम का उपयोग कर एक्सएमएल के बजाय जेएसओएन वापस करने के लिए एएसपी.नेट वेब एपीआई कैसे प्राप्त करूं?



google-chrome asp.net-web-api (25)

क्रोम में नए एएसपी.नेट वेब एपीआई का उपयोग करके, मैं एक्सएमएल देख रहा हूं - मैं JSON का अनुरोध करने के लिए इसे कैसे बदल सकता हूं ताकि मैं इसे ब्राउज़र में देख सकूं ? मुझे विश्वास है कि यह अनुरोध हेडर का हिस्सा है, क्या मैं उसमें सही हूं?


Answers

मैं बहुत सारे उत्तरों को देखने के लिए आश्चर्यचकित हूं कि एक एपीआई में एक ही प्रयोग केस (जीईटी) को एक उचित उपकरण का उपयोग करने के बजाय कोडिंग की आवश्यकता होती है जिसे एक बार इंस्टॉल किया जाना चाहिए और किसी भी एपीआई (स्वयं या तृतीय पक्ष) के लिए इस्तेमाल किया जा सकता है और सभी बक्सों का इस्तेमाल करें।

तो अच्छा जवाब है:

  1. यदि आप केवल Requestly या अन्य सामग्री प्रकार का अनुरोध करना चाहते हैं तो अनुरोध करें या एक समान टूल इंस्टॉल करें और स्वीकृति हेडर को संशोधित करें।
  2. यदि आप POST का भी उपयोग करना चाहते हैं और अच्छी तरह से स्वरूपित जेसन, एक्सएमएल, आदि Postman या ARC जैसे उचित एपीआई परीक्षण एक्सटेंशन का उपयोग करना चाहते हैं।

यहां jayson.centeno's और अन्य उत्तरों 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
 }

समाधान मुख्य रूप से वेबएपी की शुरुआती रिलीज में ओडाटा के लिए $ प्रारूप का समर्थन करने के लिए तैयार किया गया था, लेकिन यह गैर-ओडाटा कार्यान्वयन पर भी लागू होता है, और Content-Type: application/json; charset=utf-8 जेसन लौटाता है Content-Type: application/json; charset=utf-8 प्रतिक्रिया में Content-Type: application/json; charset=utf-8 शीर्षलेख।

यह आपको ब्राउजर के साथ परीक्षण करते समय अपने यूरी के अंत तक &$format=json या &$format=xml करने की अनुमति देता है। गैर-ब्राउज़र क्लाइंट का उपयोग करते समय यह अन्य अपेक्षित व्यवहार में हस्तक्षेप नहीं करता है जहां आप अपने हेडर सेट कर सकते हैं।


कोर लाइब्रेरीज़ और जेसननेट के हालिया अपडेट के बाद, वर्षों के लिए फ़ेलिप लीसिन के उत्तर का उपयोग करके, मैं एक सिस्टम में भाग गया। MissingMethodException: समर्थित मीडिया टाइप्स। मेरे मामले में समाधान, आशाहीन रूप से एक ही अप्रत्याशित अपवाद का सामना करने वाले अन्य लोगों के लिए सहायक है, System.Net.Http को स्थापित करना है। NuGet स्पष्ट रूप से कुछ परिस्थितियों में इसे हटा देता है। मैन्युअल स्थापना के बाद, समस्या हल हो गई थी।


WebApiConfig वह जगह है जहां आप कॉन्फ़िगर कर सकते हैं कि आप जेसन या एक्सएमएल में आउटपुट करना चाहते हैं या नहीं। डिफ़ॉल्ट रूप से यह एक्सएमएल है। रजिस्टर फ़ंक्शन में हम आउटपुट प्रारूपित करने के लिए एचटीपी कॉन्फ़िगरेशन फॉर्मेटर्स का उपयोग कर सकते हैं। System.Net.Http.Headers => MediaTypeHeaderValue ("टेक्स्ट / एचटीएमएल") को जेसन प्रारूप में आउटपुट प्राप्त करने की आवश्यकता है।


बस अपनी WebApiConfig कक्षा पर कोड की उन दो पंक्तियों को जोड़ें

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


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

आप नीचे के रूप में उपयोग कर सकते हैं:

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

सही प्रारूप को वापस करना मीडिया-प्रकार फॉर्मेटर द्वारा किया जाता है। जैसा कि अन्य ने उल्लेख किया है, आप इसे 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"));

        ...
    }
}

अधिक के लिए, जांचें:

यदि आपके कार्य एक्सएमएल लौटा रहे हैं (जो डिफ़ॉल्ट रूप से मामला है) और आपको जेएसओएन वापस करने के लिए केवल एक विशिष्ट विधि की आवश्यकता है, तो आप एक 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
}

ध्यान दें कि आप क्रिया सजावट पर Attribute शब्द को छोड़ सकते हैं और [JsonOutput] बजाय बस [JsonOutput] उपयोग कर सकते हैं।


यदि आप WebApiConfig में ऐसा करते हैं तो आपको डिफ़ॉल्ट रूप से JSON मिल जाएगा, लेकिन यह आपको एक्सएमएल वापस करने की अनुमति देगा यदि आप text/xml रूप में text/xml पास Accept हेडर Accept

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

यदि आप एमवीसी प्रोजेक्ट प्रकार का उपयोग नहीं कर रहे हैं और इसलिए इस कक्षा को शुरू करने के लिए नहीं मिला है, तो इस जवाब को इसके बारे में विवरण के लिए देखें।


MediaTypeMapping विशेषज्ञता का उपयोग करने का एक त्वरित विकल्प है। Application_Start ईवेंट में QueryStringMapping का उपयोग करने का एक उदाहरण यहां दिया गया है:

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

अब जब भी यूआरएल में क्वेरीस्ट्रिंग होता है? ए = बी इस मामले में, जेसन प्रतिक्रिया ब्राउज़र में दिखाई जाएगी।


मेरे अनुप्रयोगों में मैंने सबसे आसान तरीका यहां उपयोग किया है। Register फ़ंक्शन में App_Start\\WebApiConfig.cs में कोड की 3 पंक्तियों के नीचे दिए गए जोड़ें

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

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

एएसपीनेट वेब एपीआई स्वचालित रूप से जेएसओएन पर आपकी रिटर्निंग ऑब्जेक्ट को क्रमबद्ध कर देगा और जैसे ही हेडर में application/json जोड़ा जाएगा, ब्राउज़र या रिसीवर समझ जाएगा कि आप जेएसओएन परिणाम लौट रहे हैं।


मैंने क्रोम ऐप "उन्नत रीस्ट क्लाइंट" आरईएसटी सेवाओं के साथ काम करने के लिए उत्कृष्ट पाया। आप अन्य चीजों के साथ सामग्री-प्रकार application/json सेट कर सकते हैं: उन्नत आरईएसटी क्लाइंट


मैं बस अपने एमवीसी वेब एपीआई प्रोजेक्ट में App_Start / WebApiConfig.cs क्लास में निम्नलिखित App_Start / WebApiConfig.cs हूं।

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

यह सुनिश्चित करता है कि आप अधिकांश प्रश्नों पर जेसन प्राप्त करें, लेकिन जब आप text/xml भेजते हैं तो आप xml प्राप्त कर सकते हैं।

यदि आपको application/json रूप में प्रतिक्रिया Content-Type की आवश्यकता है तो कृपया नीचे टोड का जवाब देखें ।

NameSpace System.Net.Http.Headers का उपयोग कर रहा है;


एएसपीनेट वेबएपी 2 के नवीनतम संस्करण के अनुसार,

WebApiConfig.cs तहत, यह काम करेगा

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

आप बस इस तरह 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}"
       );
    }

मैंने Accept: application/xml करने के लिए एक वैश्विक क्रिया फ़िल्टर का उपयोग किया Accept: application/xml जब 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();
    }
}

काम करने लगता है।


अपने एपीआई का परीक्षण करने के लिए अपने ब्राउज़र का उपयोग न करें।

इसके बजाय, एक HTTP क्लाइंट का उपयोग करने का प्रयास करें जो आपको अपना अनुरोध निर्दिष्ट करने की अनुमति देता है, जैसे कि कर्ल, या यहां तक ​​कि फिडलर।

इस समस्या के साथ समस्या क्लाइंट में है, एपीआई में नहीं। ब्राउजर के अनुरोध के मुताबिक वेब एपीआई सही तरीके से व्यवहार करता है।


इस सवाल से पूछा गया था (और उत्तर दिया गया) के बाद से कुछ समय बीत चुका है, लेकिन एक और विकल्प सर्वर पर स्वीकृति शीर्षलेख को ओवरराइड करना है, क्योंकि संदेश मैंडलर का उपयोग कर अनुरोध प्रक्रिया के दौरान नीचे दिया गया है:

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

जहां कुछ अन्य नियंत्रण ब्राउज़र प्रकार, आदि सहित कुछ भी हो सकता है। यह सशर्त मामलों के लिए होगा जहां कभी-कभी हम डिफ़ॉल्ट सामग्री वार्तालाप को ओवरराइड करना चाहते हैं। अन्यथा अन्य उत्तरों के अनुसार, आप कॉन्फ़िगरेशन से केवल एक अनावश्यक फॉर्मेटर निकाल देंगे।

आपको इसे निश्चित रूप से पंजीकृत करना होगा। आप या तो वैश्विक स्तर पर ऐसा कर सकते हैं:

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

वेबएपीआई में सामग्री बातचीत पर नज़र डालें। ये ( भाग 1 और भाग 2 ) आश्चर्यजनक रूप से विस्तृत और पूरी तरह से ब्लॉग पोस्ट बताते हैं कि यह कैसे काम करता है।

संक्षेप में, आप सही हैं, और केवल Accept या Content-Type अनुरोध शीर्षलेख सेट करने की आवश्यकता है। आपके एक्शन को एक विशिष्ट प्रारूप को वापस करने के लिए कोड नहीं किया गया है, आप Accept: application/json कर सकते हैं Accept: application/json


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

WebApiConfig.cs में , रजिस्टर फ़ंक्शन के अंत में जोड़ें:

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

Source


मुझे फेलिप लीसिन के दृष्टिकोण को सबसे अच्छा लगता है - सुनिश्चित करें कि ब्राउज़र उन क्लाइंट्स से सामग्री वार्तालाप समझौता किए बिना जेएसओएन प्राप्त करें जो वास्तव में एक्सएमएल चाहते हैं। मेरे लिए एकमात्र गायब टुकड़ा यह था कि प्रतिक्रिया शीर्षलेखों में अभी भी सामग्री-प्रकार शामिल है: टेक्स्ट / एचटीएमएल। वह एक समस्या क्यों थी? क्योंकि मैं 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());

एमएसडीएन से एएसपी.नेट और एंगुलरजेएस (लगभग 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, शीर्षलेख और विकल्पों के साथ ऐसा करने के कई तरीके हैं ... लेकिन जो मुझे लगता है कि सबसे अच्छा अभ्यास होना सरल है। आप एक सादे यूआरएल (उदा: 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 डिफ़ॉल्ट हैं, या शायद कहीं और बनाए गए हैं (मेरी परियोजना पर किसी और द्वारा)। एवेज, उम्मीद है कि यह मदद करता है।


चूंकि सवाल क्रोम-विशिष्ट है, इसलिए आप पोस्टमैन एक्सटेंशन प्राप्त कर सकते हैं जो आपको अनुरोध सामग्री प्रकार सेट करने की अनुमति देता है।


एक नया मुख्य अंतर है जिसके लिए जिम्मेदार होना आवश्यक है - सर्विसस्टैक अब v4 के रूप में उपयोग करने के लिए स्वतंत्र नहीं है। चूंकि एसएस प्रो पर एक सुंदर निश्चित उत्तर है, इसलिए मैं वेब एपीआई के लिए एक जोड़े को फेंकना चाहता था

वेब एपीआई

प्रो का:

  1. आपके प्रोजेक्ट में उपयोग करने के लिए नि: शुल्क (बशर्ते आपके पास एक वीएस लाइसेंस है जो व्यावसायिक उपयोग की अनुमति देता है)
  2. माइक्रोसॉफ्ट और पूरे वेब पर उपलब्ध असाधारण उच्च स्तर का मुफ्त समर्थन, यहां .com पर भी शामिल है।
  3. एएसपी.नेट एमवीसी जैसे अन्य माइक्रोसॉफ्ट टेक्नोलॉजी स्टैक के साथ त्वरित रूप से एकीकृत करता है जो माइक्रोसॉफ्ट की दुकानों में बेहद लोकप्रिय है
  4. आपके माइक्रोसॉफ्ट स्टैक में रीस्टफुल प्रमाणीकरण और प्रमाणीकरण के लिए समर्थन में बनाया गया है

कॉन:

  1. SOAP का समर्थन नहीं करता है

सहायक लाभ

(कृपया नीचे दी गई टिप्पणियां छोड़ने के लिए स्वतंत्र महसूस करें कि क्यों वेब एपीआई के लाभ हैं या मेरे पास पेशेवर / विपक्ष शामिल हैं)





json google-chrome asp.net-web-api