I have an existing site that I'd like to convert to use routing, and after reading Scott Guthrie's post here, I built a working sample that works for most circumstances. However, since not all of the pages on the existing site match a particular pattern, I'll need to check against a database to determine which route (destination .aspx page) to use.
For example, most pages are like this:
http://www.mysite.com/people/person.html
This is fine - I can easily route these to the view_person.aspx page because of the 'people' directory.
But some pages are like this:
http://www.mysite.com/category_page.html
http://www.mysite.com/product_page.html
This necessitates checking the database to see whether to route to the view_category.aspx page or the view_product.aspx page. And this is where I'm stuck. Do I create an IRouteHandler that checks the database and returns the route? Or is there a better way? The only code I've found that kind of fits is the answer to this question.
Thanks in advance.
If you don't mind doing so, the cleanest solution is to:
http://www.mysite.com/pages/category_page.html
In ASP.NET MVC, this situation would be handled a little differently, by specifying a default controller and action method on the root route.
Your route handler doesn't check the database. It sends all the requests to a handler .aspx script. It's that script that checks the database.
My register route looks like...
private static void RegisterRoutes()
{
Route currRoute = new Route("{resource}.axd/{*pathInfo}",
new StopRoutingHandler());
RouteTable.Routes.Add( "IgnoreHandlers", currRoute);
currRoute = new Route("{urlname}",
new EPCRouteHandler("~/Default.aspx"));
currRoute.Defaults = new RouteValueDictionary {{"urlname", "index.html"}};
RouteTable.Routes.Add( "Default", currRoute);
}
The custom handler, which shouldn't be needed in ASP.Net 4.0, simply passes the urlname parameter to the responding script as a URL variable.
Now how often the responding script checks the database depends on how often the data in the database is changed. You can easily cache paths and invalidate the cache when the data is suppose to have changed for instance.
For anyone stuck in the same situation, I ended up adapting the code from this answer to check against a database and return the proper ASPX page.
Related
A little background:
We need to develop a custom Orchard module for a client that will catch the external URL referrer (if any) and store it in a session variable for later use, e.g. submitting a query for one of their products.
My naive solution was to suggest we record the URL referrer on Session_Start because it is a reliable way of knowing how the user got to our site. The problem is that the client does not want us touching the global.asax.cs file. It has to be done via a custom module. This is non-negotiable.
So my question is this: how can I reliably retrieve and store the UrlReferrer information when a new session starts using an Orchard module?
Or alternatively, is there some other way I can hook into the page lifecycle and maybe check whether or not the previous page was an external referrer?
My most important concern here is I need to know whether someone clicked on a sponsored link and I need to find that out in a module, not global.asax.cs. I am not dead set on any particular tracking method, as long as it is possible in the Orchard framework given the limitations imposed on me.
FYI: Orchard version is 1.8+
You can do this from a filter. I implemented this a while ago in my commerce module, to enable giving discounts or attributions for conversions from partner sites, typically. You can see the source code for my filter here: https://github.com/bleroy/Nwazet.Commerce/blob/master/Filters/ReferrerFilter.cs
What I would do, is create a custom module and in there a custom controller:
public class ReferrerController : Controller {
public ActionResult Index(string referrer) {
if (Session["Referrer"] != null) {
// do nothing, already used as entry point in the current session
} else {
// handle referrer, probably also some timestamp or hash
Session["Referrer"] = referrer; // save in session
}
return RedirectToRoute("~/"); // redirect to home
}
}
Obviously, also create a route for this. Then from the external referrers, go to this route where the referrers will be handled. (http://example.com/referrer?referrer=somereferrer)
I am working on an existing ASP.NET webforms project - slowly updating to MVC. I am trying to conditionally override some of the existing webforms pages by routing to new MVC controllers. I can easily route an "example.aspx" URL to an MVC controller, but it doesn't work if there is an existing "example.aspx" file.
Example code:
routes.MapRoute
(
name: "example",
url: "example.aspx",
defaults: new
{
controller = "Example",
action = "Index"
}
constraints: new { useMvc= "1" }
);
The code above works fine, and routes to the controller as expected, unless there is an existing "example.aspx" file in my solution - in which case it routes to that instead. But that's exactly what I'm trying to override.
Are existing webform routes given preferential treatment? Is there some way to circumvent this?
I've found mechanisms to do the reverse by using MapPageRoute(), but as far as I can see, that doesn't help me.
You can configure your application to ignore specific routes that your are handling through MVC. You could add the following line before registering a new route:
routes.IgnoreRoute("{*path}/example.aspx");
Hope this helps.
I haven't solved the problem as stated, but I've found a work-around that will accomplish the same result.
1) I renamed the "example.aspx" file to something else "foo.aspx"
2) Added the MapRoute() similar to my original question (with the constraint)
3) Used MapPageRoute() to route all other "example.aspx" calls to "foo.aspx"
I also ended up having to use the QueryStringConstraint logic as described by
another stackoverflow answer: but that's a separate issue.
I'll leave this question open for a few more days to see if there is a "real" solution before marking my own answer.
I'm having a little problem i hope someone can help me with.
on ASP.net MVC 4 (C#) i need to be able to edit the parameters of my route from my controller.
example the request url is
MyController/MyAction/param1/param2
now from MyAction I need to edit the returned url so that it displays
MyController/MyAction/Modifiedparam1/Modifiedparam2
The purpose of this is to translate the parameters that i retrieve from my database from language changes.
Please use redirect result for this (in MyAction on some condition):
return RedirectToAction("MyAction", { param1Name = Modifiedparam1, param2Name = Modifiedparam2 };
Basically you cannot modify url in controller. Urls is something send by the browser to invoke some action. You may just say browser to redirect user to another url.
Don't fight with framework. It will fight back sooner or later. Instead follow mvc principles, redirect from controller action or filters/interceptors to do so.
i want to route Default.aspx to another URL when page starts.
my global.asax is like this :
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute(
"Default", // Route name
"My Site", // URL with parameters
"~/Default.aspx" // Parameter defaults
);
}
should i write a handler for my purpose?
(i found some samples for .net 3.5 and MVC but what about .net 4 web forms)
if yes how can i write it?
EDIT:
what this line exactly do?
routes.Add("Default", new Route(string.Empty, new RouteHandler("~/Default.aspx")));
i am using web forms -> Not MVC
thanks in advace
Here's a specific example of how to deal with routing on asp.net 4.0 web forms (it's just under the mvc part).
http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx
The way you are approaching it is fine. You do have an error in the second parameter of your route. Well perhaps not an error, I dislike spaces in urls as they are actually the encoded spaces. Check out the guide.
Just noticed your edit.
Adding the route essentially creates a mapping between a url or url pattern (which you have as string.Empty which is a problem) and a handler which serves the request(You specify RouteHandler which I don't believe actually exists?). .net Provides a PageRouteHandler which allows you to specify which page responds to your request and deal with a couple other details like security defined on the physical structure of your site. Internally, MapPageRoute is simply calling routes.Add but using the PageRouteHandler.
I am trying to come up with idea how to implement msdn like localization based on address string
http://msdn.microsoft.com/en-us/library/system.string.aspx
http://msdn.microsoft.com/ru-ru/library/system.string.aspx
I tried to find various information about ASP.NET localization, but failed to find a description of strategy that can be used to get above result.
I am not very experienced with ASP.NET and would like to get some advice on how to implement something that will result in similar paths on my website(using best possible way with least code duplication for example).
I understand that I could duplicate both files in 2 folders. or 10 files in 10 folders if i got 10 cultures. But that sounds like not the best strategy. Is there some rewrite & parameter pass going on behind or ?
Update: I ended up implementing it the following way:
for my localizable pages I register routes to all current cultures ( in a generic method),
for example for help.aspx I register ru-ru/help/ and en-us/help/ routes, inside help.aspx (and other localizable pages, oop way) I analyze address string and retrieve desired language. After that I setup html contents matching the related culture provided in url.
Microsoft appear to be either rewriting the URLs, or taking advantage of custom routing in ASP.NET. They are using using the URL to determine which culture to select. They could have used a query string but the URLs would not look as good.
I'd suggest that you start by looking into ASP.NET MVC as it uses routing out of the box. Then modify the routes to match those used by MS above, before using them to apply a culture.
Where you will be hosting your application could have an impact on whether you can do similar things. If you are managing the whole server and not using shared hosting it will be easier to implement these things, especially URL rewriting. If you have to use ASP.NET 2.0 because you are in some aging corporate environment you will probably have an even more difficult time.
Valentin, try to use url routing:
1 - Add routing info to global.asax
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapPageRoute("cultureCrossroad", "{culture}/Library/{article}", "~/library/ArticleHost.aspx");
}
2 - Create host page at ~/Library/ArticleHost.aspx
public partial class ArticleHost : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// ! Here we have access to url's parts and can redirect user for desired page via Server.Transfer method.
var response = string.Format("culture: {0}<br/> article: {1}", Page.RouteData.Values["culture"], Page.RouteData.Values["article"]);
Response.Write(response);
}
}