有没有办法强制 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");
}
83552 次浏览

如果 Accept: text/print 不起作用,那么就没有文本哑剧类型的注册格式化程序。

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

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

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

  • 请小心 不要在 ASP.NET Web API 中使用上下文,否则你迟早会后悔的。NET Web API 的异步特性使得使用 HttpContext.Current成为一种负担。
  • 使用纯文本格式化程序并添加到格式化程序中。这附近有好几十个。你甚至可以很容易地写出你的。WebApiContrib有一个。
  • 如果已经注册了纯文本格式化程序,可以通过在控制器中将 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();
});
}
}

不要忘记将它添加到您的全球网络应用程序接口配置。

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

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

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 核心:

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

Https://learn.microsoft.com/en-us/aspnet/core/mvc/models/formatting

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

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