ASP.Net MVC ActionResult returns 缓存视图?

ASP.Net MVC ActionResult returns cached View?

在问了几个关于如何根据下拉控件的选定值刷新页面的问题后,我现在有一个新问题 - 我的 "ChangeLanguage" 方法 returns 我的视图的缓存版本不知何故.

查看:

@model ViewModels.HomeViewModel

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/jquery-1.10.2.js" type="text/javascript"></script>
<title id="Title">Default</title>
</head>
<body>
<div class="Header">
    <div class="HeaderTextArea">
        <span id="HeaderText">
            @Model.Title.Where(o => o.Language.Equals(Model.SelectedLanguage)).FirstOrDefault().ControlText
        </span>
    </div>
    <div class="HeaderImageArea">
        <img id="RB_Image" src="~/Content/Images/RB_Logo.png" alt="RB_IMAGE" />
    </div>
    <div class="LanguageSelection">
        @{
            @Html.DropDownList("SelectedLanguage", new SelectList(Model.AvailableLanguages, "ID", "Description"))
        }
    </div>
</div>
<div class="Content">
    @RenderBody()
</div>

<script>
var url = '@Url.Action("ChangeLanguage", "Home")';
$('#SelectedLanguage').change(function () {
    $.getJSON(url, {
        ID: $(this).val(), Model: @Html.Raw(Json.Encode(Model))
        });
});

请注意,这是我的布局视图。我也在我的索引上试过这个,结果相同。

控制器:

public class HomeController : Controller
{
    public ViewModels.HomeViewModel HVM { get; private set; }
    // GET: Home
    public ActionResult Index()
    {
        this.HVM = new ViewModels.HomeViewModel();
        this.HVM.SelectedLanguage = this.HVM.AvailableLanguages.First();
        return View(this.HVM);
    }

    public ActionResult ChangeLanguage(int id, ViewModels.HomeViewModel model) {
        model.SelectedLanguage = model.AvailableLanguages.Where(o => o.ID.Equals(id)).First();
        model.SelectedTitle = model.Title.Where(o => o.Language.Equals(model.SelectedLanguage)).First();
        return View("Index", model);
    }
}

ChangeLanguage 方法被调用,修改所需的数据和 returns "new" 预期的视图 - 视图内的逻辑也完成了它的工作 - 但预期的内容没有显示- 相反,来自 "first View" 的数据出现了。所以数据和显示的数据不一样。

Ps。我知道 Views 应该是愚蠢的,不应该在里面放置任何逻辑——但这只是为了测试目的。最后,所有内容都应该位于我的 ViewModels 中。

如下所示添加 OutputCache 属性

 [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
 public ActionResult ChangeLanguage(int id, ViewModels.HomeViewModel model) {

您没有缓存任何内容。 ajax 调用停留在同一页面上。您正在调用一个 returns 视图(它应该是局部视图)的方法,但是您不对该内容执行任何操作(即更新 DOM)。您的脚本还使用 $.getJSON(),它需要 json,但是您的控制器方法 returns html,所以无论如何它都不会工作。此外,不要使用 @Html.Raw(Json.Encode(Model) 传回整个模型。这将传递您已经可以在控制器中访问的原始模型(未更改),因此它只会降低性能。

您可以考虑 3 个选项

  1. 将所选语言传递给 returns json 的控制器方法 正如我在回答您的 之一时所指出的那样。 这将提供最佳性能
  2. 将所选语言传递给 returns 一个控制器方法 部分视图并更新 DOM

控制器(注意删除 public ViewModels.HomeViewModel HVM { get; private set; }

public PartialViewResult ChangeLanguage(int id) {
  HomeViewModel model = new HomeViewModel();
  model.SelectedLanguage = model.AvailableLanguages.Where(o => o.ID.Equals(id)).First();
  model.SelectedTitle = model.Title.Where(o => o.Language.Equals(model.SelectedLanguage)).First();
  return PartialView(model); // the partial just contains the elements you want to update
}

查看

<div id="mycontent"></div>

$('#SelectedLanguage').change(function () {
  $('#mycontent').load(url, { ID: $(this).val() });
});
  1. 如果您不关心性能,请将下拉列表放在带有提交按钮的表单中并进行正常提交(如果您想生成一个全新的视图,使用 ajax 没有实际意义)