开发者

ASP.NET MVC - hiding id in URL?

I'm building a basic blog application just now, for viewing data I'm just using the default route, i.e. -

routes.MapRoute
(
     "Default", // Route name
     "{controller}/{action}/{id}",
     new { controller = "Blog", action = "Index", id = UrlParameter.Optional } 
);

So that when you go to mysite.com/View/12 it displays the blog with id 12. I want to modify the URLs so that they look as follows: mysite.com/View/2010/06/01/this-is-the-title.

I could have a URL mapping like -

        routes.MapRoute(
            "View",
            "View/{year}/{month}/{day}/{title}",
            new { controller = "Blog", action = "View" }
        );

But then I'm not passing the ID into the Controller action so I would have to search on the date and title which doesn't feel right. On the other hand, if I pass the ID in it will show up in the URL which isn't what I'm aiming for either. Is there any way to redirect to the URL I want in the controller action after passing o开发者_运维百科nly the ID in as a paramter, or to pass the ID into the a Map Route but hide it in the URL?

Thanks for your help!


When you make your Title field in your blog posts, pre-generate the url-safe title and put it in a colunm in the blog table. Then you can select on that, and match the date against the input just to be sure (for duplicates).

Although, Most blogs though are like

/2010/05/31/23343-the-topic-has-the-id-in-it


Your URL mapping idea is actually the right thing to do. You can ignore the year/month/day (though make sure you put in URL constraints to match only numbers of the right sizes). So your controller action method might only care about the title, if the title is guaranteed to be unique (via your model constraints). Just make sure that your db indexes the title field for fast searching.

As Aren said, what's common as well is to have a 'slug' field that takes the post title and makes it URL safe and saves it in that state.

If you really want to, you could also use the wildcard mapping (e.g. "blog/{slug*}") which maps will map everything else in the URL as written, not using slashes as delimiters, so blog/2010/02/05/my-title would be passed into an actionmethod as a string parameter that equals "2010/02/05/my-title"


I did something like that though I showed IDs in URL. You can check the ID in an action routed from default URL then redirect it to shiny one.

public ActionResult Index(int id)
{
    BlogPost blogPost=blogRepository.GetPost(id);
    TempData["post"]=blogPost;
    //this makes sure post is stored in memory so it doesn't get to database again
    return Redirect("/View/"+blogPost.year+"/"+blogPost.month+"/"+blogPost.day+"/"+blogPost.title);
}

public ActionResult View(int year, int month, int day, string title)
{
    if(TempData["post]"==null)//I assume you will publish links with that URL, so someone can be routed here without redirecting
    {

        BlogPost blogPost=blogRepository.GetPost(title);
        return View(blogPost);
    }
    else 
        return View(TempData["post"]);
}

I think you better publish links with date too, that would make you check date and title for retrieving data but it would look better. Anyway if you just want to go with ID, Redirect and TempData can do the trick.


When an ID is passed in, I set a session variable, and then redirect the user to another controller ActionResult that reads the session variable. It's an annoying hack, but it's also annoying to display ID's in the URL. The SessionVariables class you see below is just a class of static properties that get/set to the session variables.

End result - redirect to a view with no ID by using session variables.

public ActionResult ViewContext(Int64 ContextID)
    {

        SessionVariables.the_context = "UserView";
        SessionVariables.the_context_id = ContextID;

        return RedirectToAction("ViewWithNoID");
    }

    public ActionResult ViewWithNoID()
    {
        //Change this to UserView

        Security_User obj = Security_User.getByPK(SessionVariables.the_context_id);

        return View("View", obj);
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜