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
Strange Behaviour of Console.Readkey() with Multithreading
Converting ASP.NET MVC Razor @Helper Function into a Method of a Helper Class
Why Do Members of a Static Class Need to Be Declared as Static? Why Isn't It Just Implicit
Using Statement with Generics: Using Iset<> = System.Collections.Generic.Iset<>
Modifying a JSON File Using System.Text.JSON
Xml Validation Using Xsd Schema
Preprocessor Directive in C# for Importing Based on Platform
How to Delay Shutdown and Run a Process in Window Service
Convert Am/Pm Time to 24 Hours Format
Get Line Number for Xelement Here
C# Object Initialization of Read Only Collection Properties
How to Get a Combination of Keys in C#
Group by Variable Integer Range Using Linq
How Can a C++ Windows Dll Be Merged into a C# Application Exe