0

I'm new to mvc and I'm struggling with this model stuff. My understanding is that I can only use one model per action.

public class TestModel
{
    public string foo1 { get; set; }
    public string foo2 { get; set; }
    public string foo3 { get; set; }
}

I want to partially load my model in the normal action:

    public ActionResult Index()
    {
        TestModel model = new TestModel();
        model.foo1 = "foo1";
        return View(model);
    }

Then the user should add data to the model from the view.

@model SAS_MVC.Models.Test.TestModel

@using (Html.BeginForm())
{
   @Html.EditorFor(model => model.foo1, new { htmlAttributes = new { @class = "form-control" } })
   @Html.EditorFor(model => model.foo2, new { htmlAttributes = new { @class = "form-control" } })
   @Html.EditorFor(model => model.foo3, new { htmlAttributes = new { @class = "form-control" } })

   <input type="submit" value="submit" />
}

According to the user's data I have to add further data in the post controller:

    [HttpPost]
    public ActionResult Index(MyModel model, FormCollection form)
    {
        // get some data from DB

        model.foo3 = 123;
        return View(model);
    }

How can I save this model permanently? I have problems with e.g. foo3 is empty in the view. I want to pass the model between the post-controller and view several times without losing data.

I did try with TempData and ViewBag but for me this is very uncomfortable to work with... no intellisense.

So how can I do it right? Thanks for help!

Update with EF6:

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class TestController : Controller
{
    DB03SASModel dbModel = new DB03SASModel();

    // GET: Test
    public ActionResult Index()
    {
        MyEntity model = new MyEntity();
        model.Name = "AAAA";
        dbModel.MyEntities.Add(model);
        dbModel.SaveChanges();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyEntity model)
    {
        model.Name = "BBBB";
        dbModel.SaveChanges();
        //UpdateModel(model);
        return View(model);
    }
}

View

@model SAS_MVC.MyEntity

@using (Html.BeginForm())
{
  @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
  @Html.DisplayFor(model => model.Id, new { htmlAttributes = new { @class = "form-control" } })
  @Html.HiddenFor(model => model.Id, new { htmlAttributes = new { @class = "form-control" } })


  <input type="submit" value="submit" />
}

Now I save the model using EF Code First and I checked it in the DB --> every thing is well saved. But: Again the view take the wrong value and I still struggle. I found out the the @Html.HiddenFor provide me the current ID of the entity in the post controler. Than I changed the value to "BBBB" and than I pass the exact same entity back to the view but the view never did an update! I don't get it sorry. When I try with UpdateModel(model); "AAAA" is again my value! Where did this value come from? In the DB there is no such value at this time!! What did I wrong??

GertR
  • 75
  • 1
  • 7
  • 3
    The correct pattern is to Save the data when the post occurs and everytime you need that data you need to get from database – Leandro Soares Jun 20 '16 at 14:20
  • `I can only use one model per action` Not exactly true. Let's say you have a form that for whatever reason needs to post both a Customer model and an Order model at the same time. You can create a new model CustomerOrder that includes both a Customer property and an Order property, thus allowing you to post both at the same time. – mason Jun 20 '16 at 14:22
  • Take a look at PRG pattern. This will help you started [How do I include a model with a RedirectToAction?](http://stackoverflow.com/questions/11209191/how-do-i-include-a-model-with-a-redirecttoaction) – Shyju Jun 20 '16 at 14:23
  • 1
    You can use only one model at a time, but as @mason aluded to, this model can be as complicated as you like. It's hard to see it as a limiting factor. What do you mean by "How can I save this model permanently?". Do you mean persist as in write to a database? Replace MyModel with TestModel and you get the values in that from the web page form. MVC binding does this for. – Ian Jun 20 '16 at 15:02
  • Assuming you are using Entity Framework, you'll use context.SaveChanges(); to save the value to the db. – nurdyguy Jun 20 '16 at 16:17
  • 1
    You can remove the pointless `FormCollection form` parameter. You should follow the PRG pattern, but to explain why setting `model.foo3 = 123;` and then returning the view will not display `123` in the view, refer the second part of [this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) –  Jun 21 '16 at 03:09

1 Answers1

0

Saving the model should happen in the post action, and to save the model permanently so you should save it to the database, that requires you to map your model to a database table, and to do that you should create a database and create a table that will hold your model data then use Entity framework or any other ORM to map your model with the database table.

Update 1:

You are saving the model to the database in two places, first in the get action and then in the post action, so every time you save "BBB" in the post action it will get overridden in the get action to "AAAA", so here is how your code should be :

public class TestController : Controller
{
    TestEntities dbModel = new TestEntities();

    public ActionResult Index(int? id)
    {
        MyEntity model = new MyEntity();
        if (id.HasValue)
            model = dbModel.MyEntity.First(m => m.Id == (id ?? 0));

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyEntity model)
    {
        dbModel.MyEntity.Add(model);
        dbModel.SaveChanges();

        return RedirectToAction("Index", new { id = model.Id });
    }
}

as you see saving the data to the database only happen in the post action, the get action is to get the data back from the database.

Bassem
  • 54
  • 3
  • 2
    Welcome to Stackoverflow! To be sure you are providing a great answer, please be sure to include some code or more detailed instructions on how to complete the task you described. – buczek Jun 20 '16 at 15:51
  • Thanks a lot to @Bassem! When routing my model with your `RedirectToAction` over the get action it is working perfect. – GertR Jun 23 '16 at 06:39
  • @buczek is my post to less detailed? – GertR Jun 23 '16 at 06:42