2012-07-20 135 views
107

我需要從ASP.NET Web API控制器以純文本形式獲取響應。有沒有辦法強制ASP.NET Web API返回純文本?

我試過用Accept: text/plain做了一個請求,但它似乎沒有辦法。 此外,該請求是外部的,並且不在我的控制之下。我會做的是模仿舊的ASP.NET方式:

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

任何想法?

編輯,解決: 基於Aliostad的回答,我添加了WebAPIContrib文本格式化,初始化它在Application_Start:

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

和我的控制器結束了類似:

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

回答

192

嗯...我不認爲你需要創建一個自定義的格式,使這項工作。而是像這樣返回內容:

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

這對我而言沒有使用自定義格式化程序。

如果您明確要創建輸出並覆蓋基於Accept標頭的默認內容協商,則不會希望使用Request.CreateResponse(),因爲它會強制MIME類型。

而是明確創建一個新的HttpResponseMessage並手動分配內容。上面的示例使用StringContent,但還有其他很多內容類可用於從各種.NET數據類型/結構中返回數據。

+1

這實際上是我去的解決方案,因爲我的API會將JSON對象返回到所有方法的99%,只有少數(非常少)方法需要純字符串響應(對於許多我使用MemoryStream返回的方法數據直接在響應中,所以這不成問題。)只有2或3個方法返回了一個.NET字符串,並且它以JSON字符串形式返回。恕我直言,你的答案是KISS對這個問題的迴應(雖然它不是100%乾的,但我只是寫了一個擴展方法來將字符串做到這一點...... :-)不錯!)StringContent非常好。謝謝。 – Loudenvier 2013-06-15 12:34:33

+0

有許多自定義的XXXContent類可以創建特定類型的內容,使這類事情變得非常簡單。 – 2015-03-20 02:19:07

+0

我用這種方法看到了正確的答案。但是,HttpContext.Current現在爲空。對此有何想法? – 2015-05-12 22:05:25

6

當Accept:text/plain不起作用時,那麼文本MIME類型沒有註冊的格式化程序。

通過從服務配置中獲取所有支持的格式化程序的列表,您可以確保沒有指定MIME類型的格式化程序。

創建一個支持文本MIME類型的非常直接的媒體類型格式化程序。

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

+0

希望我能接受你的答案爲好,接受的答案救了我寫的麻煩我自己的格式化器。至少+1。 – 2012-07-20 15:49:12

12
  • 請注意不要在的ASP.NET Web API使用環境或你遲早會後悔的。 ASP.NET Web API的異步特性使得使用HttpContext.Current負債。
  • 使用純文本格式化程序並添加到您的格式化程序中。其中有幾十個。你甚至可以輕鬆地寫你的。 WebApiContrib有一個。
  • 如果您已註冊純文本格式化程序,您可以通過在控制器上將內容類型標頭httpResponseMessage.Headers設置爲text/plain來強制執行此操作。
+0

不要擔心,我既不暗示也不打算使用HttpContext對象,我只是添加它來說明如何在經典ASP.NET中執行它 – 2012-07-20 15:29:34

+0

好吧,waddayknow,我已經引用了WebAPIContrib,有時很簡單。 – 2012-07-20 15:40:34

+0

@Magnus當然。事實上,在我讀完我寫的內容後,我改變了措詞。但是讀另一個答案讓我強調了第一點。 – Aliostad 2012-07-20 15:44:40

11

如果你只是尋找一個簡單的普通/文本格式化程序而不添加額外的依賴關係,這應該是個竅門。

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

不要忘了將它添加到您的全球網頁API配置。

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

現在你可以通過字符串對象

this.Request.CreateResponse(HttpStatusCode.OK, "some text", "text/plain"); 
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

相關問題