2012-07-20 63 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

相关问题