web api calls routing to wrong method - asp.net

I have a webapi controller which goes against the default webapi convention to expose a few different "get" methods
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Manufacturer[] GetManufacturers()
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetManufacturers"))
{
return IvService.GetManufacturers();
}
}
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Range[] GetRanges(string manufacturer_code)
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetRanges"))
{
return IvService.GetRanges(manufacturerCode);
}
}
They are very simple methods which are called from Javascript and make another call out to an external system via WCF, then return the result. This has been working fine on dev for a while but recently stopped working- both calls from javascript to GetManufacturers and GetRanges now hit the same break point in GetManufacturers. I checked fiddler and its definitely calling the correct url.

Some refactoring had taken place to enforce some coding standards to do with parameter names and the call from javascript had been adjusted to from
VehicleController/GetRanges?manufacturer_code=AB
to
VehicleController/GetRanges?manufacturerCode=AB
without adjusting the corresponding webapi method. At first I had suspected this was some weird routing issue but it turns out because the parameters names no longer contained anything it recognized, it resolved to the only method which didn't required any parameters, which makes sense but kept me scratching my head for a little while!

Related

ASP.NET return Http Response from function called outside controller

I just started working with asp.net mvc and am working on a legacy codebase with controllers that all have the same validation code at the front of every controller. (ie. multiple lines of the exact same code returning if the user id/key are not correct)
Is there any way to separate this out into an external function that can return an HTTP response immediately if validation fails?
Right now I can do something like this:
if (!validate()) {
return forbid("Your un or Password is incorrect");
}
or for a more specific message:
var errorMsg = validate();
if (errorMsg) {
return forbid(errorMsg);
}
but if I'm going to put this at the front of most of my controllers, I'd rather have a one-liner that I takes up as little room as possible. Is there an option for bypassing the rest of the controller function and returning an HTTP response from inside my validate() function? Or is there possibly a more appropriate way to do this?

ASP.NET Web API - method that is called for all requests prior to the routed method?

I'm writing in C# for ASP.NET Web API 2. What I want is a catch-all method that will execute for every single request that comes to my Web API.
If the method returns null, then the original routing should continue, seeking out the correct method. However, if the method returns, say, an HTTPResponseMessage, the server should return that response and not proceed on to normal routing.
The use case would be the ability to handle various scenarios that may impact the entire API. For example: ban a single IP address, block (or whitelist) certain user agents, deal with API call counting (e.g. someone can only make X requests to any API method in Y minutes).
The only way I can imagine to do this right now is to literally include a method call in each and every new method I write for my API. For example,
[HttpGet]
public HttpResponseMessage myNewMethod()
{
// I want to avoid having to do this in every single method.
var check = methodThatEitherReturnsResponseOrNull(Request);
if (check != null) return (HttpResponseMessage)check;
// The method returned null so we go ahead with normal processing.
...
}
Is there some way to accomplish this in routing?
This is what Action Filters are for. These are Attributes that you can place either globally, at the class (Controller), or at the method (Action) levels. These attributes can do preprocessing where you execute some code before your action executes or post processing where you execute code after the action executes.
When using pre processing you have the option to return a result to the caller and not have your method (action) be fired at all. This is good for model validation, authorization checks, etc.
To register a filter globally edit the WebApiConfig.cs file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new YourFilterAttribute()); // add record
// rest of code
}
}
To create a custom attribute inherit from System.Web.Http.Filters.ActionFilterAttribute or you can implement interface System.Web.Http.Filters.IActionFilter or you can implement IAuthorizationFilter/AuthorizationFilterAttribute if you specifically want to allow/deny a request.
It also sounds like you want to create multiple attributes, one for each role like IP filtering or count calling etc. That way it would be more modular instead of one enormous authorization filter.
There are many tutorials out there like this one (chosen at random in my Google search results). I am not going to post code because you did not do so either so I would just be guessing as to what you wanted to do.

dojo ajax call using xhr post and json

I am not able to post a dojo form via xhr call of dojo 1.8 but its happening through deprecated method dojo.xhrPost. Please see the code fragment that I used.
This is portion from jsp for dojo ajax call
require(["dojo/request/xhr"],function(xhr){
xhr('http://localhost:8080/myApp/call',{
data: 'callerName',
method:"POST",
load: function(data, ioargs) {
alert("The message is: " + ioargs.xhr.status);
},
error: function(error){
alert("Returned: " + error);
}
});
});
<form data-dojo-type="dijit/form/Form" name="callerName" id="callerName">
...here are dojo input types
</form>
Below is spring controller
#RequestMapping(value="/call",method=RequestMethod.POST)
public ModelAndView saveData3(HttpServletRequest req, #ModelAttribute Caller caller){}
Here I am not getting the values from form to caller model attribute. but the call is happening.
Instead of this ajax call if I go for deprecated call a below, the values are getting bound.
dojo.xhrPost({
url: 'http://localhost:8080/myApp/call',
form: 'callerName',
load: function(response) {
}
for latest call in 1.8 instead of argument 'data', I tried with 'form' still not happening. What can be this issue?
Dojo has deprecated the load and error callback attributes in favor of deferreds/promises.
Sample of new code with deferreds code below old code with callbacks.
Another sample.
I thought Dojo would maintain backwards compatibility until 2.0, but perhaps it was dropped (ah.. perhaps 1.8 supports the old syntax if you require the old dojo/_base/xhr).
Also, note it is better to require dojo/request instead of dojo/request/xhr directly.
update: Why dojo/request is preferred over dojo/request/xhr:
dojo/request is a higher level abstraction than dojo/request/xhr. So it is:
more portable: dojo/request automatically selects the proper provider and works in both the client and server. dojo/request/xhr will not work on the server (node.js) and dojo/request/node will not work on the client (browser).
more flexible. In the future, perhaps a better provider will be added. dojo/request can use the best provider without any changes to your code. Also, providers can be configured based on the URL. An example use case would be using dojo/request/xhr for same domain requests and dojo/request/script for cross domain requests.
sources:
kitsonk, core Dojo contributor
dojo/request/registry documentation
dojo/request documentation

How do I get the parameter values from in a web service

I have a web service (an ASP.NET .asmx page), and for debugging purposes I need to log all calls to the webservice, including values of all parameters passed into each call. So basically the first thing each WebMethod should do is log it's state with details of all the parameter values passed in to it.
So far so good. The complication is that I also want an automated way of getting the parameter values - there's quite a few webmethods with different signatures, and some of them have up to ~30 parameters, so manually coding against each specific parameter would likely be massively error-prone. I'd rather be able to call a method that looks at the current Http context and automatically uses that to grab and parse whatever has been passed in by the client.
But I hit a snag. When I look at HttpContext.Current.Request, it turns out that both the Form and QueryString collections are empty. So if the arguments passed to the webmethod aren't in either of those collections, where would they be? Anyone know how I can retrieve them?
You can use AOP techniques for this task. Considering PostSharp, you can create custom aspect like this:
[Serializable]
public class TraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Trace.WriteLine(string.Format("Entering {0}", args.Method.Name));
for (int i = 0; i < args.Arguments.Count; i++)
{
Trace.WriteLine(string.Format(" {0}", args.Arguments.GetArgument(i)));
}
}
}
and then apply it to your web-service methods:
[WebMethod, Trace]
public string HelloWorld()
{
return "Hello World";
}
You could use SOAP extensions and follow the example in this post to log the request which would have the method name and parameters.
SOAP Extentions is a better choice. Here is another example to retreive SOAP request and SOAP response as XML. All you do is parse the XML to retreive parameter name value pairs.

How to unit test for turning off request validation?

I'm new at this TDD thing but making a serious effort, so I'm hoping to get some feedback here.
I created a little web service to minify JavaScript, and everything was nice, with all my tests passing. Then I noticed a bug: if I tried to minify alert('<script>');, it would throw a HttpRequestValidationException.
So that's easy enough to fix. I'll just add [AllowHtml] to my controller. But what would be a good way to unit test that this doesn't happen in the future?
The following was my first thought:
[TestMethod]
public void Minify_DoesntChokeOnHtml()
{
try
{
using (var controller = ServiceLocator.Current.GetInstance<MinifyController>())
{
return controller.Minify("alert('<script></script>');");
}
}
catch (HttpRequestValidationException)
{
Assert.Fail("Request validation prevented HTML from existing inside the JavaScript.");
}
}
However, this doesn't work since I am just getting a controller instance and running methods on it, instead of firing up the whole ASP.NET pipeline.
What would be a good unit test for this? Maybe reflector on the controller method to see if the [AllowHtml] attribute is present? That seems very structural, and unlikely to survive a refactoring; something functional might make more sense. Any ideas?
You have only two options:
First
Write integration test that hosts MVC in-proc or runs using browser (using Watin for instance) that will cover you scenario.
Second
Write unit test that will check that method is marked with needed attribute.
I would go with the first option.

Resources