Обновить обновленные данные в частичном представлении MVC

У меня есть частичное представление, которое позволяет мне извлекать и редактировать данные из базы данных, используя строго типизированное представление.

Моя модель:

  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

дата: вс, 08 сен 2013 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

Как указал ниже Пол Д'Амбра, мой 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);
    }

person William Smith    schedule 08.09.2013    source источник
comment
Это очень похоже на то, что браузер обслуживает страницу из своего локального кеша, поэтому я думаю, что вы на правильном пути с OutputCache. Какие заголовки ответа при загрузке страницы?   -  person Paul D'Ambra    schedule 08.09.2013
comment
@PaulD'Ambra Привет, Пол, пожалуйста, смотрите мое обновление выше.   -  person William Smith    schedule 08.09.2013
comment
Итак, в заголовках нет ничего, что могло бы помешать клиенту кэшировать страницу... но оно обновляется, если вы меняете значение... странно   -  person Paul D'Ambra    schedule 08.09.2013
comment
Необычно иметь dbContext в модели ... и я изо всех сил пытаюсь понять, что произойдет с кэшированием и проксированием, которое EF будет делать с экземплярами модели. Обычно ваш контроллер будет иметь dbContext (или какой-либо тип, который его обертывает), и каждый вызов GetRow в контроллере будет вызывать dbContext для элемента с этой моделью...   -  person Paul D'Ambra    schedule 09.09.2013
comment
Спасибо, Павел, это была проблема. Я переместил функциональность GetRow в свой контроллер, изменил представление индекса обратно на исходное, и, похоже, он работает нормально. Я пытаюсь научиться использовать MVC, и с самого начала я боролся с тем, что происходит в модели и что происходит в контроллере. Отсутствие dbContext в модели, очевидно, является хорошим правилом. Я поместил свой обновленный контроллер выше как обновление 4, если кто-то еще сочтет его полезным.   -  person William Smith    schedule 09.09.2013


Ответы (3)


Попробуйте использовать ModelState.Clear() в своем методе редактирования.

[HttpPost]
public ActionResult Edit(Associate associate)
{
    ModelState.Clear();
    ...
person JK.    schedule 09.09.2013

Если это проблема с кэшированием, вы можете определить это, добавив (для выявления проблемы)

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.

Это говорит клиенту не кэшировать ответ, чтобы вы могли исключить это (и вы сможете увидеть влияние этих изменений в заголовках ответа).

person Paul D'Ambra    schedule 08.09.2013
comment
Я очень ценю вашу помощь в этом. Пожалуйста, смотрите мое второе обновление выше. Это изменения в заголовках моих ответов: cache-control: no-cache, no-store, must-revalidate pragma: no-cache - person William Smith; 09.09.2013

Попробуй это.

 $(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);
    }
}
person Rashad Valliyengal    schedule 21.02.2014