MVC5 using MvcSiteMapProvider to build twitter boo

2019-02-19 21:54发布

问题:

Default menu section in MVC5 template looking like that:

     <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
            @Html.Partial("_LoginPartial")
        </div>

_LoginPartial looking like that:

@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {
    @Html.AntiForgeryToken()

    <ul class="nav navbar-nav navbar-right">
        <li>
            @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
        </li>
        <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
    </ul>
    }
}
else
{
    <ul class="nav navbar-nav navbar-right">
        <li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
        <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
    </ul>
}

So i can replace the code

        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
        </div>

with just one line:

@Html.MvcSiteMap().Menu(false)

That line will produce this:

        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
           //how to put _LoginPartial here!
        </div>

So the question is how can i render @Html.Partial("_LoginPartial") inside menu created by MvcSiteMapProvider ?

回答1:

Rowan's answer is pretty close to what you need to do, and should have led you down the correct path. The template MyMenu.cshtml can contain any logic you need to output the desired HTML. You simply need to modify the template to meet your requirement. Note that you can also modify the default templates if desired, but you will have to be careful to select "no" when asked to replace them during an upgrade of MvcSiteMapProvider, or your customizations will be overwritten.

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
@using MvcSiteMapProvider.Web.Html.Models

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        @foreach (var node in Model.Nodes) { 
            <li>@Html.DisplayFor(m => node)</li>
        }
    </ul>
    @Html.Partial("_LoginPartial")
</div>

And then this line will produce the desired output:

@Html.MvcSiteMap().Menu("MyMenu")


回答2:

If I recall correctly you can specify the DisplayTemplate in the Menu() method.

Navigate to ~/Views/Shared/DisplayTemplates and create a new view called MyMenu.cshtml.

Set the model type to MvcSiteMapProvider.Web.Html.Models.MenuHelperModel and then specify the menu structure (with HTML).

MyMenu.cshtml

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
@using MvcSiteMapProvider.Web.Html.Models

<ul class="nav navbar-nav navbar-right">
    @foreach (var node in Model.Nodes) { 
        <li>@Html.DisplayFor(m => node)</li>
    }
</ul>

Now change your Menu() method.

@Html.MvcSiteMap().Menu("MyMenu")