Accessing known headers for HttpRequestMessage, HttpResponseMessage and HttpContent - asp.net

I'm currently working with creating a HttpRequestMessage and making a request with it. I have a collection of headers that I want to add to the request message.
I iterate through these headers and add them to the request with
message.Headers.Add(header, values);
However as part of my testing I'm finding that I get the following error thrown occassionaly (e.g. with Content-Length or Content-Type).
Misused header name. Make sure request headers are used with
HttpRequestMessage, response headers with HttpResponseMessage, and
content headers with HttpContent objects.
I've used a decompiler to look at HttpContentHeaders and HttpRequestHeaders and they both have an internal static method that populates a HashSet with a list of known headers, e.g.
internal static void AddKnownHeaders(HashSet<string> headerSet)
{
headerSet.Add("Allow");
headerSet.Add("Content-Disposition");
headerSet.Add("Content-Encoding");
// snip...
}
Is there a way to access the known/allowed headers for each of the types (content, request)? Reflection is an option but I'm wondering if there's another method to know where to add the headers?

Related

Get the JSON that was used to call our ASP.NET REST Web API

We often have the case that clients call our ASP.NET API with an invalid JSON. The mistakes can be anywhere from wrong fields to wrong formatting.
Yes, you could argue that this is the clients problem, but this will not make my life easier.
Is there a way to get to whatever the client sent us, if the controller throws an Exception?
This code snippet will allow you to see the raw content of the request body:
using (var reader = new System.IO.StreamReader(System.Web.HttpContext.Current.Request.InputStream))
{
var content = reader.ReadToEnd(); // raw content of request body
}

Dart - HTTP - Encode JSON Object with Array & int properties

I'm trying to make a POST request using dart's http package with json data as the body, I'm using a variable of type dynamic to create the json object and so far it works perfectly as long as all the values in the object are strings.
If I assign the value of a property to be an int or List<int> (expecting it to be converted to an array, as expected by the server) dart crashes due to expecting either a Map<String, String> or a List<int> as the type for the body (the exact type it expects is dynamic, but it tries to cast it to Map<String, String> or List<int>).
My question is, is there any workaround to making a http POST request in dart using a object with dynamic property values?
I was able to resolve this issue by using the HttpClient & HttpClientRequest classes from the dart:io package.
I stored the body as a Map<String, dynamic> and json encoded it before writing it to the request stream.

Why cant we get a file data from a RequestBody in java?

I am trying to upload a file to a server so i am trying to use #RequestBody to get the data of the file, but i am getting 415 error code while trying to upload a file.
So i have googled(got solution to upload a file) and got to know that i cant get file data from a request body. So i want to know why cant we access file data from request body as data will be sent in request body in HTTP requests, so i want to know how is the request happening in the case of uploading a file.
My server code before:
#RequestMapping(value = "/upload",headers = "Content-Type=multipart/form-data", method = RequestMethod.POST)
#ResponseBody
public String upload(#RequestBody MultipartFile file)
{
}
Solution:
#RequestMapping(value = "/upload",headers = "Content-Type=multipart/form-data", method = RequestMethod.POST)
#ResponseBody
public String upload(MultipartHttpServletRequest request)
{
}
Technically you could write your own HttpMessageConverter which would parse the full multipart request body, but you'd have to have a very specific target type that could handle all the parts.
You'll notice from the javadoc of #RequestBody
Annotation indicating a method parameter should be bound to the body
of the web request.
that the intention is to bind the entirety of the request body to the method parameter. How do you bind every part of a multipart request to a single parameter? Something like a MultiValueMap<String, Object> (which is what FormHttpMessageConverter uses when writing a multipart request). But that wouldn't be very useful because you'd have to check the type of each value.
It makes much more sense as a developer to specify exactly what you need. That's why #RequestParam and #RequestPart are available.
Because the files are not the request body, they are part of it and there is no built-in HttpMessageConverter that can convert the request to an array of MultiPartFile.
Thats why it works #RequestParam("file") MultipartFile[] files
instead of
#RequestBody MultipartFile file
Hope it helps.

How to create an endpoint that accepts any content type in the request body using ASP.Net Web API

I'd like to create a generic API endpoint that a client can post text or file data to, where we won't know the content/media type of the data. It seems the framework requires a content formatter to be specified for any content-type passed in the HTTP header, or it throws an error. I don't want to have to define a formatter for every possible media type we might accept since we don't know yet what all they could include.
Is there a way to define an endpoint with a generic media type formatter, or not specify one at all? It doesn't seem to mind if I use a generic Object as my method parameter, but the framework keeps getting hung up on not being able to handle the media type without a formatter.
We don't actually need to be able to process this data, just store it (for something like a messaging system).
On a side note, I'd rather receive this data as the raw content of the request body and not use a multipart form request, but if it would make more sense to do it that way, it might be an option.
Or if you want to go even more low level than Youssef's suggestion, you can do..
public Task<HttpResponseMessage> Post(HttpRequestMessage request) {
var stream = await request.Content.ReadAsStreamAsync();
return new HttpResponseMessage(HttpStatusCode.Ok) { RequestMessage = request } ;
}
You can bypass formatters entirely by reading the content yourself. Here's an example:
public async Task Post()
{
string content = await Request.Content.ReadAsStringAsync();
// Store away the content
}
This doesn't require you to use or define any formatters at all.

Spring 3.0 HEAD Requests

recently we moved to spring 3.0 Controller handling like this:
#Controller
public class MyController {
#RequestMapping(method = RequestMethod.POST)
protected String onSubmit ( Form form, Errors errors) {
// handle POST
}
#RequestMapping(method = RequestMethod.GET)
protected void getForm ( Form form ) {
// handle GET
}
}
Now we are getting lots of Exceptions in our logs because of HEAD Requests.
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'HEAD' not supported
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodResolver.resolveHandlerMethod(AnnotationMethodHandlerAdapter.java:621)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:422)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)
...
I would like to support HEAD Requests the same way like GET Requests, but obeying the HTTP reference of course:
The HEAD method is identical to GET
except that the server MUST NOT
return a message-body in the response.
The metainformation contained in
the HTTP headers in response to a HEAD
request SHOULD be identical to the
information sent in response to a GET
request. This method can be used
for obtaining metainformation about
the entity implied by the request
without transferring the entity-body
itself. This method is often used
for testing hypertext links for
validity, accessibility, and recent
modification.
http://www.ietf.org/rfc/rfc2616.txt
Does anybody has an elegant solution or is there even a spring solution out-of-the-box?
I searched the web but did not find any answers to this.
I believe this is what you're looking for:
http://www.axelfontaine.com/2009/09/transparently-supporting-http-head.html
In the current Spring (4.3.10) HEAD is automatically supported:
#RequestMapping methods mapped to "GET" are also implicitly mapped to
"HEAD", i.e. there is no need to have "HEAD" explicitly declared. An
HTTP HEAD request is processed as if it were an HTTP GET except
instead of writing the body only the number of bytes are counted and
the "Content-Length" header set.
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-head-options
Just add HEAD as a supported method the the request mapping:
#RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
Update: I think you can provide a custom class that extends AnnotationMethodHandlerAdapter to be the method handler (in dispatcher-servlet.xml), and just bypass the HEAD support check there. But I'd just use the replace features of an IDE to add it.

Resources