Http failure response for http://localhost:5000/api/users/siteUsers/[object%20Object],[object%20Object],[object%20Object]: 400 Bad Request - asp.net-core-webapi

I am trying to add a multi-select dropdown in angular 11 and .netcore 3.1 web api.
when i submit the dropdown, errors occur like this.
"Http failure response for http://localhost:5000/api/users/siteUsers/[object%20Object],[object%20Object],[object%20Object]: 400 Bad Request"
backend
[Route("siteUsers/{id}")]
How can i pass the from frontend the data.
Edit:
Angular service.ts file
CreateSiteUsersAsync(data: FormData, id: number) {
return this.http.post(`${this.baseUrl}/${this.basePath}/siteUsers/${id}`, data);
}
.ts file
async onSubmitHandler() {
const data = { ...this.userForm.value};
await this.userService.CreateSiteUsersAsync(data,data.siteCode).toPromise();
}

A few things that is wrong with your function.
First Route is being specified, but the not the Http method. Meaning the default method is Get. You cannot pass form data to a Get method. It should be, Postor Put. So first thing is add a http method:
[Route("siteUsers/{id}")]
[HttpPost]
or more elegantly:
[HttpPost("siteUsers/{id}")]
Next is the receival attributes where you get the data from. There are four options [FromRoute], [FromForm], [FromQuery] and [FromBody].
By default C# uses [FromQuery]. So for both the id and the data you will need to specify where you search this data. See code below:
[HttpPost("siteUsers/{id}")]
public IActionResult MyEndpoint([FromRoute] id, [FromForm] data)
{
...
return Ok();
}
You can also use [FromBody] instead of the [FromForm] tag since technically both are are from the body.

Related

razor named handler and BindProperty

I am trying to send an ajax post request to a razor page. This razor page has some public properties with [BindProperty]. For the ajax request I am trying to use a named handler.
#page "{title}"
[BindProperty]
public BookViewModel BookModel { get; set; }
public IActionResult OnPostMarkdownInput(string title)
{
return new EmptyResult();
}
On the client side, sending empty data (+ /title) ends in a BadRequest. But sending it with the form that binds BookModel works. My suspicion was therefore that [BindProperty] requires this property to be bound even for the namedHandler. But the problem persisted even after removing it.
How can I add a namedHandler that does not require any properties to be bound? Or why do I get a BadRequest when no data is sent?
Thanks!
A Bad Request response from an AJAX-initiated request in Razor Pages is usually the symptom of a missing Request Verification token, which you need to include either as a form value or a header depending on the type of request you are making. If you are posting JSON, you need to add a header:
$.ajax({
type: "POST",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
url: "/yourformhandler",
...
Otherwise you just need to ensure that the hidden field is included in the posted values.
See more about Request Verification here: https://www.learnrazorpages.com/security/request-verification

Issue with RedirectAction

I have a FormController with Index action and SimpleController with CorticonIndex action.
I am redirecting to CorticonIndex from Index action. My problem is, I have put a breakpoint at return RedirectToAction() and CorticonIndex().
So,Only for the first time I can see the execution by F11 but for the second time controller is not going to CorticonIndex().
How the RedirectToAction() will work?
Is it only one time execution or can we execute multiple time??
FormController
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
return RedirectToAction("CorticonIndex", " SimpleController");
}
SimpleController
public ActionResult CorticonIndex()
{
var viewModel = this.Model.GetViewModel(payLoad);
return View(CorticonResponseModel.viewName, viewModel);
}
How the RedirectToAction() will work?
It sends an HTTP 302 response to the browser of the web site along with a Location header. What the browser does with that is up to the browser. Normally, it will use the Location header to submit another request to your server. But, as this is entirely out of the application's control, there are no guarantees.
But in this case you are initially calling the server using an HTTP POST. If your browser reloads the page using an HTTP GET, it will not hit this same action method. If you have an HTTP GET action method named Index, it will call that one instead.
NOTE: FYI - if you remove the HttpPost attribute, your action method will respond to both GET and POST. But that is probably not the solution to your issue, as it is normal to have a separate action method in each case.

Spring MVC binding request parameters

I wrote a spring-mvc controller method to get an array of values in the request parameter.The method looks like below
/**
Trying to get the value for request param foo which passes multiple values
**/
#RequestMapping(method=RequestMethod.GET)
public void performActionXX(HttpServletRequest request,
HttpServletResponse response,
#RequestParam("foo") String[] foo) {
......
......
}
The above method works fine when the request url is in below format
...?foo=1234&foo=0987&foo=5674.
However when the request url is in below format the server returns 400 error
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
Any idea how to fix the method to cater to the second format request url?
This is not possible with #RequestParam. What you can do is implement and register your own HandlerMethodArgumentResolver to perform to resolve request parameters like
...?foo[0]=1234&foo[1]=0987&foo[2]=5674
into an array. You can always checkout the code of RequestParamMethodArgumentResolver to see how Spring does it.
Note that I recommend you change how the client creates the URL.
The server is supposed to define an API and the client is meant to follow it, that's why we have the 400 Bad Request status code.
I resolved this issue using the request.getParameterMap().Below is code.
Map<String,String> parameterMap= request.getParameterMap();
for(String key :parameterMap.keySet()){
if(key.startsWith("nameEntry")){
nameEntryLst.add(request.getParameter(key));
}
}

Does JSON always have to match a POJO/Bean and vice versa in spring-mvc Rest?

Every time I call my REST API sending a JSON through PUT, for instance, and there is some different property on it, I got 400 (Bad Request) as a result.
Is there any way to configure spring-mvc to ignore no existent properties when JSON and my Class do not perfectly match?
Here is a sample of a method on my controller:
======
#Transactional
#RequestMapping(method=RequestMethod.PUT, value="/include",
consumes=MediaType.APPLICATION_JSON_VALUE,
produces={MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE })
public #ResponseBody ResponseEntity<Client>
inserirClienteSemRedeSocial(#RequestBody Client client) {
clientDAO.insert(client);
return new ResponseEntity<Client>(client, HttpStatus.OK);
}
you can add to your Pojo:
#JsonIgnoreProperties(ignoreUnknown=true)
which will ignore unknown fields
javadoc

ASP.NET Web API removing HttpError from responses

I'm building RESTful service using Microsoft ASP.NET Web API.
My problem concerns HttpErrors that Web API throws back to user when something go wrong (e.g. 400 Bad Request or 404 Not Found).
The problem is, that I don't want to get serialized HttpError in response content, as it sometimes provides too much information, therefore it violates OWASP security rules, for example:
Request:
http://localhost/Service/api/something/555555555555555555555555555555555555555555555555555555555555555555555
As a response, I get 400 of course, but with following content information:
{
"$id": "1",
"Message": "The request is invalid.",
"MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'MyNamespaceAndMethodHere(Int32)' in 'Service.Controllers.MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}
Something like this not only indicates that my WebService is based on ASP.NET WebAPI technology (which isn't that bad), but also it gives some information about my namespaces, method names, parameters, etc.
I tried to set IncludeErrorDetailPolicy in Global.asax
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
Yeah, that did somehow good, now the result doesn't contain MessageDetail section, but still, I don't want to get this HttpError at all.
I also built my custom DelegatingHandler, but it also affects 400s and 404s that I myself generate in controllers, which I don't want to happen.
My question is:
Is there any convinient way to get rid of serialized HttpError from response content? All I want user to get back for his bad requests is response code.
What about using a custom IHttpActionInvoker ?
Basically, you just have to send an empty HttpResponseMessage.
Here is a very basic example :
public class MyApiControllerActionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
var result = base.InvokeActionAsync(actionContext, cancellationToken);
if (result.Exception != null)
{
//Log critical error
Debug.WriteLine("unhandled Exception ");
return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));
}
else if (result.Result.StatusCode!= HttpStatusCode.OK)
{
//Log critical error
Debug.WriteLine("invalid response status");
return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(result.Result.StatusCode));
}
return result;
}
}
In Global.asax
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker());
One other important thing you could do, not related to Web Api, is to remove excessive asp.net & IIS HTTP headers. Here is a good explanation.
I believe your approach of using the message handler is correct because regardless of the component in the Web API pipeline that sets the status code to 4xx, message handler can clear out response body. However, you do want to differentiate between the ones you explicitly set versus the ones set by the other components. Here is my suggestion and I admit it is a bit hacky. If you don't get any other better solution, give this a try.
In your ApiController classes, when you throw a HttpResponseException, set a flag in request properties, like so.
Request.Properties["myexception"] = true;
throw new HttpResponseException(...);
In the message handler, check for the property and do not clear the response body, if the property is set.
var response = await base.SendAsync(request, cancellationToken);
if((int)response.StatusCode > 399 && !request.Properties.Any(p => p.Key == "myException"))
response.Content = null;
return response;
You can package this a bit nicely by adding an extension method to HttpRequestMessage so that neither the ApiController nor the message handler knows anything about the hard-coded string "myException" that I use above.

Resources