Put Content in Httpresponsemessage Object

Put content in HttpResponseMessage object?

Apparently the new way to do it is detailed here:

http://aspnetwebstack.codeplex.com/discussions/350492

To quote Henrik,

HttpResponseMessage response = new HttpResponseMessage();

response.Content = new ObjectContent<T>(T, myFormatter, "application/some-format");

So basically, one has to create a ObjectContent type, which apparently can be returned as an HttpContent object.

Web API: Content in HttpResponseMessage

HttpResponseMessage<T> was removed after Beta. Right now, instead of a typed HttpResponseMessage we have a typed ObjectContent

If you manually create HttpResponseMessage using its default parameterless constructor, there is no request context available to perform content negotiation - that's why you need to specify the formatter, or perform content negotiation by hand.

I understand you don't want to do that - so use this instead:

HttpResponseMessage response = Request.CreateResponse<MyObject>(HttpStatusCode.OK, objInstance);

That would create the response message relying on the content negotiation performed against the request.

Finally, you can read more about content negotiation here On this link

Converting the content of HttpResponseMessage to object

So, first to address the you need Newtonsoft.Json comments, I really haven't felt the need yet. I've found the built in support to work well so far (using the APIError Json in my original question:

[DataContract]
internal class APIError
{
[DataMember (Name = "status")]
public int StatusCode { get; set; }
[DataMember (Name = "code")]
public int ErrorCode { get; set; }
}

I have also defined a JsonHelper class to (de)serialize:

public class JsonHelper
{
public static T fromJson<T> (string json)
{
var bytes = Encoding.Unicode.GetBytes (json);

using (MemoryStream mst = new MemoryStream(bytes))
{
var serializer = new DataContractJsonSerializer (typeof (T));
return (T)serializer.ReadObject (mst);
}
}

public static string toJson (object instance)
{
using (MemoryStream mst = new MemoryStream())
{
var serializer = new DataContractJsonSerializer (instance.GetType());
serializer.WriteObject (mst, instance);
mst.Position = 0;

using (StreamReader r = new StreamReader(mst))
{
return r.ReadToEnd();
}
}
}
}

The above bits I already had working. As for a single method that would handle each request execution based on the type of result expected while it makes it easier to change how I handle things (like errors, etc), it also adds to the complexity and thus readability of my code. I ended up creating separate methods (all variants of the Execute method in the original question:

// execute and return response.StatusCode
private static async Task<HttpStatusCode> ExecuteForStatusCode (HttpRequestMessage request, bool authenticate = true)
// execute and return response without processing
private static async Task<HttpResponseMessage> ExecuteForRawResponse(HttpRequestMessage request, bool authenticate = true)
// execute and return response.IsSuccessStatusCode
private static async Task<Boolean> ExecuteForBoolean (HttpRequestMessage request, bool authenticate = true)
// execute and extract JSON payload from response content and convert to RESULT
private static async Task<RESULT> Execute<RESULT>(HttpRequestMessage request, bool authenticate = true)

I can move the unauthorized responses (which my current code isn't handling right now anyway) into a new method CheckResponse that will (for example) log the user out if a 401 is received.

web api: add data to the HttpResponseMessage

Use the CreateResponse extension method on the request and it will allow for content negotiation based on associated request. If you want to force the content type based on the content type of the request take it from the request and include it in the create response overloads.

public class MyApitController : ApiController {
[HttpPost]
public async Task<HttpResponseMessage> Create([FromBody] AType payload) {
if (payload == null) {
throw new ArgumentNullException(nameof(payload));
}

await Task.Delay(1);

var t = new T { Id = 0, Name = payload.tName, Guid = Guid.NewGuid() };

var response = new MyResponse { T = t };

var contentType = Request.Content.Headers.ContentType;

var result = Request.CreateResponse(HttpStatusCode.OK, response, contentType);

return result;
}

}

The type returned should ideally be based on what the request indicates it wants to accept. The framework does allow flexibility on that topic.

Check this for more info Content Negotiation in ASP.NET Web API

Getting content/message from HttpResponseMessage

You need to call GetResponse().

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();

Return Content From HttpResponseMessage and Map to POCO

You can use DeserializeObject method from Newtonsoft.Json.JsonConvert class like this:

var response = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<List<TeamName>>(response);

How to put a file in the HttpResponseMessage Content?

You can use the System.Net.Http.HttpContent.StreamContent instance to add a FileStream object to the to the HttpResponseMessage's Content property. Something like this:

        // Return archive stream
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(fileStream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileName = fileName.ToString()
};

Note that you should probably also add a MD5 checksum to the file content in real applications.



Related Topics



Leave a reply



Submit