I have an apache camel route that is making an HTTP POST request i.e.
from(...).setHeader(Exchange.HTTP_METHOD, constant(POST)).to("http4://myUrl?...");
The request URL includes query params (unusual for POST i know, but I have no choice here) that I need to populate from details of the exchange which are stored on the body.
i.e. The body is a POJO like so:
public class Params {
String param1;
int param2;
....
//etc. etc. including getters and setters
}
Where each field is either a primitive or string, and refers directly to an equivalent query parameter:
http4://myUrl?param1=...¶m2=...&...
Is there a way I can avoid having to manually define every parameter on the URL and instead automagically map the exchange body to query params on the request being made?
The reason I need to do this is that some of the query params are optional, and should be populated based on the contents of the exchange body.
You can set the header Exchange.HTTP_QUERY with the query parameters separated.
And its not possible to automatic map from a message bodies its fields to URI parameters (no magic included). You would need to build some code that computes the URI query with & separating the values, and setting that as the HTTP_QUERY header.
Related
Usually I send my post request with a custom parameter and a custom return and object using
HttpClientExtension.PostAsJsonAsync<T>
This allows my to call a post method with a custom object.
Now, I want to be able to send my custom object as a parameter and return value to a GET Method.
Lets say my method signature is
[HttpGet]
public MyMethodResponse MyMethod(MyMethodRequest request)
How can I send a request when I have an instance of MyMethodRequest ?
Thanks.
You need to encode MyMethodRequest onto the query string. You can either encode it as separate query string parameters or as a single one. You have handle the encoding yourself on the client side, remembering to URI-encode the parameters. Decoding is done using a custom ModelBinder or TypeConverter respectively. This article shows examples of binding a complex object on the query string.
With a POST request in case it has the same parameter in the query string and in the body of the request which one takes priority with model binding?
From this article, in the "Value Provders" section.
Previously bound action parameters, when the action is a child action
Form fields (Request.Form)
The property values in the JSON Request body (Request.InputStream), but only when the request is an AJAX request
Route data (RouteData.Values)
Querystring parameters (Request.QueryString)
Posted files (Request.Files)
So if the same name appears in multiple places, the last place the model binder looks will take precedence (I think), in your case, the querystring.
Easiest thing to do is try it. Enter a url with a &id=23" and make sure you have a HTML input field named "id" and POST that back to the controller and see which one is passed.
Let say I have a url mappings
"blog/$year/$month/$day" (controller:'blog')
There's no way that I can pass the values for $year, $month and $day to remoteFunction so that it generates the proper url.
without variables, default rule would match and generated url would be like "/controller/action" I know i can pass the params to remoteFunction - so incoming url will match the rule, but how about reverse url mappings - that is used to generate the url for the ajax endpoint.
Any solution ?
If you are looking for a way to put the parameters from the url mapping into a remoteFunction() call, the grails manual says this can be done by accessing the params map in the controller after the request is received:
static mappings = {
"/$blog/$year/$month/$day/$id"(controller: "blog", action: "show")
}
"The individual tokens in the URL would again be mapped into the
params object with values available for year, month, day, id and so
on."
http://grails.org/doc/latest/guide/theWebLayer.html#urlmappings
The server is hosting Asp.net mvc3 app and the Browser culture is set to da (Danish)
GET request url: /get?d=1.1 (note that the decimal separator is .)
return: da;1,1 (note that the decimal separator is ,)
GET request url: /get?d=1,1 (the decimal separator is ,)
return: Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'd' of non-nullable type 'System.Decimal' for method 'System.Web.Mvc.ContentResult get(System.Decimal)' in 'Intranet.Controllers.OrderController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
But given the same input to a post request, the results are exactly opposite.
POST request url: /get2 (form data d=1.1)
return: Exception ...
POST request url: /get2 (form data d=1,1)
return: da;1,1
I suppose the POST request is working as expected. But why does the GET request behave differently? How does the default model binder work in this case.
When you send the data through a post, the locales take effect. When you send the data through a GET, it always uses the invariant locale.
It seems this is done because you could copy and paste an URL, and send it to someone in another country. If the language of the browser was considered when a parameter is included in the URL (GET) the URL would break (it's more obvious if you think about date formats than decimal separators).
Among other places, it's mentioned here by a member of the .Net team: http://forums.asp.net/t/1461209.aspx/1?Nullable+DateTime+Action+Parameters+Parsed+in+US+format+irrespective+of+locale+
I need to make oAuth multipart request message for the API which requires some query string parameters as well as Multipart Post Part.
But there is no PrepareAuthorizedRequest Method which accepts both IDictionary type query string parameters and MultipartPostPart fields.
What should I do?
Simply create a MessageReceivingEndpoint whose URI already includes those query string parameters.