1

I'm struggling with navigation in asp.net mvc and URLs.

When you are visiting your profile at Facebook, the url is facebook.com/yourusername. At your profile there is a menu with the following links: Timeline, About, Friends etc.

When you click on one of these links, for example Photos, the URL is changed to facebook.com/yourusername/Photos, and the photos are rendered. The menu described above are still there, and so also the profile picture and the cover picture. Its like a partial view has rendered viewing the photos.

I want to accomplish this effect in my project, but I don't know how to do it. I have tried to do it with Partial view but the problem is that the URL is not changed when the partial view is rendered.

How should I structure it?

My Index.cshtml that belongs to Home-controller looks like this:

div class="centering col-lg-7 logged_in_mainboxes" style="padding: 0; position: relative">

    <div class="col-lg-12 coverPicture" style="background-image: url('/Content/Images/@Model.CoverPicture');">
       <div id="image-cropper">
            <div class="cropit-preview"></div>         
            <h3 class="coverPicTextStyle">
                @Model.Name
            </h3>
            <button type="submit" id="uploadCoverpicture" class="btn_style_2 btn" style="position: absolute; bottom: 10px; right: 10px;">Upload</button>
            <button type="submit" id="crop" class="btn_style_2 btn" style="position: absolute; bottom: 50px; right: 10px; display: none;">Done</button>
            <input type="file" class="cropit-image-input" id="coverUpl" style="display: none;" />
        </div>
        <div class='progress' id="progress_div">
            <div class='bar' id='bar1'></div>
            <div class='percent' id='percent1'></div>
        </div>
        <input type="hidden" id="progress_width" value="0">
    </div>
    <div class="col-lg-12 pull-left">
        <div class="user_menu">
            <ul>
                <li>@Html.ActionLink("Wall","Wall","Home")</li>
                <li>@Html.ActionLink("Music", "Music", "Home")</li>
                <li>@Html.ActionLink("Photos", "Photos", "Home")</li>
                <li>@Html.ActionLink("Videos", "Videos", "Home")></li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
            </ul>
        </div>
    </div>
    <div class="col-lg-7 pull-left" style="margin-top: 15px;">

    </div>
    <div class="col-lg-3 pull-right" style="border-left: 1px solid #ddd; margin-top: 15px; ">
        asdasd
    </div>
</div>
14
  • You could do that by defining routes - say url: {username}/Photos and defaults { controller = "Photos", action = "Index" } and redirect to that method, passing the user name (the menus etc would be just part of the layout) Commented May 20, 2016 at 3:50
  • @StephenMuecke: But I don't want that user specific menu to be a part of the Layout-file. Commented May 20, 2016 at 3:53
  • If its a user specific menu, then you generate it in the layout by using @{ Html.RenderAction(...); }, passing the username (or ID) to the a method that generates the menu items based on the user Commented May 20, 2016 at 3:55
  • @StephenMuecke: Sorry, I dont understand your solution. I have the all the layout of the profile inside my Index.html that belongs to the Home-controller. Check my updated question. Commented May 20, 2016 at 3:57
  • @StephenMuecke: Yes I have? Commented May 20, 2016 at 4:20

2 Answers 2

2

I would first start by grouping all he methods associated with the user in a UserController method which will include methods such as

public ActionResult Index(string username)
public ActionResult Photos(string username)
public ActionResult Music(string username)

etc, and the routing configuration as per your subsequent question. and create a separate layout page hat will be used for each of these methods (say) _UserLayout.cshtml and each view for these methods will then include

@{ Layout = "~/Views/Shared/_UserLayout.cshtml"; }

In order to pass the username around(to the layout, and subsequently to the methods via the ActionLink() methods, create a base class (say)

public class UserBaseVM
{
    public string UserName { get; set; }
}

and all models used in these methods would derive from that base class (say)

public class UserPhotosVM : UserBaseVM
{ 
    public List<YourPhotoModel> Photos { get; set; }
    ....

Then in _UserLayout.cshtml, use the UserName property of UserBaseVM to generate your links

@model yourAssembly.UserBaseVM
... //add common menu/navigation elements
<div class="col-lg-12 pull-left">
    <div class="user_menu">
        <ul>
            <li>@Html.ActionLink("Photos", "Photos", new { userName = Model.UserName })</li>
            ....

Then your method would be

public ActionResult Photos(string userName)
{
    UserPhotosVM model = new UserPhotosVM()
    {
        UserName = userName,
        Photos = .....
    }
    return View(model);
}

A cleaner and more flexible solution would be to create a [ChildActionOnly] method that returns a partial view of the menu, for example

[ChildActionOnly]
public ActionResult Menu(string userName)
{
    UserBaseVM model = new UserBaseVM(){ UserName = userName });
    ....
    return PartialView(model);
}

and in the _UserLayout.cshtml file, use

@{ Html.RenderAction("Menu", new { userName = Model.UserName });
Sign up to request clarification or add additional context in comments.

Comments

0

The solution is you should implement routes in your application.

Create a class "RouteConfig" like this: Use using System.Web.Routing;

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        var route = routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "YourController", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "YourDomain.NameSpace.Controllers" }
        );
        route.DataTokens["UseNamespaceFallback"] = true;
    }
}

Register the routes in your Global.asax file in Application_Start() method:

RouteConfig.RegisterRoutes(RouteTable.Routes);

Now implement Session concept to redirect a user logged to your application and call it by using OnAuthorization method in your base controller.

If you to use partial view page, use:

@Html.Partial("_YourPartialViewPage", Model)

Use Ajax calls in your javascript method to pass data to the controller.

yourAjax({ url: '@Url.Content("~/YourController/YourControllerAction")', data: { headerId: id, }, success: successFunction });

3 Comments

Each language has its own way of compiling and interpreting. And this, is a simple way of configuring routes in MVC and not a complex solution as you think. If you want to consider an example of using complexity in this. consider about multilingual and implementing localizations in your application.
Ok. But I don't see how the code you provided solves my problem? I already have the code that you specified, except the namespace part in the routes-file. How does the code you provided help me with my issues provided In my question?
Follow the solution completey. It should solve the problem. Check if you have done others and try to implement that if you have missed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.