क्या ASP.NET वेब एपीआई को सादा पाठ वापस करने के लिए मजबूर करने का एक तरीका है?


125

मुझे ASP.NET वेब एपीआई नियंत्रक से सादे पाठ में प्रतिक्रिया प्राप्त करने की आवश्यकता है।

मैं एक अनुरोध के साथ करने की कोशिश की है, Accept: text/plainलेकिन यह चाल नहीं लगता है। इसके अलावा, अनुरोध बाहरी है और मेरे नियंत्रण से बाहर है। पुराने ASP.NET तरीके की नकल करने के लिए मैं क्या करूंगा:

context.Response.ContentType = "text/plain";
context.Response.Write("some text);

कोई विचार?

EDIT, समाधान : अलीओस्टाड के उत्तर के आधार पर, मैंने WebAPIContrib टेक्स्ट फॉर्मेटर को जोड़ा , इसे Application_Start में आरंभीकृत किया:

  config.Formatters.Add(new PlainTextFormatter());

और मेरे नियंत्रक ने कुछ इस तरह समाप्त किया:

[HttpGet, HttpPost]
public HttpResponseMessage GetPlainText()
{
  return ControllerContext.Request.CreateResponse(HttpStatusCode.OK, "Test data", "text/plain");
}

जवाबों:


231

हम्म् ... मुझे नहीं लगता कि आपको यह काम करने के लिए एक कस्टम फ़ॉर्मेटर बनाने की आवश्यकता है। इसके बजाय इस तरह से सामग्री लौटाएँ:

    [HttpGet]
    public HttpResponseMessage HelloWorld()
    {
        string result = "Hello world! Time is: " + DateTime.Now;
        var resp = new HttpResponseMessage(HttpStatusCode.OK);
        resp.Content = new StringContent(result, System.Text.Encoding.UTF8, "text/plain");
        return resp;
    }

यह मेरे लिए एक कस्टम फ़ॉर्मेटर का उपयोग किए बिना काम करता है।

यदि आप स्पष्ट रूप से आउटपुट बनाना चाहते हैं और स्वीकृत हेडर के आधार पर डिफ़ॉल्ट सामग्री बातचीत को ओवरराइड करना चाहते हैं तो आप Request.CreateResponse()इसका उपयोग नहीं करना चाहेंगे क्योंकि यह माइम प्रकार को बाध्य करता है।

इसके बजाय स्पष्ट रूप से एक नया बनाएं HttpResponseMessageऔर सामग्री को मैन्युअल रूप से असाइन करें। उपरोक्त उदाहरण का उपयोग करता है, StringContentलेकिन विभिन्न .NET डेटा प्रकारों / संरचनाओं से डेटा वापस करने के लिए कुछ अन्य सामग्री वर्ग उपलब्ध हैं।


1
यह वास्तव में वह समाधान है जिसके लिए मैं गया था क्योंकि मेरी एपीआई JSON ऑब्जेक्ट्स को सभी तरीकों के 99% पर लौटाएगी, केवल कुछ (बहुत कुछ) तरीकों से सादे स्ट्रिंग प्रतिक्रियाओं की आवश्यकता होगी (और उनमें से कई के लिए मैं डेटा वापस करने के लिए एक मेमोरीस्ट्रीम का उपयोग करता हूं सीधे प्रतिक्रिया में इसलिए यह एक गैर-मुद्दा था।) केवल 2 या 3 तरीकों में मैंने एक .NET स्ट्रिंग वापस किया, और यह JSON स्ट्रिंग के रूप में वापस किया जा रहा था। आपका जवाब, IMHO, इस समस्या के लिए KISS प्रतिक्रिया है (हालांकि यह 100% सूखी नहीं है, लेकिन मैं सिर्फ स्ट्रिंग के लिए एक विस्तार विधि ने लिखा है कि ऐसा करने के लिए ... :-) अच्छा!) StringContent बहुत अच्छा है। धन्यवाद।
लाउडेनवियर

विशिष्ट प्रकार की सामग्री बनाने के लिए कई कस्टम XXXContent कक्षाएं हैं जो इस प्रकार की चीज़ को बहुत सीधे आगे बनाती हैं।
रिक स्ट्राल

मैं इस दृष्टिकोण के साथ सही प्रतिक्रिया देखता हूं। हालाँकि, HttpContext.Current अब शून्य है। इस पर कोई विचार?
नचिकेत मेहता

@JavascriptEnthyer - HttpContext.Current सबसे अधिक संभावना है क्योंकि आप स्वयं-होस्टिंग कर रहे हैं या सिस्टम के बिना OWin स्टैक के माध्यम से चल रहे हैं। पाइपलाइन। हालांकि इस समाधान से संबंधित नहीं है।
रिक स्ट्राल

15

यदि आप केवल अतिरिक्त निर्भरता को जोड़ने के बिना एक सरल सादे / पाठ फ़ॉर्मेटर की तलाश कर रहे हैं, तो यह चाल चलनी चाहिए।

public class TextPlainFormatter : MediaTypeFormatter
{
    public TextPlainFormatter()
    {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
    }

    public override bool CanWriteType(Type type)
    {
        return type == typeof(string);
    }

    public override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
    {
        return Task.Factory.StartNew(() => {
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(value);
            writer.Flush();
        });
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
    {
        return Task.Factory.StartNew(() => {
            StreamReader reader = new StreamReader(stream);
            return (object)reader.ReadToEnd();
        });
    }
}

इसे अपने ग्लोबल वेब एपीआई कॉन्फिगर में जोड़ना न भूलें।

config.Formatters.Add(new TextPlainFormatter());

अब आप स्ट्रिंग ऑब्जेक्ट्स को पास कर सकते हैं

this.Request.CreateResponse(HttpStatusCode.OK, "some text", "text/plain");


12
  • कृपया सावधान रहें कि ASP.NET वेब एपीआई में संदर्भ का उपयोग न करें या आप जल्दी या बाद में क्षमा करें। ASP.NET वेब API की अतुल्यकालिक प्रकृति HttpContext.Currentएक दायित्व का उपयोग करती है।
  • एक सादे पाठ फ़ॉर्मेटर का उपयोग करें और अपने फ़ॉर्मेटर्स में जोड़ें। उनके आसपास दर्जनों हैं। आप भी आसानी से लिख सकते हैं। WebApiContrib में एक है।
  • आप पर सामग्री प्रकार हैडर सेट करके आप उसे मजबूर कर सकते हैं httpResponseMessage.Headersकरने के लिए text/plainअपने नियंत्रक में प्रदान की आप सादे पाठ फ़ॉर्मेटर पंजीकृत किया है।

चिंता मत करो, मैं न तो निहित है और न ही HttpContext ऑब्जेक्ट का उपयोग करने का इरादा है, मैंने सिर्फ यह बताने के लिए इसे जोड़ा कि कैसे कोई इसे क्लासिक ASP.NET में करेगा
मैग्नस जोहानसन

खैर, वाडडेकोन, मेरे पास पहले से ही वेबएपॉन्ट्रिब का संदर्भ था, कभी-कभी यह सरल होता है।
मैगनस जोहानसन

@ मैग्नस ज़रूर मैंने जो लिखा था उसे पढ़ने के बाद मैंने वास्तव में शब्द बदल दिया। लेकिन एक अन्य उत्तर को पढ़ने से मुझे पहले बिंदु पर जोर दिया गया।
अलीओस्ताद

आप HttpContext.Current का उपयोग नहीं करने के लिए कह रहे हैं, विकल्प क्या हैं?
सूर्या

@spiderdevil हाँ, यह बिल्कुल वही है जो मैं कह रहा हूँ। आपको इसकी आवश्यकता नहीं है, सीधे अनुरोध / प्रतिक्रिया / कॉन्फ़िगरेशन पास करें।
अलीओस्ताद

6

जब स्वीकार करें: पाठ / सादा काम नहीं करता है, तो पाठ माइम प्रकारों के लिए कोई पंजीकृत फ़ॉर्मेटर नहीं है।

आप यह सुनिश्चित कर सकते हैं कि सेवा कॉन्फ़िगरेशन से सभी समर्थित फ़ॉर्मेटरों की सूची प्राप्त करके निर्दिष्ट माइम प्रकार के लिए कोई फॉर्मेटर्स नहीं हैं।

एक बहुत ही सीधा मीडिया प्रकार का फ़ॉर्मेटर बनाएं जो टेक्स्ट माइम प्रकारों का समर्थन करता है।

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters


काश मैं आपका उत्तर भी स्वीकार कर लेता, स्वीकृत उत्तर ने मुझे अपने स्वयं के फ़ॉर्मेट लिखने की परेशानी से बचा लिया। कम से कम +1।
मैग्नस जोहानसन

0

निम्नलिखित की तरह एक एक्सटेंशन लाइनों की संख्या को कम कर सकता है और आपके कोड को सुशोभित कर सकता है:

public static class CommonExtensions
{
    public static HttpResponseMessage ToHttpResponseMessage(this string str)
    {
        var resp = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(str, System.Text.Encoding.UTF8, "text/plain")
        };

        return resp;
    }
}


अब आप अपने में परिभाषित विस्तार का उपभोग कर सकते हैं Web API:

public class HomeController : ApiController
{
    [System.Web.Http.HttpGet]
    public HttpResponseMessage Index()
    {
        return "Salam".ToHttpResponseMessage();
    }
}


रूटिंग करके {DOMAIN}/api/Home/Indexआप निम्नलिखित सादे पाठ देख सकते हैं:

MyPlainTextResponse


स्ट्रिंग से असंबंधित सामान के साथ स्ट्रिंग नेमस्पेस को बर्बाद न करें।
रामबालक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.