Attribute Routing changes WebAPI pipeline - asp.net-web-api

I've got a .NET WebApi solution. I'm constraining access to HTTPS but conditionally allowing HTTP traffic. One of the conditions is that all HTTP requests must use the HTTP POST method, passing the x-http-method-override header to supply the intended method so the request can be properly routed. I've configured a global DelegatingHandler to validate all incoming requests and perform the redirection if needed.
With standard routing everything works great. When I configure AttributeRouting things go off the rails. It appears that AttributeRouting attempts to locate the route before the DelegatingHandler modifies the request, resulting in improper routes or IIS 404 errors. Is there a way to intercept the route before the AttributeRouting handler resolves the route?
More info: The project is hosted on IIS (not self hosted). The AttributeRouting I'm using is what comes in WebApi 2.0. The DelegatingHandler is defined thusly in App_Start:
GlobalConfiguration.Configuration.MessageHandlers
.Add(new MyCustomDelegateHandler());
AttributeRouting is configured simply using:
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
The routes are defined using the attributes:
[HttpGet("api/test/v1/users")]

Couple of question for clarity...Is this a Selfhost or Webhost(IIS) scenario? By AttributeRouting you mean the built-in Web API 2 attribute routing and not TimMcCall's attribute routing nuget package...right?
There have always been differences between when route matching occurs between Selfhost and Webhost. In Selfhost, route matching happens after message handlers are run, where as in case of Webhost route matching happens before message handlers are run.
If your scenario is Webhost, then I would expect the behavior to not change...but if your are seeing different behavior, then can you share how your route configuration (WebApiConfig.cs & the attributed controller/action) look like?
In Webhost, to intercept requests before route matching happens, you could create a Owin middleware which sits before the request is received by Web API. In this middleware you can modify the request details as you need.
NOTE:
Based on the update "More Info" in the post above, pre-RTM bits were being used where this seems to be an issue and this is not longer a problem with the final RTM bits.

Related

ColdFusion not handles HTTP OPTIONS requests for CFC

Scenario:
A webserver which hosts a frontend application based on ExtJS.
A ColdFusion 10 server (with Apache) that hosts backend services.
Frontend application make AJAX requests to ColdFusion components (CFC) with form http://<CF_server>/<app_path>/<CFC>?method=someMethod&...
CFC responds with JSON.
Since frontend and backend are on different servers we are in a CORS (Cross-Origin Resource Sharing) environment and AJAX requests making two http requests to backend: first is an OPTIONS method for handshake and second is a POST request. I have need enabling headers in Apache on CF server and using "Header set Access-Control-Allow-Origin: *" directive for enabling CORS, but I would like handling headers programmatically from CF not Apache. I have run some test and I noticed that OPTIONS method in http request works only with CFM and not with CFC, so the first AJAX request (with OPTIONS method) fails. I can bypass OPTIONS request in AJAX call setting useDefaultXhrHeader properties, but I would understand CF behavior.
After running tests with cfhttp tag I have found that:
HTTP request with OPTIONS method to CFM are similar to GET method: triggers events method on Application.cfc (orRequestStart, ...), returns filecontent and headers.
HTTP request with OPTIONS method to CFC don't triggers events, don't return filecontent nor headers.
A call (with OPTSIONS method) to unexistants CFC return same result.
Why CF not handle OPTIONS method when calling CFC?
In my tests i have bypassed Apache using integrated CF webserver on port 8500. I have also tried on CF9 with same results. Railo, instead, has a different behavior: handles OPTIONS method also for CFC.
This is similar as this thread without response: http://www.houseoffusion.com/groups/cf-talk/thread.cfm/threadid:59715
Thanks.
I've run into the same kind of issue with both CF and Apache CXF recently.
It seems CF has no defined behavior for verbs other that GET and POST. In my case, I installed the CORS filter here: http://software.dzhuvinov.com/cors-filter-installation.html
That intercepts the requests and handles them before they make it as far as your app. It worked for CXF and should work for CF, but the downside is that it requires a change to your web.xml, which may not be allowed in certain hosting setups.
The other option is to configure apache to add the necessary headers: http://enable-cors.org/server_apache.html
I also found a number of differences between browser vendors in when they use an OPTIONS call. I can't remember the specifics, but test early cross-browser if that's an eventual requirement.

Backbone Collection.fetch() when after session timeout

I have an ASP.NET MVC4 sub web application added in to an existing ASP.NET WebForm web site. the whole website is using forms authentication.
In my MVC4 client side, I use Backbone.js for building the application, and the client application is most likely a SPA.
Everything works fine, but after session timeout my application does not redirect to log-in page.
I tried the error callback on Collection.fetch method, it was triggered (which is good) when trying to fetch after session time out.
However, the response status code is 200 (OK) with response content is the log-in page content.
So, my question is, in error handler how do I know whether the callback is triggered by session timeout or any other unexpected error?
If determined, how should I do to let Backbone redirect page to log-in page while referring current page?
Here is something what Phil Haack had blogged about
Exceprts from the post :
Possible Solutions
I’m going to cover a few possible solutions I’ve seen around the web and then present the one that I prefer. It’s not that these other solutions are wrong, but they are only correct in some cases.
Remove Forms Authentication
If you don’t need FormsAuth, one simple solution is to remove the forms authentication module as this post suggests. This is a great solution if you’re sole purpose is to use ASP.NET to host a Web API service and you don’t need forms authentication. But it’s not a great solution if your app is both a web application and a web service.
Register an HttpModule to convert Redirects to 401
This blog post suggests registering an HTTP Module that converts any 302 request to a 401. There are two problems with this approach. The first is that it breaks the case where the redirect is legitimate and not the result of FormsAuth. The second is that it requires manual configuration of an HttpModule.
Install-Package MembershipService.Mvc
My colleague, Steve Sanderson, has an even better approach with his MembershipService.Mvc and MembershipService.WebForms NuGet packages. These packages expose ASP.NET Membership as a service that you can call from multiple devices.
Some more info from comment of this blog
We had the same problem. But what we did, was to hook to AuthenticateRequest (just like you did) and we also checked the request to see if it's ajax or not (again, just like what you did). But at this point, we simply returned a JSON like {location: 'http://www.domain.com/path-to-login-page'} and we simply ended response in that method with HTTP code 200. This way, jQuery still gets a JSON result. But if the result has a "location" property, we simply do a client-side redirect to login page. That's our way and it works like a charm.

Is server-side validation an appropriate use of ASP.NET WebAPI ApiController action

Before WebAPI, I did all client-side remote validation calls using regular MVC action methods. With WebAPI, I can now have POST, PUT, DELETE, and GET methods on an ApiController. However, validation still needs to happen.
I have successfully been able to put remote validation action methods on an ApiController and get them to work. Before submitting a POST, PUT, or DELETE for a resource, the client can POST to one or more validation URL's to validate user input and receive appropriate validation messages.
My question is, should these remote validation actions be on an ApiController? Or a regular MVC controller? It seems to me having them all in the ApiController makes the most sense, because that class can then encapsulate everything having to do with resource (and resource collection) mutations.
Update: reply #tugberk
I should elaborate. First, we are not using DataAnnotations validation. There are already rich validation rules and messages configured on the domain layer commands using FluentValidation.NET. Many of the validation classes use dependency injection to call into the database (to validate uniqueness for example). FluentValidation has good pluggability with MVC ModelState, but I have not found a good way to plug it into WebAPI ModelState yet.
Second, we are doing validation at the POST, PUT, and DELETE endpoints. Clients do not need to know the validation endpoints in order to discover what went wrong. Here is an example:
var command = Mapper.Map<CreateCarCommand>(carApiModel);
try
{
_createHandler.Handle(command);
}
catch (ValidationException ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
}
Clients will get a 400 response along with a message indicating what went wrong. Granted, this is not as granular as the response in the example you linked to. Because we are just returning a string, there is no easy way to parse out which fields each validation message belongs to, which is needed for our own HTML + javascript client of the API. This is why I spiked out adding more granular validation endpoints (as a side note, they are consumed by field-specific knockout-validation calls on our javascript client).
I am assuming that you are referring to something similar to ASP.NET MVC Remote Validation by saying remote validation. In that case, I don't think that your HTTP API needs a remote validation. Think about a scenario where I need to consume your HTTP API with my .NET application and assume that you have a remote validation. Two things bother me here:
That remote validation is not discoverable unless you are providing a .NET client for your API by yourself and put that logic inside that client.
Assuming that the remote validation is there for the .NET client and the application will make a validation call to the server before sending the actual request, this is just a overkill.
In my opinion, the user send a request to your API and you should make the validation there. You can find a sample from the following URL:
ASP.NET Web API and Handling ModelState Validation

Calculating the URL for a SOAP service call?

Given a SOAP service at a Uri http://www.example.com/index.php/api/v2_soap?wsdl=1 (Magento in this case)
How can I work out what URL is called when a particular method sales_order_invoice.list is invoked?
The reason for this question is that I need to be find out if the sites rewrite rules are interfering with the method call by rewriting the uri.
Is the uri one of:
http://www.example.com/index.php/api/v2_soap/sales_order_invoice.list
http://www.example.com/index.php/api/sales_order_invoice.list
http://www.example.com/index.php/sales_order_invoice.list
http://www.example.com/sales_order_invoice.list
Or something else entirely?
It's something else entirely. The API interface you're describing is a RESTful one. Different URLs for different resources. A SOAP API (Magento's or otherwise) doesn't work like that. All API requests go through
http://www.example.com/index.php/api/v2_soap?wsdl=1
The SOAP client will POST specifically formatted XML through the above endpoint URL, which will tell the the SOAP server which method needs to be called, and with what arguments.

Are there any MVC web frameworks that support multiple request types?

In every MVC framework I've tried (Rails, Merb, Waves, Spring, and Struts), the idea of a Request (and Response) is tied to the HTTP notion of a Request. That is, even if there is an AbstractRequest that is a superclass of Request, the AbstractRequest has things like headers, request method (GET, POST, etc.), and all of the other things tied to HTTP.
I'd like to support a request-response cycle over SMS, Twitter, email, or any other medium for which I can make an adapter. Is there a framework that does this particularly well?
The only other option I've thought of is creating, for example, a Twitter poller that runs in a separate thread and translates messages into local HTTP requests, then sends the responses back out.
If there were a good framework for multiple request media, what would routing look like? In Rails, the HTTP routing looks something like:
map.connect 'some/path/with/:parameter_1/:paramter_2', :controller => 'foo', :action => 'bar'
How would a Twitter or SMS route look? Regular expressions to match keywords and parameters?
I haven't seen one. The issue is that the request is also tied to the host, and the response is tied to the request.
So if you get a request in via email, and a controller says to render view "aboutus", you'd need the MVC framework to know how to :
get the request in the first place - the MVC framework would almost need to be a host (IIS doesn't get notified on new emails, so how does your email polling code get fired?)
allow flexible route matching - matching by path/url wouldn't work for all, so request-specific controller routing would be needed
use the aboutus email view rather than the SMS or HTTP view named "aboutus"
send the response out via email, to the correct recipient
A web MVC framework isn't going to cut it - you'll need a MVC "host" that can handle activation through web, sms, email, whatever.
The Java Servlet specification was designed for Servlets to be protocol neutral, and to be extended in a protocol-specific way - HttpServlet being a protocol-specific Servlet extension. I always imagined that Sun, or other third poarty framework providers, would come up with other protocol-specific extensions like FtpServlet or MailServlet, or in this case SmsServlet and TwitterServlet.
Instead what has happened is that people either completely bypassed the Servlet framework, or have built their protocols on top of HTTP.
Of course, if you want to implement a protocol-specific extension for your required protocols, you would have to develop the whole stack - request object, response object, a mechanism of identifying sessions (for example using the MSISDN in an SMS instead of cookies), a templating and rendering framework (equivalent of JSP) - and then build an MVC framework on top of it.
You seem to be working mostly with Java and/or Ruby, so forgive me that this answer is based on Perl :-).
I'm very fond of the Catalyst MVC Framework (http://www.catalystframework.org/). It delegates the actual mapping of requests (in the general, generic sense) to code via engines. Granted, all the engine classes are currently based on HTTP, but I have toyed with the idea of trying to write an engine class that wasn't based on HTTP (or was perhaps tied to something like Twitter, but was separated from the HTTP interactions that Twitter uses). At the very least, I'm convinced it can be done, even if I haven't gotten around to trying it yet.
You could implement a REST-based Adapter over your website, which replaces the templates and redirects according to the input parameters.
All requestes coming in on api.yourhost.com will be handled by the REST based adapter.
This adapter would allow to call your website programmatically and have the result in a parseable format.
Practically this means: It replaces the Templates with an own Template Engine, on which this things happen:
instead of the assigned template, a generic xml/json template is called, which just outputs a xml that contains all template vars
then you can make your Twitter Poller, SMS Gateway or even call it from Javascript.

Resources