ASP.NET Web API가 일반 텍스트를 반환하도록 강제하는 방법이 있습니까?


125

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

답변:


231

흠 ...이 작업을 수행하기 위해 사용자 지정 포맷터를 만들 필요가 없다고 생각합니다. 대신 다음과 같은 내용을 반환하십시오.

    [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가 모든 메소드의 99 %에 JSON 객체를 반환 할 것이기 때문에 내가 선택한 솔루션입니다. 단지 몇 가지 (매우 적은) 메소드 만 일반 문자열 응답을 필요로 할 것입니다 (그리고 그 중 많은 것에서는 MemoryStream을 사용하여 데이터를 반환합니다) 응답에서 직접 문제가되지 않았습니다.) 2 개 또는 3 개의 메서드에서만 .NET 문자열을 반환했으며 JSON 문자열로 반환되었습니다. 귀하의 대답 IMHO는이 문제에 대한 KISS 응답입니다 (100 % DRY는 아니지만 문자열에 확장 메서드를 작성했습니다 ... :-) 좋습니다!) StringContent는 매우 좋습니다. 감사합니다.
Loudenvier 2013-06-15

이러한 종류의 일을 매우 간단하게 만드는 특정 유형의 콘텐츠를 만드는 여러 사용자 지정 XXXContent 클래스가 있습니다.
릭 Strahl

이 접근 방식으로 올바른 응답을 봅니다. 그러나 HttpContext.Current는 이제 null입니다. 이것에 대한 아이디어가 있습니까?
Nachiket Mehta 2015 년

@JavascriptEnthusiast-HttpContext.Current는 자체 호스팅이거나 System.Web 파이프 라인없이 OWin 스택을 통해 실행 중이기 때문에 null 일 가능성이 높습니다. 하지만이 솔루션과는 관련이 없습니다.
Rick Strahl 2015

15

추가 종속성을 추가하지 않고 단순한 일반 / 텍스트 포맷터를 찾고 있다면 트릭을 수행해야합니다.

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");


12
  • ASP.NET Web API에서 컨텍스트를 사용하지 않도록주의하십시오. 그렇지 않으면 조만간 죄송합니다. ASP.NET Web API의 비동기 적 특성은 사용을 어렵게 만듭니다 HttpContext.Current.
  • 일반 텍스트 포맷터를 사용하고 포맷터에 추가하십시오. 주변에 수십 개가 있습니다. 당신은 당신의 것을 쉽게 쓸 수도 있습니다. WebApiContrib 에는 하나가 있습니다.
  • 일반 텍스트 포맷터를 등록한 경우 컨트롤러에서 콘텐츠 유형 헤더를 httpResponseMessage.Headers로 설정하여 강제 할 수 있습니다 text/plain.

걱정하지 마세요. HttpContext 개체를 암시하거나 사용할 의도가 없었습니다. 방금 클래식 ASP.NET에서이를 수행하는 방법을 설명하기 위해 추가했습니다
Magnus Johansson

글쎄, waddayknow, 나는 이미 WebAPIContrib을 참조했으며 때로는 간단합니다.
Magnus Johansson 2012

@Magnus 물론입니다. 사실 나는 내가 쓴 것을 읽은 후에 단어를 변경했습니다. 그러나 다른 답변을 읽으면 그 첫 번째 요점이 강조되었습니다.
Aliostad 2012-07-20

HttpContext.Current를 사용하지 말라고 말하는 것입니다. 대안은 무엇입니까?
surya

@spiderdevil 예, 그것은 절대적으로 내가 말하는 것입니다. 필요하지 않으며 요청 / 응답 / 구성을 직접 전달하십시오.
Aliostad 2013-08-09

6

Accept : text / plain이 작동하지 않으면 text MIME 유형에 대해 등록 된 포맷터가 없습니다.

서비스 구성에서 지원되는 모든 포맷터 목록을 가져 와서 지정된 MIME 유형에 대한 포맷터가 없는지 확인할 수 있습니다.

텍스트 MIME 유형을 지원하는 매우 간단한 미디어 유형 포맷터를 만듭니다.

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


내가 당신의 대답을 받아 들일 수 있기를 바랍니다. 받아 들여진 대답은 나만의 포맷터를 작성하는 수고를 덜어주었습니다. 적어도 +1.
Magnus Johansson 2012

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


문자열과 관련이없는 항목으로 문자열 네임 스페이스를 낭비하지 마십시오.
Rambalac
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.