有没有办法强制ASP.NET Web API返回纯文本?

时间:2012-07-20 14:49:02

标签: asp.net 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");
}

6 个答案:

答案 0 :(得分:217)

嗯......我认为您不需要创建自定义格式化程序来实现此功能。而是返回这样的内容:

    [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 :(得分:14)

如果您只是在寻找一个简单的普通/文本格式化程序而不添加其他依赖项,那么这应该可以解决问题。

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

不要忘记将其添加到您的Global web api配置中。

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

现在您可以将字符串对象传递给

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

答案 2 :(得分:12)

  • 请小心不要在ASP.NET Web API中使用上下文,否则您迟早会抱歉。 ASP.NET Web API的异步特性使HttpContext.Current成为一种责任。
  • 使用纯文本格式化程序并添加到格式化程序中。周围有几十个。你甚至可以轻松地写你的。 WebApiContrib有一个。
  • 如果您已注册纯文本格式化程序,则可以通过在控制器中将httpResponseMessage.Headers上的内容类型标题设置为text/plain来强制执行此操作。

答案 3 :(得分:6)

当Accept:text / plain不起作用时,没有注册格式化文本mime类型。

通过从服务配置中获取所有支持的格式化程序列表,可以确保没有指定mime类型的格式化程序。

创建一个非常简单的媒体类型格式化程序,支持文本mime类型。

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

答案 4 :(得分:4)

对于.net核心:

[HttpGet("About")]
public ContentResult About()
{
    return Content("About text");
}

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/formatting

答案 5 :(得分:-1)

如下所示的扩展名可以减少行数并美化您的代码:

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