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

有没有办法强制ASP.NET Web API返回纯文本?,asp.net,asp.net-web-api,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的回答,我添加了文本格式化程序,并在应用程序启动时对其进行了初始化: co

我需要从ASP.NET Web API控制器返回纯文本响应

我曾尝试使用
Accept:text/plain
执行请求,但似乎没有效果。 此外,请求是外部的,我无法控制。我要做的是模仿旧的ASP.NET方式:

context.Response.ContentType = "text/plain";
context.Response.Write("some text);
有什么想法吗

编辑,解决方案: 根据Aliostad的回答,我添加了文本格式化程序,并在应用程序启动时对其进行了初始化:

  config.Formatters.Add(new PlainTextFormatter());
我的控制器的结果是:

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

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

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

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

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

如果您只是在寻找一个简单的纯文本格式化程序,而没有添加额外的依赖项,那么这应该可以实现

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();
        });
    }
}
现在可以将字符串对象传递给

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

嗯。。。我认为您不需要创建自定义格式化程序来实现这一点。而是按如下方式返回内容:

    [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数据类型/结构返回数据。

对于.NET core:

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

像下面这样的扩展可以减少行数并美化代码:

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


别担心,我既没有暗示也没有打算使用HttpContext对象,我只是添加它来说明如何在经典的ASP.NETWell中使用它。waddayknow,我已经引用了WebAPIContrib,有时它很简单。@Magnus确定。事实上,在我读了我写的东西之后,我改变了措辞。但是阅读另一个答案让我强调了第一点。你是说不要使用HttpContext。目前,有什么替代方案?@spiderdevil是的,这绝对是我要说的。你不需要它,直接通过请求/响应/配置。希望我也能接受你的答案,接受的答案省去了我编写自己的格式化程序的麻烦+至少是1。事实上,这是我选择的解决方案,因为我的API将向99%的所有方法返回JSON对象,只有少数(极少数)方法需要纯字符串响应(对于许多方法,我使用MemoryStream直接在响应中返回数据,所以这不是问题)。只有在2或3个方法中,我返回了.NET字符串,它以JSON字符串的形式返回。你的答案,IMHO,是这个问题的KISS响应(虽然它不是100%干燥的,但我刚刚为string编写了一个扩展方法…:-)很好!)内容非常好。谢谢。有许多定制的XXXContent类可以创建特定类型的内容,使这类内容变得非常简单。我看到了这种方法的正确响应。但是,HttpContext.Current现在为空。有什么想法吗?@javascriptfander-HttpContext.Current很可能是空的,因为您是自托管的,或者在没有System.Web管道的情况下通过OWin堆栈运行。但与此解决方案无关。不要将字符串命名空间浪费在与字符串无关的内容上。
public class HomeController : ApiController
{
    [System.Web.Http.HttpGet]
    public HttpResponseMessage Index()
    {
        return "Salam".ToHttpResponseMessage();
    }
}