A few days ago I asked this question about jquery ajax function invoking action in ASP.NET MVC controller. It's now working the way it's supposed to but I encountered another problem and I've been trying to solve it since then.
Scenario is that the player is creating a new character and is given free points to modify the character stats (strenght, agility and intelligence). I'm using view model to pass data from controller to view and TempData["model"] for passing model between controller actions. Everything looks ok on server side. On click, ajax POST request is sent to server invoking ChangeStat method, character stats are modified in the model. Then I redirect to action which renders the View.
My problem is that the data displayed in the View are still the same (i.e. not updated according to modified model). I've read that it's due to MVC validation and so HTML helpers first chceck for old value to display when rendering the same view. I suppose that it's quite a common problem but I wasn't able to find a solution. I've tried using ViewData instead of model, partial view with model/with ViewData but with no result. Below are code snippets. Hope we can find a solution or maybe my approach is wrong and there is better practice to solve this.
Controller action for changing stats:
[HttpPost]
public ActionResult ChangeStat(LobbyModels.StatChange stat)
{
int changeCoef = 0;
LobbyModels.CreateCharModel model = (LobbyModels.CreateCharModel)TempData["model"];
if (model.CharFreePts == 0)
{
return RedirectToAction("Create");
}
switch (stat.ActionName)
{
case "Inc":
changeCoef = 1;
break;
case "Dec":
changeCoef = -1;
break;
}
switch (stat.StatName)
{
case "Str":
model.CharStr = model.CharStr + changeCoef;
break;
case "Agi":
model.CharAgi = model.CharAgi + changeCoef;
break;
case "Int":
model.CharInt = model.CharInt + changeCoef;
break;
}
model.CharFreePts = model.CharFreePts + (changeCoef * (-1));
TempData["model"] = model;
return RedirectToAction("Create");
}
Create method which renders the view:
public ActionResult Create()
{
LobbyModels.CreateCharModel model = LobbyModels.CreateCharModel)TempData["model"];
if (model == null)
{
// null model handling
}
TempData["model"] = model;
return View(model);
}
and in View I render data from model with html helpers
<div id="CharStats">
<%= Html.TextBoxFor(m => m.CharStr)%>
<input type="button" id="Str_Inc" value="+" />
<input type="button" id="Str_Dec" value="-" />
<%= Html.TextBoxFor(m => m.CharAgi)%>
<input type="button" id="Agi_Inc" value="+" />
<input type="button" id="Agi_Dec" value="-" />
<%= Html.TextBoxFor(m => m.CharInt)%>
<input type="button" id="Int_Inc" value="+" />
<input type="button" id="Int_Dec" value="-" />
<br />
<%= Html.TextBoxFor(m => m.CharFreePts)%>
</div>
ChangeStat function is missing some logic but that's not a problem for now. My point is that I need to update textbox value according to current model data (or maybe try different approach completely).