1

In my _Layout.cshtml view I have

@using SiteNET.Utilities
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>"SomeTitle"</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

    <!-- Favicons -->
    <link rel="apple-touch-icon-precomposed"
          sizes="256x256"
          href="@Url.Content("~/Content/Images/SiteRetro256.png")">
    <link rel="shortcut icon"
          href="@Url.Content("~/Content/Icons/SiteRetro.ico")">
</head>
<body>
    <div class="container">
        <div class="navbar navbar-default" role="navigation">
            <div class="container-fluid">
                <div class="navbar-header">
                    <button type="button"
                            class="navbar-toggle"
                            data-toggle="collapse"
                            data-target=".navbar-collapse">
                        <span class="sr-only">Toggle navigation</span>
                    </button>
                    @Html.ActionLink(SiteNET.Utilities.Constants.Site,
                        "Index", "Home", null, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li class="@Url.MakeActive("Home")">
                            @Html.ActionLink("Home", "Index", "Home")
                        </li>
                        <li class="@Url.MakeActive("Index", "Contacts")">
                            @Html.ActionLink("Contacts", "Index", "Contacts")
                        </li>
                    </ul>
                    @Html.Action("_LoginPartial", "Account") <- THIS LINE
                </div>
            </div> <!--container-fluid-->
        </div> <!--navbar-->
        @RenderBody()
        <hr />
        ...
    </div>
</body>
</html>

My aim is be able to load a view model into my _LoginPartial view. So I have added the following to my AccountController class

[ChildActionOnly]
public ActionResult _LoginPartial()
{
    ApplicationUser user = null;
    ManageUserViewModel model = null;
    string userID = User.Identity.GetUserId() ?? String.Empty;
    if (!String.IsNullOrEmpty(userID))
    {
        user = UserManager.FindById(userID);
        model = new ManageUserViewModel();
        model.IsAdmin = user.IsAdmin;
    }
    return PartialView(model);
}

But this does not call this method from

@Html.Action("_LoginPartial", "Account")`

I have read this answer and have swapped the

@Html.Action("_LoginPartial", "Account")

to

@Html.Action("_LoginPartial", "Account", new { area = "" }) 

as the controller is not in the "Shared" folder. I have also tried

@Html.Action("_LoginPartial", "Account", new { area = "Controllers" })` 

but I am just getting a browser error:

The page isn't redirecting properly

What am I doing wrong here?

Thanks for your time.


Edit. following @markpSmith's suggestion, I have attempted to use

 @{ Html.RenderAction("_LoginPartial", "Account"); }

_but this give the same error. _

Community
  • 1
  • 1
MoonKnight
  • 23,214
  • 40
  • 145
  • 277

2 Answers2

1

Use @Html.Partial("_LoginPartial")

You don't need to specify action in Controller as you can access User.Identity in View so update _LoginPartial with User.Identity instead of Model.

sandip patil
  • 191
  • 4
  • But then in the view I will have to get the user like `user = UserManager.FindById(userID)` so will have to intantiate the `UserManager` is this okay to do? – MoonKnight Nov 10 '14 at 15:02
  • You can check if logged in user is Admin using User.IsInRole("Admin") code so I think you don't need to user info from UserManager. Is it making sense? – sandip patil Nov 10 '14 at 15:09
  • Kind of, but I am not using Roles (this may be deemed bad!). The reason is that the application is very simple and there will be only one Admin user. So i have stored a field called `IsAdmin` in the user database. All users are created `IsAdmin=false` except a single user called `Administrator` which has `IsAdmin =true` set when the database is first created. I am taking your advice though and checking the `User.IsAdmin` in the view... – MoonKnight Nov 10 '14 at 15:11
  • 1
    I would suggest instead on invoking Action for this single reason you can create BaseController and override OnActionExecuting and set ViewBag.IsAdmin true or false as per your conditions. And inherit all your controllers from BaseController. – sandip patil Nov 10 '14 at 15:17
1

I can't see if you have attempted the:

@Html.RenderPartial()

ActionMethod (see MSDN)

making yours look similar to:

View:

@Html.RenderPartial("_LoginPartial","Account")

Controller:

(within AccountController)

public ActionResult _LoginPartial()
{
    ApplicationUser user = null;
    ManageUserViewModel model = null;
    string userID = User.Identity.GetUserId() ?? String.Empty;
    if (!String.IsNullOrEmpty(userID))
    {
        user = UserManager.FindById(userID);
        model = new ManageUserViewModel();
        model.IsAdmin = user.IsAdmin;
    }
    return PartialView(model);
}

Other than that, I would suggest removing the underscore and see if you can run it instead (since it is a partial view, I don't think it will be navigateable anyway)

jbutler483
  • 24,074
  • 9
  • 92
  • 145
  • @Killercam It's what I use to open Partial views, anyway. I've never heard of/used {areas =...} ever so not entirely sure that's required. – jbutler483 Nov 10 '14 at 15:14
  • 1
    One thing is that `RenderPartial` returns void, so you can just put it "in place of" this `@Html.Action` method... – MoonKnight Nov 10 '14 at 15:17