开发者

Not updated data after post (mvc razor)

I am using "Composite C1" cms, mvc and razor view engine. Some page should show list items and user could filter data by some criteria. First part works fine (items are shown without problems), I have problem with second part - filtered data is not updated, page displays old data.

I have ItemsController:

public class ItemsController : Controller
{
    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult Filter()
    {
        // Initialize all filter comboboxes for Items page
        // ...
        return View(new MyModel());
    }

    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult List()
    {
        // Set first default items
        ViewBag.Items = (IEnumerable)GetRandomItems(8);

        return View(new MyModel());
    }

    [HttpPost]
    [ValidateInput(true)]
    [OutputCache(CacheProfile = "ZeroCacheProfile")]
    public ActionResult List(MyModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // Set filtered items
        // ...
        ViewBag.Items = (IEnumerable)itemList;

        return Json(new { Success = true, Filter = filter, ItemNumber = itemList.Count }, JsonRequestBehavior.AllowGet);
    }
}

And I have two views: "List.cshtml" - in order to display data and "Filter.cshtml" - in order to generate criteria to filter data.

"Filter" view has script that does query to /Items/List, - in order to filter and update data.

<script type="text/javascript" language="javascript">
/* <![CDATA[ */
    $(document).ready(function () {
        $("#search_button_filter").bind('click', function() {
            var $form = $("#filter_form");
            $.ajax({
                url: '/Items/List/default.aspx',
                type: 'POST',
                data: $form.serialize(),
                success: function (data) {
                    if (data.Success) {
                        // Show report: amount of filtered items, etc.
                        // ...
                    }
                }
            });
            return false;
        });
    });
/* ]]> */
</script>

I checked - "ActionResult List(MyModel model)" set correct filtered data in next code line

ViewBag.Items = (IEnumerable)itemList;

But "List" view continue to display previous data.

Probably, someone tell me way to solve my problem.

Thank you.

New Update

I remade my solution and it works now. The same two 'List' and 'Filter'开发者_JAVA百科 views on my page, but without any Rest/Post, just Get and QueryString:

<script type="text/javascript" language="javascript">
/* <![CDATA[ */
    $(document).ready(function () {
        $("#search_button_filter").bind("click", function() {
            var $filter1 = $("#filter1_search_filter").val();
            var $filter2 = $("#filter2_search_filter").val();
            var $filter3 = $("#filter3_search_filter").val();
            window.location.href = "@UrlUtil.ItemsPageUrl" + "?&filter1=" + $filter1 + "&filter2=" + $filter2 + "&filter3=" + $filter3;
        });
    });
/* ]]> */
</script>

But I have very small problem now. Amount of items is calculated in 'ActionResult List()' method (which initializes 'List' view), but I need display this value on 'Filter' view. I tried to use TempData collection - set

[OutputCache(CacheProfile = "ZeroCacheProfile")]
public ActionResult List()
{
    TempData["AmountOfFilteredItems"] = null;

    Guid filter1;
    if (!Guid.TryParse(Request.QueryString["filter1"], out filter1))
    {
        filter1 = Guid.Empty;
    }

    Guid filter2;
    if (!Guid.TryParse(Request.QueryString["filter2"], out filter2))
    {
        filter2 = Guid.Empty;
    }

    Guid filter3;
    if (!Guid.TryParse(Request.QueryString["filter3"], out filter3))
    {
        filter3 = Guid.Empty;
    }

    List<MyModel> items;
    if ((filter1 == Guid.Empty) && (filter2 == Guid.Empty) && (filter3 == Guid.Empty))
    {
        items = GetRandomItems(8);
    }
    else
    {
        items = GetFilteredItems(filter1, filter2, filter3);
    }

    TempData["AmountOfFilteredItems"] = items.Count;

    return View(items);
}

value in 'ActionResult List()' method of 'Items' controller and return this value in 'Filter' view:

@model MyModel
@using (Html.BeginForm("Items", "Filter", FormMethod.Post, new { @id = "filter_form" }))
{
    <!-- Fill required data -->
    <!-- ... -->
    <font class="bold">@(TempData["AmountOfFilteredItems"].NotNull() ? TempData["AmountOfFilteredItems"] : 0)</font>
}

Just one problem this value is always delayed by one step/iteration - if real amount of items is '2' then view displays previous value '8'. And next time when real number is '0' then it displays previous real value '2'.

How I can solve it?


The HTML in the browser won't update unless you update it. The code in the browser is disconnected from what's happening on the server. If you use Ajax to send a request to the server, then you need to process the response and do something with it.

If you want to use Ajax, you need to make sure your List(MyModel) method returns a partial view, and then overwrite a section of your DOM with it.

However, the easiest thing might be to remove the Ajax and just handle it as a normal page postback - this will be much simpler. It's a little old, but there's some info on form posts in MVC here:

http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx


I just read that the purpose of TempData is to provide data for the "next" request, so I wonder if the "current" request only sees TempData from the "previous" request, hence it's out of step.

Try changing to ViewBag instead, and see if that fixes the problem.

Eg. in my Action I added:

ViewBag.ItemCount = 10;

(Note: it's a dynamic object, so you can make properties up as you go).

Then to display it, I added this to my view:

Count: @ViewBag.ItemCount

Seems to work as expected.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜