views:

45

answers:

1

I have a requirement to add specific functionality to an asp.net mvc2 web site to provide addtional SEO capability, as follows:

The incoming URL is plain text, perhaps a containing a sentence as follows

"http://somesite.com/welcome-to-our-web-site" or "http://somesite.com/cool things/check-out-this-awesome-video"

In the MVC pipeline, I would like to take this URL, strip off the website name, look up the remaining portion in a database table and call an appropriate controller/view based on the content of the data in the table. All controllers will simply take a single parameter bieng the unique id from the lookup table. A different controller may be used depnding on different urls, but this must be derieved from the database.

If the url cannot be resolved a 404 error needs to be provided, if the url is found but obsolete then a 302 redirect needs to be provided.

Where the url is resolved it must be retained in the browser address bar.

I have had a look at the routing model, and custom routing and can't quite work out how to do it using these, as the controller would not be predefined, based on a simple route. I am also unsure of what to do to provide 404, 302 back to the headers also. Perhpas I need a custom httpmodule or similar but going there went beyond my understanding.

This must be possible somehow... we did it years ago in Classic ASP. Can anyone help with some details on how to achieve this?

A: 

Well, the simplest way would be to have an id somewhere in the url (usually the first option)

routes.MapRoute(
    "SEORoute", // Route name
    "{id}/{*seostuff}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional, seostuff = UrlParameter.Optional } // Parameter defaults
);

In your controller you'd have something like

public class HomeController {
    public ActionResult Index(int id) {
        //check database for id
        if(id_exists) {
            return new RedirectResult("whereever you want to redirect", true);
        } else {
            return new HttpNotFoundResult();
        }
    }
}

If you don't want to use the id method you could do something else like...

routes.MapRoute(
    "SEORoute", // Route name
    "{category}/{page_name}", // URL with parameters
    new { controller = "Home", action = "Index", category = UrlParameter.Optional, pagename = UrlParameter.Optional } // Parameter defaults
);

public ActionResult Index(string category, string page_name) {
    //same as before but instead of looking for id look for pagename
}

The problem with the latter is that you would need to account for all types of routes and it can get really difficult if you have a lot of parameters that match various types.

This should get you in the right direction. If you neeed some clarification let me know and I'll see if I can write a specific route to help you

Additional

You could probably do what you're looking for like

public ActionResult Index() {
    //Create and instance of the new controlle ryou want to handle this request
    SomeController controller = new SomeController();
    controller.ControllerContext = this.ControllerContext;
    return controller.YourControllerAction();
}

but I don't know any of the side effects by doing that...so it's probably not a good idea - but it seems to work.

BuildStarted
Interesting... It worked up to a point. routes.MapRoute( "Generic", // Route name "{url}", // URL new { controller = "Content", action="Redirector", url = urlParameter.Optional } // Parameter defaults I can redirect in the controller and return 404. Cool. What I need though is to call a specific controller based on the content of the database as follows: get long url, read id and controller name from database based on this url, **redirect** to correct controller while retaining url in address bar. Different urls could be handled by different controllers.
FlashRobert
Unfortunately MVC provides no direct way to do this as all redirections involve the client.
BuildStarted