Ajax Web-Api optional parameter null issue. - asp.net-web-api

Ajax webapi when parameter is null or blank then 400 bad reuqsest occurs. solution needed asap.
http://{parenturl}/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10&BuildTypeName=
here BuildTypeName is optional parameter when there is not search parameter passed how to reduce 400 error.
//controller
public HttpResponseMessage GetBuildTypeList(int CurrPage, int PageSize, string BuildTypeName = "")
{
}
here issue with only BuildType.
help some one.
Regards

You need to change the way the request is made. Either complete your request string by adding ="" to the end, or leave out the BuildTypeName parameter when it is empty.
So you get either of these two cases:
/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10&BuildTypeName=""
/api/BuildTypeWebApi/GetBuildTypeList?CurrPage=1&PageSize=10
This way, Web API actually knows what you want to do with the BuildTypeName parameter. In your case it was an incomplete request.

Related

Attribute Routing - optional parameter not working?

According to http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#optionals-and-defaults
You can have optional parameters by adding a question mark (?) when using attribute routing. However it does not work for me (ASP.NET Web API 5).
[Route("staff/{featureID?}")]
public List<string> GetStaff(int? featureID) {
List<string> staff = null;
return staff;
}
If I use staff/1 etc it works fine, if I use /staff I get the usual:
"No HTTP resource was found that matches the request URI..."
"No action was found on the controller that matches
the request."
Am I missing a reference or something? Or doing it wrong?
I also ran into the same issue and solved it a little differently. However, it still didn't work for me as laid out in that blog post. Instead of adding the default parameter value in the route definition I added it to the function definition.
I had to do this to for my example to work properly because I was using a string instead of an int and adding the default in the route definition of null caused my function parameter to have the string value "null".
[Route("staff/{featureID?}")]
public List<string> GetStaff(int? featureID = null) {
List<string> staff = null;
return staff;
}
This is because you always have to set a default value for an optional parameter, even if the default is null. That is why this works:
[Route("staff/{featureID=null}")]
If I do:
[Route("staff/{featureID=null}")]
instead of
[Route("staff/{featureID?}")]
It works.
Technically this doesn't answer my question but it gets me working!

Spring MVC detect ajax request

How to detect an ajax request in the best possible way?
I'm currently using this in my controller:
private boolean isAjax(HttpServletRequest request){
String header = request.getHeader("x-requested-with");
if(header != null && header.equals("XMLHttpRequest"))
return true;
else
return false;
}
But I don't like this way, I think there should have a better solution with Spring.
That is the only "generic" way to detect an Ajax request.
But keep in mind: that's not failproof, it is just a best effort attempt, it is possible to make an Ajax request without sending the X-Requested-With headers.
jQuery usually includes that header. Maybe another lib doesn't. The protocol certainly doesn't consider that header mandatory.
Just a note: Your code is perfectly valid, though you could write it a bit simpler:
private boolean isAjax(HttpServletRequest request) {
String requestedWithHeader = request.getHeader("X-Requested-With");
return "XMLHttpRequest".equals(requestedWithHeader);
}
There is a simple bullet proof solution. Simply send query parameter like ajax=1 from your ajax request and send a different value or do not send this parameter for regular request and check in your controller and take action accordingly.

Web API 2 attribute routing returning 404

I'm having trouble getting the Web API 2 attribute routing to work.
I've been trying everything I could find this whole evening but I can't find the problem.
What I want to achieve is the following:
Make a POST request to http://localhost:xxxx/api/chat/joingroup/1234 to get to the following API call:
[Route("joingroup/{id}")]
[HttpPost]
public async Task<IHttpActionResult> JoinGroup(string id, string connectionID)
{
await hubContext.Groups.Add(connectionID, id);
return Ok(hubContext.Groups.ToString());
}
This keeps getting me a http 400 message.
{"message":"No HTTP resource was found that matches the request URI 'http://localhost:41021/api/chat/joingroup/123'.",
"messageDetail":"No action was found on the controller 'Chat' that matches the request."}
But sending a post to: http://localhost:41021/api/chat/sendmessage/pm/123123 and also to http://localhost:41021/api/chat/joingroup gives me a 200
The chatcontroller:
[RoutePrefix("api/chat")]
public class ChatController : ApiController
{
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
[...]
[Route("joingroup/{id}")]
[HttpPost]
public async Task<IHttpActionResult> JoinGroup(string id, string connectionID)
{
await hubContext.Groups.Add(connectionID, id);
return Ok(hubContext.Groups.ToString());
}
HTTP POSTS to http://localhost:xxxx/api/chat/sendmessage are working fine.
I cannot figure out why it isn't going to the correct method when I'm calling a POST on http://localhost:xxxx/api/chat/joingroup/1234.
SOLUTION:
The solution was to reference both values that are needed in the JoinGroup method, id and connectionID. Now the request will hit this method.
Using:
http://localhost:xxxx/api/chat/joingroup/john?connectionid=123 will work.
I noticed two things on the code you sent through:
the path you POST to is: localhost:xxxx/joingroup/1234 , this
should be localhost:xxxx/api/chat/joingroup/1234
because you have 2 parameters for the joingroup, you will need to pass both of them through, may be like this localhost:xxxx/api/chat/joingroup/1234?connectionID=value or you can pass it on the request body
if the connectionID is optional you can modify the method to use option al parameters like this
public string JoinGroup(string id, string connectionID = "")
please let me know if this helps.
Thanks
Ashraf
I assume the connectionID parameter references the POSTed data. The easiest thing to make it work is to decorate it with the [FromBody] attribute and put an = in front of the value being sent like this: =MyConnection1.
Web API expects an object with properties or an array otherwise. Alternatively, you can wrap the connection ID with a custom class and pass it serialized as JSON/XML.

QueryString truncated in WebAPI RequestBody when request is manually composed?

I've confirmed I have the dropdown set to post and the URL is correct, because the string gets passed into my Web API project without error. However it is cutting everything off of the string after the first parameter
Request Headers:
User-Agent: Fiddler
Host: localhost:52888
Content-Length: 35
Content-Type: application/x-www-form-urlencoded
Request Body:
=name=TestName&date=10/15/2014
In the Web API project the only part that is passed is name=Test Name
I'm confident the query string is in the right format. I'm wondering if anyone else can point me in the direction of what I might be missing.
If I remove the = in front of the request body then nothing is received
A signature like AddCourse([FromBody] string courseRequest) tells WebAPI to look for a POST parameter named courseRequest. But (when it is properly formatted) your request body doesn't have that parameter - instead it has name and date. When you misformat the request body by prepending an = character, it apparently causes the parser to decide that name=test is the value. But the second part of the query string is after an &, and is clearly a different parameter. It has nowhere to bind that parameter, so it just gets dropped.
There are at least two solutions here. One would be to pass the parameters on the query string instead of in the request body, and use a method signature like: AddCourse(string name, string date) (note removed of [FromBody]).
Another would be to create a model object that encapsulates the request, something like
public class AddCourseModel{
public string Name {get;set;}
public string Date {get;set;}
}
and use that as the argument to your method: AddCourse([FromBody] AddCourseModel model).

Web API: Make action parameter mandatory

I have an action that looks thus:
[HttpPost]
public HttpResponseMessage PostInstantiation(Guid id, [FromBody]Instantiation instantiation)
If the user does a POST to the correct URL, but with no (/empty) body, then model validation doesn't fail, and the instantiation argument is null. I expected it to fail.
What is the correct way of handling this scenario?
What you are noticing is an expected behavior. If you indeed would like to check if the user has sent an empty body, then you could probably check for the Content-Length header of the incoming request.
if(Request.Content.Headers.ContentLength == 0)

Resources