【问题标题】:Refresh updated data in MVC partial view在 MVC 局部视图中刷新更新的数据
【发布时间】:2013-09-08 14:59:26
【问题描述】:

我有一个局部视图,允许我使用强类型视图从数据库中检索和编辑数据。

我的模特:

  public partial class Associate
{
    public Associate()

    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
....

public Associate GetRow(int count)
    {
        Associate a = new Associate();
        var query = from rows in db.Associates orderby rows.ID select rows;
        if (count > 0)
        {
            foreach (var row in query.Skip(count - 1).Take(1))
            {
                a = row;
            }
            return a;
        }
....

我的控制器:

 public ActionResult GetRow(int count)
    {
        return PartialView("Edit", new MVC.Models.Associate().GetRow(count));
    }

    [HttpPost]
    public ActionResult Edit(Associate associate)
    {
        if (ModelState.IsValid)
        {
            db.Entry(associate).State = EntityState.Modified;
            db.SaveChanges();
            return PartialView("Edit",associate);
        }
        return RedirectToAction("../Error");
    }

我的索引视图:

   <script>
    $(document).ready(function () {
     $('#record').change(function () {
    if (/^[0-9]+$/.test($("#record").val()) == true) {
        $.ajax({
            type: "POST",
            url: "Associate/GetRow",
            data: { count: $('#record').val() },
            success: function (data) {
                $('#FormContainer').html(data)
            },
            error: function (result) {
                alert(result.responseText);
            }
        });
    }
})  
   });
   </script>

<div id="FormContainer">
</div>
<input type=text id="record" style="width:3em; top:-0.7em;position:relative" />

和我的部分观点:

  @model MVC.Models.Associate


 <script type="text/javascript" >
.....
 var form = $('#form1');
                $.ajax({
                    type: form.attr('method'),
                    url: form.attr('action'),
                    data: form.serialize(),
                    success: function (data) {
                    },
                    error: function (result) {
                        alert(result.responseText);
                    }
                });
....
</script>
 @using (Html.BeginForm("Edit", "Associate", FormMethod.Post, new { id = "form1" }))
{
@Html.ValidationSummary(true)
<fieldset>
    <legend>Contacts</legend>
    @Html.HiddenFor(model=>model.ID)
        <div class="editor-label">
        @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
        @Html.EditorFor(model => model.FirstName)
        @Html.ValidationMessageFor(model => model.Type)
        </div>

        <div class="editor-label">
        @Html.LabelFor(model => model.LatName)
        </div>
        <div class="editor-field">
        @Html.EditorFor(model => model.LastName)
        @Html.ValidationMessageFor(model => model.LastName)
        </div>
.....

当我在索引表单的#record 输入中输入新值时,Associates/GetRow 会返回正确的关联 - 这是有效的。当表单失去焦点时调用 ajax 函数来更新记录(代码未显示)。当我编辑表单上的字段并移动焦点时,数据库中的基础数据将更改为新值 - 因此检索记录和更新记录都可以正常工作。

但是,当我编辑一条记录然后移动到下一条记录然后返回到已编辑记录时,已编辑记录中的更新值不会显示。因此 Associates/GetRow 操作返回旧值,而不是从数据库中获取新值。或者,如果我编辑一个字段,然后手动或通过代码刷新整个页面或部分视图,即使新值存储在基础数据库中,新值也会被旧值替换。

我试过了 [OutputCache(Duration=0)] 在我的控制器中没有成功。

任何建议将不胜感激。

更新 1:

响应头是:

服务器:asp.net开发服务器/10.0.0.0

日期:2013 年 9 月 8 日星期日 19:21:16 GMT

x-aspnet-版本:4.0.30319

x-aspnetmvc-版本:3.0

缓存控制:私有

内容类型:文本/html;字符集=utf-8

内容长度:2910

连接:关闭

如果我关闭浏览器窗口并清除缓存的网页,包括表单输入,甚至是我的项目中的 Ctrl 和 F5 以重建网页,旧数据仍会显示。我发现显示新数据的唯一方法是对项目进行更改并保存更改然后重建项目。然后显示新数据。

更新 2:

我找到了另一种显示新数据的方法,它可能显示正在发生的事情。我已将我的索引视图更改为包括:

 <div id="FormContainer">
 @Html.Partial("Edit", new MVC.Models.Associate().GetRow(1))
 </div>

然后编辑第一条记录。 当我编辑第一条记录然后使用#record 输入移动到新记录并返回时,旧值仍然显示。但是,如果我手动刷新页面,则现在会为第一条记录显示新值。

当我在 GetRow 函数中包含您建议的代码时,即使我用上面的索引视图的更改刷新页面,新值也不会显示。

更新 3:

我已经改变了我的索引视图,如下所示:

<script>
$(document).ready(function () {
    $('#Button1').click(function(){
        RefreshPartial();
    })
 });

  function RefreshPartial() {
    $('#FormContainer').load('/Associate/GetRow', {count:1});    
  }
</script>
 <input id="Button1" type="button" value="button" />
 <div id="FormContainer">
  @Html.Partial("Edit",new MVC.Models.Associate().GetRow(1))
 </div>

所以现在我有两种替代方法来获取第一条记录。

如果我编辑记录中的字段,然后单击按钮 RefreshPartial 函数运行,新值将替换为旧值。如果我然后刷新页面以便 @Html.Partial 代码运行旧值将替换为新值。如果我关闭浏览器并重新打开它,旧值在所有情况下都会显示。

底层数据库中的值始终是新值。

更新 4

正如 PaulD'Ambra 在下面指出的,我的 GetRow 应该从模型中获取项目,而不是成为模型的一部分。这是用于从数据库中检索记录的 GetRow 控制器操作:

 public ActionResult GetRow(int count)
    {
        Associate a = new Associate();
        var query = from rows in db.Associates orderby rows.ID select rows;
        if (count > 0)
        {
            foreach (var row in query.Skip(count - 1).Take(1))
            {
                a = row;
                a.record_count = count;
            }
        }
        else
        {
            foreach (var row in query.Skip(query.Count() + 1).Take(1))
            {
                a = row;
                a.record_count = count;
            }
        }
        return PartialView("Edit", a);
    }

【问题讨论】:

  • 这听起来很像浏览器正在从其本地缓存中提供页面,所以我认为你在使用 OutputCache 的道路上是正确的。加载页面时的响应标头是什么?
  • @PaulD'Ambra 嗨,保罗请看我上面的更新。
  • 因此,标头中没有任何内容可以阻止客户端缓存页面...但是如果您更改值,它会更新...奇怪
  • 在模型中包含 dbContext 是不寻常的......我正在努力了解缓存和代理 EF 对模型实例的影响。通常,您的控制器将具有 dbContext(或包装它的某种类型),并且每次调用控制器中的 GetRow 都会调用具有该模型的项目的 dbContext...
  • 谢谢保罗,这就是问题所在。我已将 GetRow 功能移到我的控制器中,将索引视图更改回原始视图,它似乎工作正常。我正在尝试学习使用 MVC,并且我从一开始就一直在努力研究模型中的内容和控制器中的内容。模型中没有 dbContext 显然是一个好规则。如果其他人觉得它有用,我会将更新后的控制器作为 Update 4 放在上面。

标签: jquery asp.net-mvc asp.net-mvc-partialview


【解决方案1】:

尝试在您的 Edit 方法中使用ModelState.Clear()

[HttpPost]
public ActionResult Edit(Associate associate)
{
    ModelState.Clear();
    ...

【讨论】:

    【解决方案2】:

    如果这是一个缓存问题,您可以通过添加来识别它(为了识别问题)

    HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1))
    HttpContext.Current.Response.Cache.SetValidUntilExpires(false)
    HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches)
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache)
    HttpContext.Current.Response.Cache.SetNoStore()
    

    进入您的 GetRow 方法。

    这告诉客户端不要缓存响应,以便您可以排除这种情况(您将能够在响应标头中看到这些更改的影响)。

    【讨论】:

    • 非常感谢您在这方面的帮助。请参阅我上面的第二次更新。这些是我的响应标头的更改: cache-control: no-cache, no-store, must-revalidate pragma: no-cache
    【解决方案3】:

    试试这个。

     $(document).ready(function () {
                var url = "@(Html.Raw(Url.Action("ActionName", "ControllerName")))";
                $("#PartialViewDivId").load(url);
            setInterval(function () {
                var url = "@(Html.Raw(Url.Action("ActionName", "ControllerName")))";
                $("#PartialViewDivId").load(url);
            }, 30000); //Refreshes every 30 seconds
    
            $.ajaxSetup({ cache: false });  //Turn off caching
        });
    

    它会进行初始调用以加载 div,然后以 30 秒为间隔进行后续调用。

    在控制器部分,您可以更新对象并将对象传递给局部视图。

    public class ControllerName: Controller
    {
        public ActionResult ActionName()
        {
            .
            .   // code for update object
            .
            return PartialView("PartialViewName", updatedObject);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      相关资源
      最近更新 更多