views:

183

answers:

2

Hello,

I am trying to implement user-friendly URLS, while keeping the existing routes, and was able to do so using the ActionName tag on top of my controller (http://stackoverflow.com/questions/436866/can-you-overload-controller-methods-in-asp-net-mvc)

I have 2 controllers:

ActionName("UserFriendlyProjectIndex")]
public ActionResult Index(string projectName) { ... }

public ActionResult Index(long id) { ... }

Basically, what I am trying to do is I store the user-friendly URL in the database for each project.

If the user enters the URL /Project/TopSecretProject/, the action UserFriendlyProjectIndex gets called. I do a database lookup and if everything checks out, I want to apply the exact same logic that is used in the Index action.

I am basically trying to avoid writing duplicate code. I know I can separate the common logic into another method, but I wanted to see if there is a built-in way of doing this in ASP.NET MVC.

Any suggestions?

I tried the following and I go the View could not be found error message:

[ActionName("UserFriendlyProjectIndex")]
public ActionResult Index(string projectName)
{
    var filteredProjectName = projectName.EscapeString().Trim();

    if (string.IsNullOrEmpty(filteredProjectName))
        return RedirectToAction("PageNotFound", "Error");

    using (var db = new PIMPEntities())
    {
        var project = db.Project.Where(p => p.UserFriendlyUrl == filteredProjectName).FirstOrDefault();
        if (project == null)
            return RedirectToAction("PageNotFound", "Error");

        return View(Index(project.ProjectId));
    }
}

Here's the error message:

The view 'UserFriendlyProjectIndex' or its master could not be found. The following locations were searched:
~/Views/Project/UserFriendlyProjectIndex.aspx
~/Views/Project/UserFriendlyProjectIndex.ascx
~/Views/Shared/UserFriendlyProjectIndex.aspx
~/Views/Shared/UserFriendlyProjectIndex.ascx
Project\UserFriendlyProjectIndex.spark
Shared\UserFriendlyProjectIndex.spark

I am using the SparkViewEngine as the view engine and LINQ-to-Entities, if that helps. thank you!

A: 

Sorry, it looks like I am answering my own question!

I returned the call to Index controller inside my "wrapper" controller and then I specified the view name in the Index controller.

ActionName("UserFriendlyProjectIndex")]
public ActionResult Index(string projectName) 
{ 
    //...
    //var project = ...;
    return Index(project.ProjectId);
}

public ActionResult Index(long id) 
{
    //...
    return View("Index", project);
}
AbeP
A: 

Just as an addition this this, it might pay to optimize it to only hit the database once for the project...

ActionName("UserFriendlyProjectIndex")]
public ActionResult Index(string projectName) 
{ 
    //...
    //var project = ...;
    return IndexView(project);
}

public ActionResult Index(long id) 
{
    //...
    //var project = ...;
    return IndexView(project);
}

private ViewResult IndexView(Project project) 
{
    //...
    return View("Index", project);
}
Charlino