Extending Asp.Net MVC routing mechanism - asp.net-mvc

I've found a limitation in the routing mechanism for ASP.Net mvc and I'm trying to find a workaround.
I posted a related question here about the issue I was having.
The gist of the problem is that routes that end with a . (period) are never handled by the default routing mechanism. A "Resource Cannot Be Found" error is always thrown. For example it cannot handle these urls:
http://www.wikipediamaze.com/wiki/Washington,_D.C.
http://www.wikipediamaze.com/wiki/anythingendinglikethis.
if I change it to querystring parameter like this it works fine:
http://www.wikipediamaze.com/wiki/?topic=Washington,_D.C.
I'm trying to find an extensibility point in the routing mechanism that will help me resolve this issue. I've tried other solutions like this:
//Global.asax.cs
protected void Application_Error()
{
var url = HttpContext.Current.Request.RawUrl;
if(TopicRegex.IsMatch(url))
{
var fixedUrl = FixUrlPath(url);
//This throws an error
Response.Redirect(fixedUrl);
//This also throws an error
Server.Transfer(fixedUrl );
}
}
I'm guessing that the Response.Redirect and Server.Transfer throw errors because in MVC you should be calling the RedirectToAction methods from the controller. Of course I can't even get to the controller.
This seems to be a pretty big limitation considering the Apache server that Wikipedia uses handles this just fine. try it out http://en.wikipedia.org/wiki/Washington,_D.C. If anyone could please offer some help here I would appreciate it.

Could you turn of checking file exists in the routes but allow certain extensions through?
routes.RouteExistingFiles = true;
// Ignore the assets directory which contains images, js, css & html
routes.IgnoreRoute("Assets/{*pathInfo}");
// Ignore text, html, files.
routes.IgnoreRoute("{file}.txt");
routes.IgnoreRoute("{file}.htm");
routes.IgnoreRoute("{file}.html");
routes.IgnoreRoute("{file}.aspx");

Related

Generic URLMapping in Grails for all 4xx or 5xx Errors

I am using Grails 2.4.4 and would like to define a generic UrlMapping for a range of HTTP-error-codes (like 450-499, 510-540).
I've found some related questions - even on SO - but the answers are either outdated or not working.
The container does not start once I use regular expressions on error-mappings.
For instance, this simple example will fail:
"$errorCode" {
controller = "error"
action = "general"
constraints {
errorCode(matches:/\d{3}/)
}
}
Does anyone know how I may approach this?
I tried doing same using Filters but we cannot redirect again after checking status code in httpResponse hence that also doesn't help.
As per grails-doc "Mapping to Response Codes"
http://grails.github.io/grails-doc/3.1.x/guide/single.html#urlmappings
we can only hard code them and redirect it to mentioned controller and action.
So you need to mention all http codes and handle all of them separately.
Thanks.

http module cant get correct page url

Hi i got a very noob question to ask . I am using http module to do a access right. Let say the user is 'admin' then he got authorized to view the page.The http module will get the access right from the database based on the page url, thereafter the http module will determine the user is allowed to access or not .
Here is my sample coding :
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(context_AcquireRequestState1);
}
void context_AcquireRequestState1(object sender, EventArgs e)
{
try
{
string requestUrl = application.Request.AppRelativeCurrentExecutionFilePath.ToString().Trim();
//return last string of .aspx
string requestAspx = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1).Trim();
}
but the httpmodule will run several time. It cant get the url correctly.
For example first time it may get ~/Module/Admin/Role/RoleManagementList.aspx.
then second time will get the wrong url ~/favicon.ico.Can anyone help me solve this problem? thank you so much
You are not getting the "wrong" url. The user's browser is simply making a different request for a different resource. You http module will execute for each http request, which will mean one for each resource in addition to the "page" such as favicons (displayed in the browsers url, and sometimes requested even if you don't have one) or images, external .css, external .js files, etc. referenced on the page (unless they are directly served by IIS bypassing the ASP.NET stack). You will need to consider all of these urls in your module.
Depending on how tightly you control your deployment environment,you may also/instead be able to exempt certain file extensions from every hitting asp.net by having IIS simply serve them directly. See http://msdn.microsoft.com/en-us/library/ms972953.aspx

Handling question mark in url in codeigniter

I am using a payment method which on success returns a url like mysite/payment/sucess?auth=SDX53641sSDFSDF, but since i am using codeigniter, question marks in url are not working for me.
I tried routing but it didnt work. As a final resort i created a pre system hook and unset the GET part from the url for with i had to set
$config["uri_protocol"] = "REQUEST_URI";
It worked that way but all other links in my site were not working as intended, tried changing the uri_protocol but could not make it work by any means.
So basically my problem is handling the ?auth=SDFSEFSDFXsdf5345sdf part in my url, whenever the paypment method redirects to my site with the url mentioned above, it gets redirected to homepage instead of the function inside controller.
How can i handle this, i'm using codeIgniter 1.7 version, and couldnt find any way.
Please suggest some solution.
I think I would extend the core URI class, by creating new file at application/libraries/MY_URI.php which will extend the CI_URI class, then copy the _fetch_uri_string method and here you can add your logic if the $_SERVER['QUERY_STRING'] is present:
class MY_URI extends CI_URI
{
function __construct()
{
parent::CI_URI();
}
//Whatever this method returns the router class is using to map controller and action accordingly.
function _fetch_uri_string()
{
if(isset($_SERVER['QUERY_STRING']) AND !empty($_GET['auth']))
{
//Do your logic here, For example you can do something like if you are using REQUEST_URI
$this->uri_string = 'payment/success/'.$_GET['auth'];
return;
//You will set the uri_string to controller/action/param the CI way and process further
}
//Here goes the rest of the method that you copied
}
}
Also please NOTE that you must do security check of your URL and I hope this works for you, otherwise you can try extending the CI_Router class or other methods (experiment little bit with few methods, though the _set_routing is important). These 2 classes are responsible for the intercepted urls and mapping them to controller/action/params in CI.
I believe this thread holds the answer.
Basically add
$config['enable_query_strings'] = TRUE;
to your config.php
hope this will help you ! no need to change htaccess,just change your code.
redirect(base_url()."controller_name/function_name");
Looking at the example code in the Stripe docs:
https://stripe.com/docs/payments/checkout/set-up-a-subscription
one might conclude that you can only retrieve a checkout_session_id as a named GET parameter like this:
'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
After playing around with .htaccess and config settings (as in previous answers) and finally getting it to work, it suddenly dawned on me that the DEVELOPER is in control of the success_url format, not Stripe. So one can avoid all the problems with a GET parameter by specifying the success url in the normal, clean Codeigniter format, like this:
'success_url' => 'https://example.com/success/{CHECKOUT_SESSION_ID}',
In my routes file, the incoming CHECKOUT_SESSION_ID string is passed to the Subscription controller's checkout_success method with this route:
$route['success/(:any)'] = 'subscription/checkout_success/$1';
The method accepts the $checkout_session_id like this:
function checkout_success($checkout_session_id)
{
// Do something with the $checkout_session_id...
}
I'm new to Stripe Checkout but this seems to simplify the integration without breaking Codeigniter's GET processing rules.

301 redirect in ASP.NET MVC from known URL's

I have a .Net MVC 1 site that replaced a legacy. Google still has a stack of old URL's in its index and i need to 301 redirect them. All of the old URL's are .html or .php pages, i also have a db table for old urls and their new equivalent. I know what i need to do, im just unsure of how to do it! Here are my thoughts
somewhere in the global.asax catch the url requested using a regexp
do a db lookup to hopefully find the new url
if we found the new url then 301 redirect it. if not either 301 to the homepage or throw a 404
Ive tried hacking around myself with little luck, plus all of the examples i can find online dont really cover this example. Would really like to do this via code rather than adding about 80 seperate routes to the global.asax
Any help or links is greatly appreciated
You could probably use Handlers. If the URLs are distinct enough, you could write a pretty broad entry in to urlMappings section of your web.config and then use the handler to re-route the traffic.
I'd use the catch all route and before returning that 404 I'd insert the logic to check if it needs a 301 instead.
[UrlRoute(Name = "404", Path = "{*path}", Order = 100)]
public ViewResult NotFound(string path)
{
}

Verify that a URL maps to an actual route in ASP.Net MVC

To support legacy URLs in my application, I use a regex to convert URLs of the form /Repo/{ixRepo}/{sSlug}/{sAction} to the new form /Repo/{sName}/{sAction}, using the ixRepo to get the correct sName. This works well, and I can redirect the user to the new URL with a RedirectResult.
However, I'd like to catch legacy URLs with an invalid action before I redirect the user. How can I verify if a URL string will map to a registered route? MVC clearly does this internally to map a request to the correct action, but I'd like to do it by hand.
So far, I've come up with this:
var rd = Url.RouteCollection.GetRouteData(new HttpContextWrapper(new HttpContext(
new HttpRequest("", newPath, ""),
new HttpResponse(null))));
which appears to always return a System.Web.Routing.RouteData, even for bad routes. I can't find a way to check if the route was accepted as a catch all, or if actually mapping to a route that's registered on the controller.
How can I use MVC's routing system to check if a URL maps to a valid controller/action via a registered route?
(I've seen ASP.NET MVC - Verify the Existence of a Route, but that's really inelegant. MVC has a routing system built in, and I'd like to use that.)
Wrong question. Anything can be a route, whether or not it actually maps to an action.
I think you're asking, "Will this execute OK, or will it 404?" That's a different question.
For that, you need to do what MVC does. Look in the MVC source at MvcHandler.ProcessRequestInit and then ControllerActionInvoker.InvokeAction to see how MVC looks up the controller and action, respectively.
If you know the controller and ask for valid actions, just do some reflection stuff as done in here.
If the redirected url goes to your application, then you can check if the url goes to a valid route. Some code on haacked.com http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx does route testing as a unit test. After this you have controller and action as routedata and you have to do, what Craig said "do the same as mvc does".
The routing system maps request uris to route handler. The mvc route handler (class) throws an exception if it fails. There is no checking.
You can add constraints to your routes. If you constrain the action property. Then checking if the url goes to a valid route my be what you want.

Resources