7

My Index.cshtml

@model ReportGenerator.WebUI.Models.ReportViewModel
@Html.TextBoxFor(m => m.report.FileName, new { @class = "form-control", id = "FileName" })

My controller

public ActionResult Index(ReportViewModel model)
{
    ...some stuff
    model.report = new Report();
    model.report.FileName = "INDEX";
    return View(model);
}

public ActionResult fillFields(ReportViewModel _model)
{
    ...some stuff
    _model.report = new Report();
    _model.report.FileName = "FILL";
    return View("Index", _model);
}

When I run my application the TextBox Text property is set to "INDEX". Also when I click on a button which calls the fillFields controller action, the TextBox is still displaying "INDEX", it's not changing to "FILL".

What am I doing wrong? Why it doesn't want to work?

Craig W.
  • 17,838
  • 6
  • 49
  • 82
Icet
  • 678
  • 2
  • 13
  • 31
  • 5
    Your not doing anything wrong. Your `fillFields()` method has a parameter `ReportViewModel` so its values are added to `ModelState` when the method is initialized. When you return the view, your `TextBoxFor()` method uses the value from `ModelState` (not the model property) to set the value of the textbox. The reason for this is explained [here](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111). The correct approach is to follow the PRG pattern –  Oct 05 '15 at 09:12
  • Thanks ! I've used ModelState.Clear(); and it's working – Icet Oct 05 '15 at 09:21
  • 2
    Don't use `ModelState.Clear()`. Follow the PRG pattern and redirect! –  Oct 05 '15 at 09:22
  • ok, I'm going to change it, thanks once again ! – Icet Oct 05 '15 at 09:26
  • @StephenMuecke Oh, I can't do this. Can you give me some example? I have changed name of methods to "Index" and added [HttpPost] and [HttpGet], still TextBox have got "INDEX" – Icet Oct 05 '15 at 11:00
  • 2
    Your `Index()` should not have a parameter `ReportViewModel model` (it can fail for numerous reasons and it creates an ugly query string). Its not really clear what your intent is but best guess is it should be `public ActionResult Index(string fileName)` then initialize your model and set the `FileName` property. In the POST method, use `return RedirectToAction("Index", new { fileName = "FILL" });` –  Oct 05 '15 at 11:05
  • Thanks, now I understand my problem :) – Icet Oct 05 '15 at 11:11
  • @StephenMuecke What Should I do if I want to pass many parametrs ? I can't use RedirectToAction because it's now allowing passing multiple params – Icet Oct 05 '15 at 12:16
  • Of course you can pass multiple parameters. For example if the method is `public ActionResult Index(string fileName, int number)` then `return RedirectToAction("Index", new { fileName = "FILL" , number = 2 });`. Its impossile to be more speciic if you don't explain what your actually trying to do. –  Oct 05 '15 at 21:50
  • @StephenMuecke is it possible to pass an object? – Icet Oct 05 '15 at 22:59
  • 1
    Yes, but (1) if the object contains properties which are complex objects or collections it will fail (2) you can easily exceed the query string limit and throw an exception (3) it creates an ugly query string. –  Oct 05 '15 at 23:02
  • @StephenMuecke please add an answer so I can accept it. – Icet Jun 08 '16 at 07:03
  • 1
    Mihir Kale has added an answer. You can accept that :) –  Jun 08 '16 at 07:06

1 Answers1

1

@StephenMuecke answered this correctly in the comments above.

Your not doing anything wrong. Your fillFields() method has a parameter ReportViewModel so its values are added to ModelState when the method is initialized. When you return the view, your TextBoxFor() method uses the value from ModelState (not the model property) to set the value of the textbox. The reason for this is explained here. The correct approach is to follow the PRG pattern –

Community
  • 1
  • 1
Mihir Kale
  • 1,028
  • 1
  • 12
  • 20