MVC Controller Action在_Layout.cshtml中从Partial View调用

时间:2014-06-24 04:20:32

标签: asp.net-mvc

在我的_Layout.cshtml中,我想在网站标题中包含一个下拉列表。我并不赞成最好的方法,但我尝试使用PartialView对其进行编码。它似乎正在工作,但是当提交表单时,页面仅加载下拉列表。

视图模型:

namespace XXXX_Web_App.Models
{
    public class LanguageListPartial
    {
        [DataType(DataType.Text)]
        [Display(Name = "Language")]
        public string Language { get; set; }
    }
}

控制器:

[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&#231;ais", Value = "fr-CA" });
    languages.Add(new SelectListItem { Text = "Portugu&#234;s", Value = "pt-BR" });
    languages.Add(new SelectListItem { Text = "Espa&#241;ol", Value = "es-MX" });
    return languages;
}

部分视图

@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>&copy; @DateTime.Now.Year</p>
    </footer>

</div>

</body>
</html>

理想的逻辑是:

每个网站/网页访问

  • 匿名用户 - 从cookie加载选择。默认为英文。 (尚未完成)
  • 经过身份验证的用户 - 从用户个人资料中选择负载(尚未完成)

选择

  • 匿名用户 - 将选择保存到Cookie
  • 经过身份验证的用户 - 将选择保存到Cookie并更新用户个人资料

就像我说的那样,这似乎是有效的,除了当进行选择时,调用Controller动作,当页面重新加载时,页面上的唯一内容就是下拉列表。

在这种情况下如何返回View?

另外一个问题,我希望下拉列表项中的文字包含特定于文化的装饰,但它们显示的字面意思与Fran&#231;ais相似。在这种情况下,我不知道如何使用Html.Encode()。这可能是由于我在GetLanguageList()中添加项目的方式造成的。我该如何避免这种情况?

修改

为了澄清,我在上面的_Layout.cshtml中的摘录就是这样 - 一段摘录。我的_Layout.cshtml包含您可能期望的内容 - 带有徽标和副标题的页眉,导航菜单和RenderBody()代码。页面在部分视图的GET控制器操作中正确显示,但是当我从下拉列表中选择POST控制器操作时,只有下拉列表显示在页面上 - 没有别的。 _Layout.cshtml消失了,我所在页面的内容也一样。

1 个答案:

答案 0 :(得分:1)

提交表单时,会调用/ Account / LanguageList操作。它只返回部分视图:

return PartialView("_LanguageListPartial");

当你只返回时,你的_layout文件不会被调用。

所以你想要的是返回另一个视图。除非您指定它,否则您的所有视图都将包含您的_layout.cshtml文件。这已经包含了局部视图。

因此,当您发布到表单时,创建一个新视图并返回该视图。