In my _Layout.cshtml I want to include a dropdown list in the site header. I'm not positive of the best way to do this, but I've tried to code it using a PartialView. It seems to be working, but when the form is submitted the page loads with only the dropdownlist.
ViewModel:
namespace XXXX_Web_App.Models
{
public class LanguageListPartial
{
[DataType(DataType.Text)]
[Display(Name = "Language")]
public string Language { get; set; }
}
}
Controller:
[AllowAnonymous]
[ChildActionOnly]
public ActionResult LanguageList()
{
ViewBag.LanguageList = GetLanguageList();
return PartialView("_LanguageListPartial");
}
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult> LanguageList(string language)
{
// Save selection to cookie
HttpCookie cookie = new HttpCookie("UserSettings");
cookie["Language"] = language;
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
// Save selection to user profile
if (User.Identity.IsAuthenticated)
{
String userId = User.Identity.GetUserId();
ApplicationUser user = await UserManager.FindByIdAsync(userId);
user.Language = language;
await UserManager.UpdateAsync(user);
}
ViewBag.LanguageList = GetLanguageList();
return PartialView("_LanguageListPartial");
}
public List<SelectListItem> GetLanguageList()
{
List<SelectListItem> languages = new List<SelectListItem>();
languages.Add(new SelectListItem { Text = "English", Value = "en-US" });
languages.Add(new SelectListItem { Text = "Français", Value = "fr-CA" });
languages.Add(new SelectListItem { Text = "Português", Value = "pt-BR" });
languages.Add(new SelectListItem { Text = "Español", Value = "es-MX" });
return languages;
}
Partial View:
@model XXXX_Web_App.Models.LanguageListPartial
@Html.DropDownListFor(
x => x.Language,
new SelectList(ViewBag.LanguageList, "Value", "Text"),
new { @class = "form-control toggle", onchange = "this.form.submit();"
})
_Layout.cshtml:
@using Westwind.Globalization;
@using Westwind.Globalization.Resources;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryUI")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
<script src="/Scripts/jquery.cookie.js"></script>
</head>
<body>
<div style="">
<div class="header container">
... nav menu ...
</div>
<form action="/Account/LanguageList" method="post" >
@{Html.RenderAction("LanguageList", "Account");}
</form>
<div class="container">
<div class="row">
<div class="col-md-12">
@RenderBody()
</div>
</div>
</div>
<footer class="container">
<hr />
<p>© @DateTime.Now.Year</p>
</footer>
</div>
</body>
</html>
The desired logic is:
Every site/page visit
- Anonymous user - load selection from cookie. Default to English. (not done yet)
- Authenticated user - load selection from user profile (not done yet)
On selection
- Anonymous user - save selection to cookie
- Authenticated user - save selection to cookie and update user profile
Like I said, this seems to be working except that when a selection is made the Controller action gets called and when the page reloads the only thing on the page is the dropdown list.
How do I return the View in this situation?
One other question, I would like the text in the dropdown list items to include the culture specific decorations, but they are displaying literally like Français
instead. I don't see how I can use Html.Encode()
in this situation. It's probably being caused by the way I am adding the items in GetLanguageList()
. How do I avoid this?
EDIT
To clarify, my excerpt from _Layout.cshtml above is just that - an excerpt. My _Layout.cshtml contains what you might expect of it - a header with logo and subtitle, navigation menu, and RenderBody() code. The page displays properly on the Partial View's GET Controller Action, but when I make a selection from the dropdown list the POST Controller Action only the dropdown list is displayed on the page - nothing else. _Layout.cshtml is gone and so are the contents of whatever page I am on.