WebAPI 2 and post parameters in body passed as null - asp.net-web-api

I have a webapi2 controller method as below:
[Route("shipment/{shipmentId:long}/quotes/register")]
public HttpResponseMessage ProvideQuote(long shipmentId, [FromBody]RegisterQuote quote)
{
HttpResponseMessage response;
response = Request.CreateResponse(HttpStatusCode.Accepted, String.Format("quote of price {0} for shipment {1} has been registred", quote.QuotePrice, shipmentId));
return response;
}
now the issue is that when I test the method using my REST client, the quote is always null.
here is how I am testing
parameter
now the response I get is:
as you can see that the query string parameter is being passed correctly, but the body parameter is not passed. any idea what am I doing wrong.
Edit 1:
Request Header:
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Authorization: Bearer Hhz54k1BLyPMJxucSeq4pLwhS3Y4Ez5WCoEMzhe-uH7gHMFMRjHE2Im9juinMLhqaHVZmkVrWetEiCsYbaduzLas7rYf-D3p40lH_q3IDEn2rdt122qpiHvnUr7Cz2b6GXiPYLGDMQFOMN0lbkYmoZe95sxXDRvDfpdJw4G2Fk3Ri1A25F3qAZCnBhjA-BLoL-2eAjxX-RPCGAXjaNLjT4zsxRJH8NP5qC7azPrWCDKRuK282hnTbKViQjMBDflwlxdPhTNkiCBtxWn03xRcxH9GD1z5Ca0Qinn5gUS7qWwCt9zoZtHcbwFY1kvxyx7x5yCuyEfrGHgKG1s7zjTPjNwU0eV7cC6xQA2GsOAnqADxMDyRryCRKLY7WcyQftRhZ70WbtSW2PI0F7qmDr8n0wvktmKglusLEDf4ib925n-ajVTyMl7v9O-9OsdgCj_GSNE6_bszd3Ak1yUurs-VoQ
Content-Type: application/x-www-form-urlencoded
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,kn;q=0.6
BTW I am not sure what happened to all my images though!
Regards
Kiran

The issue here is that you are sending Json content in the body but have the content-type header as application/x-www-form-urlencoded...change the content-type header to application/json or text/json if want to send data in json...

Related

Unable to Send Data in header to Spring Boot application in Angular 6

I am trying to hit my Spring Boot APIs using Angular 6. I am sending some data as a part of headers like this
const headers = new HttpHeaders({
'X-TenantID': tenantId,
'Accept': 'application/json'
});
this.httpClient.get(this.constants.urls.TENANT.VALIDATE + '/' + tenantId, {headers: headers });
At the back end, I am using interceptor and there i am trying to get 'X-TenantID' from my request Headers like this
if (request.getHeader("X-TenantID") != null) {
String tenantName = request.getHeader("X-TenantID");
ThreadLocaleStorage.setTenant(tenantName);
return tenantName;
}
And unfortunately its always returning null value for 'X-TenantID'. When I tried to print all headers it giving me following response
host
localhost:8080
connection
keep-alive
access-control-request-method
GET
origin
http://localhost:4200
user-agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
dnt
1
access-control-request-headers
**x-tenantid**
accept
*/*
accept-encoding
gzip, deflate, br
accept-language
en-US,en;q=0.9
It's clear x-tenantid is present in headers but why I am not getting the value for it.
Please help me, how can I get this value from headers.

GetMapping "produces" works even though doesn't match accept header

Intro
There is a #GetMapping attribute, as the following in one of our projects:
#GetMapping(path = "/", produces = SaConstants.SA_MEDIA_TYPE)
public HttpEntity<Resource<Home>> get(HttpServletResponse response) {
In the SaConstants class:
public static final String SA_MEDIA_TYPE="application/sa+json";
When I access the page from any internet browser, I am getting the proper response that I want - and my breakpoint in the controller is being triggered.
The browser is sending the following headers:
Host: 127.0.0.1:8001
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: io=Qt74kp5V5ziUNIxlAAAG
When I make a request to the page, without an Accept header, the page is not working.
If I add to postman the following Accept header, everything works:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Question
My question are:
why does it work even if the Accept: header of the request doesn't match the produces attribute of the Rest Controller?
Why does it fail if no Accept header is provided (given the first question).
"*/*" means all types, this header is by default provided by most of the popular browsers

WebApi HttpPost not working with parameters

I have a Web Api project with this route config
var config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute(
"DefaultApiRoute",
"api/v1/{controller}/{action}");
I have two post method
[HttpPost]
public IHttpActionResult RetrieveTestNoParam()
{
return new JsonResult<string>("This is a test", new JsonSerializerSettings(), Encoding.UTF8, this);
}
[HttpPost]
public IHttpActionResult RetrieveTest(string input)
{
return new JsonResult<string>(input, new JsonSerializerSettings(), Encoding.UTF8, this);
}
The first one is working but the second one gives this respone
{
"Message": "No HTTP resource was found that matches the request URI 'http://test.dev.local/api/v1/NewsApi/RetrieveTest'.",
"MessageDetail": "No action was found on the controller 'NewsApiController' that matches the request."
}
This is what I see in fiddler
POST http://test.dev.local/api/v1/NewsApi/RetrieveTest HTTP/1.1
Host: test.dev.local
Connection: keep-alive
Content-Length: 261
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Type: application/javascript
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
Postman-Token: c2ba631b-4bfd-9379-bf40-0ca1a6a8a3bc
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,nl;q=0.6
Cookie: ASP.NET_SessionId=4kgfwd2u3pwusfdvdsrkt2vt; SC_ANALYTICS_GLOBAL_COOKIE=ddd9185a3e8940c9823e81b7d38cdf20|False; sc_expview=0
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa
Content-Disposition: form-data; name="input"
Dit is de input
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa
Content-Disposition: form-data; name="czczcsdcsdf"
sdfsfsdfsdff
------WebKitFormBoundaryxdYhzJ7A8WnI8qaa--
Any ideas?
Other questions I have about Web Api:
Can a controller contain multiple get or post methods?
Do I need the actionname attribute and what does this attribute do?
Regards
Danny

Why the Symfony form is "not submitted" after data is correctly sent through AJAX?

I want to sent a Symfony form through AJAX (AngularJS).
However, even if data is clearly sent, the form is said by Symfony to be "not submitted" (no error actually, but some debug show that isSubmitted returns false)
Here is a test on FOSUserBundle registration form.
EDIT: although pictures appear small, they are sufficiently resolved so that they are perfectly readable if displayed at their full size.
Here are the logs when I use a standard submission from an HTTP form:
Here are the logs when I use AJAX submission:
I have disabled CSRF token
The method I use from AJAX is "post" so it should be ok since it is the default Symfony expects (and FOSUserBundle does not override that default AFAIK).
Other forms (outside of FOSUserBundle scope) are correctly sent with AJAX
Would you have any idea on the matter? Any pointer? Or any other log I could check?
EDIT:
I use the default FOSUserBundle registration controller.
I almost use the default FOSUserBundle registration form, but I have added a (currently) empty child form which I'll need it further in the development.
namespace NONG\SecurityBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class UserRegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {}
public function getParent() {
return 'fos_user_registration';
}
public function getName() {
return 'nong_user_registration';
}
}
Headers and data sent with the HTML form (NB. added a dot before star in Accept so that the coloration stays correct):
POST /server/web/testfosuser/register/ HTTP/1.1
Host: mywebsite.com
Connection: keep-alive
Content-Length: 229
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/.*;q=0.8
Origin: http://mywebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://mywebsite.com/server/web/testfosuser/register/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxx
fos_user_registration_form%5Bemail%5D=bidon%40bidon.com&
fos_user_registration_form%5Busername%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bfirst%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bsecond%5D=bidon
Headers sent with the AJAX request: (NB. added a dot before star in Accept so that the coloration stays correct):
POST /server/web/testfosuser/register HTTP/1.1
Host: mywebsite.com
Connection: keep-alive
Content-Length: 229
Accept: application/json, text/plain, */.*
Origin: http://mywebsite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/json;charset=UTF-8 application/x-www-form-urlencoded; charset=UTF-8
Referer: http://mywebsite.com/client/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxx
fos_user_registration_form%5Bemail%5D=bidonqdsfqsdf%40qsdf&
fos_user_registration_form%5Busername%5D=charles222&
fos_user_registration_form%5BplainPassword%5D%5Bfirst%5D=bidon&
fos_user_registration_form%5BplainPassword%5D%5Bsecond%5D=bidon
I had similar problems and i changed the following inside of the controller:
$user = new User();
$form = $this->createForm(
new UserRegistrationType(),
$user,
array(
'attr' => array('novalidate' => 'novalidate'),
'action' => $this->generateUrl('user_registration')
)
);
Turning of the html5 error bubbles and setting the action URL directly worked for me. If this is not working, show your JS code.
I finally managed to find the correction:
The correct URL is ...../register/ with a final / that I forgot when I did the AJAX request.
However, I'm not sure what are the mechanisms at stake here. The deepest I could go debuging (when using the wrong URL) was in HttpFoundationRequestHandler, where the $request->getMethod() call returned GET (instead of POST), thus not submitting the form.

Action Script 3 - Posting a JSON to a RESTful server

I'm trying to POST a simple JSON object to a RESTfull server using the following code:
var messages:Array = new Array ();
messages.push ({"name":"MyName"});
var vars: URLVariables = new URLVariables();
vars.data = JSON.stringify(messages);
var urlRequest:URLRequest= new URLRequest("http://localhost:8080/xxx/player/createAccount");
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = vars;
var hdr:URLRequestHeader = new URLRequestHeader("Content-type", "application/json");
urlRequest.requestHeaders.push(hdr);
_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, onXMLDataLoaded);
_urlLoader.load(urlRequest);
My object is a simple one, it contains a field called {"name" : "MyName"}
The server fails to recognize the request's data.
the request on the network monitor shows this:
POST http://localhost:8080/xxx/player/createAccount HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 42
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:8080
X-Requested-With: ShockwaveFlash/15.0.0.223
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:8080/xxx/flashClient/lobby.swf
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,he;q=0.6
Cookie: JSESSIONID=1841C3CBE7511794A4EEF8A1A0BD56DD
data=%5B%7B%22name%22%3A%22MyName%22%7D%5D
A working post request looks like this on the network monitor tool:
POST http://localhost:8080/xxx/player/createAccount HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 20
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Origin: chrome-extension://cdjfedloinmbppobahmonnjigpmlajcd
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,he;q=0.6
Cookie: JSESSIONID=1841C3CBE7511794A4EEF8A1A0BD56DD
{ "name" : "MyName"}
Any ideas how can I make the first request perform like the second one?
If you're content type is application/json, then you don't want to use URLVariables for your data:
//this is causing the problem because it's encoding your JSON string so it's url safe.
var vars: URLVariables = new URLVariables();
vars.data = JSON.stringify(messages);
Instead, assign the stringified JSON directly to the URLRequest's data property like in the following example:
var urlRequest:URLRequest= new URLRequest("http://localhost:8080/xxx/player/createAccount");
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = JSON.stringify({"name":"MyName"});
var hdr:URLRequestHeader = new URLRequestHeader("Content-type", "application/json");
urlRequest.requestHeaders.push(hdr);
_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, onXMLDataLoaded);
_urlLoader.load(urlRequest);
P.S. There is a good tutorial that can help with understanding REST paradigm.

Resources