0

I've been searching and searching for away to make old URL like we used to do in aspx pages where you could have an alias pointing to a page like www.domain.com/my-great-alias point to www.domain.com/alias.aspx. I want to do the same thing in MVC but can not figure out how to make this happen in the route table. Where www.domain.com/my-great-alias would show up to the end user as such but point to www.domain.com/alias/2

Does this make sense to anyone else what I'm looking for?

// router

routes.MapRouteLowercase(
                            "Alias",
                            "{id}",
                            new
                            {
                                controller = "alias",
                                action = "select",
                                id = UrlParameter.Optional
                            }
                        );

// Alias controller

public ActionResult Select()
        {
            return View("select");
        }

// Recipe Controller

public ActionResult Select()
    {
        return View();
    }
  • MVC is setup to map URLs to *controller action methods* not to other URLs. Your question is a bit unclear. What is supposed to happen if the user navigates to `/alias/2`? Should it serve the page? Should it give a 404 not found or 301 redirect? If the former, you can map 2 different URLs to the same action method. If the latter, you can probably just get rid of the `/alias/2` because it doesn't seem to have much of a purpose. – NightOwl888 Jan 26 '17 at 16:06
  • If you look at this URL http://www.motherearthnews.com/organic-gardening/vegetables/late-season-salad-crops-zb0z1701zsgre this site is built using MVC this is the behavior I want. The alias comes from a CMS but I can not figure out how to do it using just MVC. The alias is not hard code in the source for any of their URL. – Cpurepair785 Jan 26 '17 at 18:19

1 Answers1

1

You should be able to do this utilizing route config and parameters (as long as it's in the same domain):

Routing

        routes.MapRoute(
            name: "AliasRoute",
            url: "{id}",
            defaults: new { controller = "Alias" }
        );

Controller

public class AliasController : Controller
{
    public ActionResult Index(string id)
    {
        //DO SOME DATABASE STUFF HERE TO LOOKUP THE CORRESPONDIND CONTROLLER AND ACTION
        var controllerAction = lookupControllerActionInDatabase(id);
        return View(controllerAction.ViewName);

        //OR

        //DO CONDITIONAL CHECKS HERE AND RETURN THE APPROPRIATE VIEW
        if (id == "my-great-alias") {
          return View("Alias");
        } else if (id == condition1) {
          return View("viewForCondition1");
        } else if (id == condition2) {
          return View("viewForCondition2");
        }
        //AND SO ON...
    }
}
Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
  • This would be a good solution but I'm more looking for a dynamic way of doing it. Such as searching the URL in a database then returning what control and action name go to it but leaving the URL as is for the end user so they only see http://www.domain.com/my-great-alias. – Cpurepair785 Jan 26 '17 at 14:30
  • Something like the code above would still allow the end user to only see domain.com/my-great-alias, and the code executed would be the `Alias` controller. I'm not sure about the "dynamic" part of it, though. When you say "dynamic" are you talking about runtime? – Matt Spinks Jan 26 '17 at 14:40
  • Yes in aspx winform I use to use the global.cs to find the alias when executed in the database and then cached to a collection. Find the URL get the page show the content. In this case i need the same thing with retaining the model information for MVC. – Cpurepair785 Jan 26 '17 at 14:52
  • That is exactly what MVC routing does (sans the database part). For instance, you can have a route with url "domain.com/my-great-alias", and the routing rule causes the `Alias` controller to be executed. That is exactly what the example above does. You could also have another routing rule for something like "domain.com/another-url" and have it also point to the `Alias` controller. Is it the database functionality you are looking for? – Matt Spinks Jan 26 '17 at 15:11
  • This is as close of a solution I have found on the internet http://stackoverflow.com/questions/23418830/aliasing-a-url-inside-a-custom-asp-mvc-route however looking at it I have tried it yet I'm going to today. But it seem to take the URL and set the URL to the controller/action URL rather then keep the alias. – Cpurepair785 Jan 26 '17 at 15:18
  • To answer your question yes I think maybe the database part of it at runtime to insert a dynamic URL / Controller / Action rather then hard coding many url into the route mapping. – Cpurepair785 Jan 26 '17 at 15:19
  • I still think you can use routing rules to achieve what you are looking for. In the rules, you can specify parameters as part of the path. So your old url "my-great-alias" can still be part of the path "domain.com/my-great-alias", but "my-great-alias" becomes a parameter. Then you can return content dynamically from your controller. Check my updated answer. – Matt Spinks Jan 26 '17 at 15:35
  • I'm talking about a lot of alias not just one. It is impossible to hard code every single alias in this matter. My alias will be 100000+ and need to be redirected to the right controller / action. Maybe I'm not getting the full idea of what your suggesting here but it seem I would have to hard code each on. – Cpurepair785 Jan 26 '17 at 15:49
  • I have a couple `if` statements, just as an example. `if` statements would not be a good idea for 100000+ aliases. However, you can do a database lookup in the controller. Lookup the id (which is your url) in the database, and find the corresponding record. And from that, get the corresponding controller/action in the database and return that view. – Matt Spinks Jan 26 '17 at 15:58
  • If you look at my code above this simple change the URL to the /Controller/Action URL or looks for a select file in the alias folder when i need it to look in the Recipe controller for the action an the url changes rather then keep the Alias. – Cpurepair785 Jan 26 '17 at 22:49
  • Now I'm really confused. What are you trying to accomplish here? The motherearthnews website you referenced is just doing some basic MVC stuff, nothing special. MVC is designed so you can have a dynamic url, parse out pieces of the url and do stuff with those pieces, whether that be streaming out a hard-coded view, or looking up stuff in a database (such as what you are trying to do) and stream out content that way. What part of my updated answer does not work for you? – Matt Spinks Jan 26 '17 at 23:41
  • The URL http://www.motherearthnews.com/organic-gardening/vegetables/late-season-salad-crops-zb0z1701zsgre does not have a controller called Organic-Garding or Vegetables etc etc. Using the code above MVC looks for the view in the folder the controller is named. In this case there is no file called alias and if you do put a file in that folder called alias then it changes the URL to /Alias/Alias or ever you call the action. – Cpurepair785 Jan 27 '17 at 00:21
  • In short all my files would have to site under the Alias folder rather then Recipe folder etc. – Cpurepair785 Jan 27 '17 at 00:29
  • So you want to return content from a view in a different folder? – Matt Spinks Jan 27 '17 at 00:31
  • Yes I want an alias that will do all the alias URLS and redirect them to the right controller and action without changing the URL in the browser. – Cpurepair785 Jan 27 '17 at 00:48
  • You can return another view (in a different folder) with the following: `return View("~/Views/Wherever/AnotherView.cshtml")`. But it won't fire off the other controller. – Matt Spinks Jan 27 '17 at 04:05
  • If you really need to fire off the other controller, you will have to do a `return RedirectToAction("AnotherController", "AnotherView");`. However, that will change the user's url. From what you are telling me, what you are doing is not going to be easy. There is another person who supposedly created a plugin to do that in MVC3. You can find it here: http://stackoverflow.com/questions/799511/how-to-simulate-server-transfer-in-asp-net-mvc?lq=1 – Matt Spinks Jan 27 '17 at 04:06
  • But that does make it seem that there is something here that we are leaving out of the equation. You talk about wanting to return views from other folders, but you also say that you don't want to hard-code the routing because there are 100,000+ redirect rules or pages. Are there really 100,000+ views there? That seems unlikely. And if not, what else are you redirecting to? Maybe it's time to rethink what you are doing from a higher level. – Matt Spinks Jan 27 '17 at 04:10
  • No there is not 100000 views/unique URL maybe 30 at most but instead of having a URL for the same area like /controller/action/id its one to many relationship where the ID is the key/URL alias. This would be the same for each separate controller area in the code. – Cpurepair785 Jan 27 '17 at 14:48
  • One solution I have been toying with is to use the alias as is because it keeps the URL and then make every other controller area use partial views that post back to the right controller for forums and then redirect back to the alias URL. I can see this working but would that be the best solution... The alias select view would have to have a select statement or something to pick which partial but man that seem like a lot of overhead on one file – Cpurepair785 Jan 27 '17 at 15:04