We use ASP.NET MVC 5's AjaxHelper
and Ajax.BeginForm
to request a partial view. That request also needs some JSON data in order to update a map control.
The view rendering part of the process works great (a table body is replaced with the strongly-typed partial view), but the JSON data (embedded into the data-json
attribute of the div
element as described in this answer and retrieved in my OnSuccess
function) always has the same value.
To eliminate the controller code or ViewBag as culprit, I replaced the JSON data (originally retrieved from the ViewBag) with a direct call to DateTime.Now
. Sure enough, the same DateTime is printed each time in updateMap()
(e.g., 2/11/2016+5:24:42+PM
)
I've tried disabling caching, and changing the HTML method to Post, in my AjaxOptions
.
In the Parent View (changing the ListBox selection submits the form):
@model string
@{
ViewBag.Title = "Project List";
AjaxOptions ajaxOpts = new AjaxOptions
{
UpdateTargetId = "tableBody",
OnSuccess = "updateMap",
HttpMethod = "Post",
AllowCache = false
};
}
@using (Ajax.BeginForm("GetProjectsData", ajaxOpts))
{
<fieldset>
<legend>Project State</legend>
<div class="editor-field">
@Html.ListBox("selectedStates", ViewBag.StatesList as MultiSelectList,
new { @class = "chzn-select", data_placeholder = "Choose States...", style = "width:350px;", onchange = "$(this.form).submit();" })
</div>
</fieldset>
}
<table class="table">
<thead>
<tr>
<th>
Project Name
</th>
<th>
Project Firm
</th>
<th>
Project Location
</th>
<th>
Building Type
</th>
<th>
Project Budget
</th>
<th></th>
</tr>
</thead>
<tbody id="tableBody">
@Html.Action("GetProjectsData", new { selectedStates = Model })
</tbody>
</table>
<script>
function updateMap() {
var jsonData = $("#geoJsonData").attr("data-json");
var decoded = decodeURIComponent(jsonData);
console.log(decoded); // always prints same value
}
</script>
The partial view:
@model IEnumerable<OurModel>
<div id="geoJsonData" data-json="@Url.Encode(DateTime.Now.ToString())"></div>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
@Html.DisplayFor(modelItem => item.COMPANY_NAME)
</td>
<td>
@Html.DisplayFor(modelItem => item.STATE)
</td>
<td>
@Html.DisplayFor(modelItem => item.BUILDING_TYPE)
</td>
<td>
@Html.DisplayFor(modelItem => item.BUDGET_AMT)
</td>
</tr>
}
I'm hesitant to jettison the MVC helper classes' pattern of returning a partial view and instead manually render a view into a JSON object. Why is the updated tablebody visible on screen, but when jQuery requests the div element it always has the same data?
Interesting...replacing the div with a good old hidden input element worked. Now fresh data is retrieved each time.
This
<div id="geoJsonData" data-json="@Url.Encode(DateTime.Now.ToString())"></div>
Became this
<input id="geoJsonData" type="hidden" value="@Url.Encode(DateTime.Now.ToString())" />
I wonder why the data-json
in the div
remained "stale" while the value
of the input
field did the trick?