2012-07-20 31 views
107

Tôi cần nhận lại phản hồi bằng văn bản thuần tuý từ bộ điều khiển ASP.NET Web API.Có cách nào để buộc ASP.NET Web API trả về văn bản thuần túy không?

Tôi đã thử thực hiện yêu cầu với Accept: text/plain nhưng có vẻ như không phải là mẹo. Bên cạnh đó, yêu cầu nằm ngoài và ngoài tầm kiểm soát của tôi. Những gì tôi sẽ thực hiện là bắt chước theo cách cũ của ASP.NET:

context.Response.ContentType = "text/plain"; 
context.Response.Write("some text); 

Bất kỳ ý tưởng nào?

EDIT, giải pháp: Dựa trên câu trả lời Aliostad, tôi thêm vào các định dạng WebAPIContrib văn bản, khởi tạo nó trong Application_Start:

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

và điều khiển của tôi đã kết thúc một cái gì đó như:

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

Trả lời

192

Hmmm ... Tôi không nghĩ rằng bạn cần phải tạo ra một định dạng tùy chỉnh để làm cho công việc này. Thay vào đó, hãy trả lại nội dung như sau:

[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; 
    } 

Điều này làm việc cho tôi mà không cần sử dụng trình định dạng tùy chỉnh.

Nếu bạn rõ ràng muốn tạo đầu ra và ghi đè thương lượng nội dung mặc định dựa trên tiêu đề Chấp nhận, bạn sẽ không muốn sử dụng Request.CreateResponse() vì nó buộc loại mime.

Thay vào đó, hãy tạo một cách mới một cách thủ công HttpResponseMessage và gán nội dung theo cách thủ công. Ví dụ trên sử dụng StringContent nhưng có khá nhiều lớp nội dung khác có sẵn để trả về dữ liệu từ các loại/cấu trúc dữ liệu .NET khác nhau.

+1

Đây là giải pháp mà tôi đã đi vì API của tôi sẽ trả về các đối tượng JSON đến 99% tất cả các phương thức, chỉ một vài (rất ít) phương thức sẽ cần các câu trả lời chuỗi đơn giản (và đối với nhiều người trong số chúng tôi sử dụng MemoryStream để trả về dữ liệu trực tiếp trong phản hồi để nó không phải là vấn đề.) Chỉ trong 2 hoặc 3 phương thức tôi trả về một chuỗi .NET, và nó đã được trả về như một chuỗi JSON. Câu trả lời của bạn, IMHO, là phản ứng KISS cho vấn đề này (mặc dù nó không phải là 100% KHÔ, nhưng tôi chỉ viết một phương pháp mở rộng để chuỗi để làm điều đó ... :-) Tốt đẹp!) StringContent là rất tốt đẹp. Cảm ơn bạn. – Loudenvier

+0

Có một số lớp XXXContent tùy chỉnh để tạo các loại nội dung cụ thể giúp bạn thực hiện điều này một cách thẳng thắn. –

+0

Tôi thấy phản hồi chính xác với phương pháp này. Tuy nhiên, HttpContext.Current là null bây giờ. Bất kỳ ý tưởng về điều này? –

6

Khi chấp nhận: văn bản/đồng bằng không hoạt động, sau đó không có trình định dạng đã đăng ký cho loại mime văn bản.

Bạn có thể đảm bảo rằng không có trình định dạng cho loại mime được chỉ định bằng cách nhận danh sách tất cả các trình định dạng được hỗ trợ từ cấu hình dịch vụ.

Tạo trình định dạng loại phương tiện rất đơn giản hỗ trợ các loại văn bản.

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

+0

ước gì có thể chấp nhận câu trả lời của bạn là tốt, câu trả lời được chấp nhận cứu tôi những rắc rối của văn bản của tôi định dạng riêng. +1 ít nhất. –

12
  • Hãy cẩn thận không sử dụng bối cảnh trong ASP.NET Web API hoặc bạn sẽ sớm hay muộn được xin lỗi. Bản chất không đồng bộ của ASP.NET Web API làm cho việc sử dụng HttpContext.Current là một trách nhiệm pháp lý.
  • Sử dụng trình định dạng văn bản thuần túy và thêm vào trình định dạng của bạn. Có hàng chục người xung quanh. Bạn thậm chí có thể viết của bạn một cách dễ dàng. WebApiContrib có một.
  • Bạn có thể ép buộc bằng cách đặt tiêu đề loại nội dung trên httpResponseMessage.Headers thành text/plain trong bộ điều khiển của bạn miễn là bạn đã đăng ký định dạng văn bản thuần túy.
+0

Đừng lo lắng, tôi không ngụ ý hay không định sử dụng đối tượng HttpContext, tôi chỉ thêm nó để minh họa cách một người sẽ làm điều đó trong ASP.NET –

+0

cổ điển Vâng, waddayknow, tôi đã có WebAPIContrib được tham chiếu, đôi khi nó đơn giản. –

+0

@Magnus Sure. Tôi thực sự đã thay đổi từ ngữ sau khi tôi đọc những gì tôi đã viết. Nhưng đọc một câu trả lời khác khiến tôi nhấn mạnh rằng điểm đầu tiên. – Aliostad

11

Nếu bạn chỉ tìm kiếm một trình định dạng đơn giản/văn bản đơn giản mà không cần thêm phụ thuộc, điều này sẽ thực hiện thủ thuật.

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

Đừng quên để thêm nó vào toàn cầu web api cấu hình của bạn.

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

Bây giờ bạn có thể vượt qua đối tượng chuỗi

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

Một phần mở rộng như sau ai có thể giảm số lượng các đường dây và làm đẹp mã của bạn:

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


Bây giờ bạn có thể tiêu thụ tiện ích được xác định trong Web API:

của bạn
public class HomeController : ApiController 
{ 
    [System.Web.Http.HttpGet] 
    public HttpResponseMessage Index() 
    { 
     return "Salam".ToHttpResponseMessage(); 
    } 
} 


Bằng cách định tuyến {DOMAIN}/api/Home/Index bạn sẽ nhìn thấy văn bản đơn giản sau đây:

MyPlainTextResponse

Các vấn đề liên quan