0

So I have a form that displays addresses for people (most of these people have multiple addresses) the form displays the current address listed and will allow them to update the city name. When I click the save button, the model does not get passed back. Some of this had to be modified so the logic could be simplified so sorry ahead of time if it seems off. When I save the HttpPost actionresult method returns the model as null. What am I doing wrong?

Controller:

[HttpGet]
    public ActionResult CANBudgets(int addressId)
    {
        PersonRepository.PersonDetailsModel model = new PersonRepository.PersonDetailsModel();
        model.Addresses= model.Addresses.Where(a => a.Address_Id == addressId).ToList();

        return PartialView(model);
    }

    [HttpPost]
    public ActionResult Address(PersonModel.PersonDetailsModel pplModel)
    {
        return PartialView(pplModel);
    }

Model:

    public class PersonDetailsModel : Person
    {
        public int? Person_Id { get; set; }
        public string Person_First_Name { get; set; }
        public string Person_Last_Name { get; set; }
        public List<AddressDetails> Addresses
        {
            get
            {
                return _entities.SelectAddresses(Person_ID).Select(a => new AddressDetails
                {
                    Address _Id = a.Address _Id
                     ,
                    Address = a.Address 
                     ,
                    State = a.State 
                     ,
                    City = a.City 
                     ,
                    Zip_Code = a.Zip_Code 
                }
                ).ToList();
            }

            set
            {

            }
        }
    }

View

@using Personnel.ViewModel;
@using Personnel.Repository;
@model  PersonModel.PersonDetailsModel

    @using (Html.BeginForm("Address", "Person", FormMethod.Post, new { pplModel = Model }))
{
    <div class="row can-totals">
        <div class="table-responsive col-md-5">
            <table class="table table-bordered table-condensed table-responsive address-tbl" id="tblAddrSummary" summary="Address Summary" style="padding-left: 10px;">
                <thead>
                    <tr class="summary-header">
                        <th class="dt-head-center">#</th>
                        <th class="dt-head-center">Person Address</th>
                    </tr>
                </thead>
                <tbody>
                    @{
    int index = 0;
                    }

                    @foreach (var item in Model.Addresses)
                    {
                        <tr>
                            <td class="addr-number">@String.Format("{0} - {1}", @item.Address_Id, @item.Address)</td>


                            <td class="addr-city">@Html.TextBox("city", Model.Addresses[index].City, new { @class = "form-control" })</td>
                        </tr>
                        index++;
                    }
                </tbody>
            </table>
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Save</button>

}
cxwilson
  • 107
  • 1
  • 5
  • 15
  • Your `Addresses` setter is nonsensical. – leppie Jul 05 '16 at 19:06
  • Try removing "new { pplModel = Model }" from the Html.BeginForm. It's not needed. – Big Daddy Jul 05 '16 at 19:13
  • @BigDaddy that didn't help unfortunately. When I debug the parameter said that the function evaluation timed out – cxwilson Jul 05 '16 at 19:26
  • There should be another Address controller method. Where is that? – derloopkat Jul 05 '16 at 19:40
  • @derloopkat I have one, it's a HttpGet. it works just fine – cxwilson Jul 05 '16 at 19:42
  • Your controller is expecting to be called by post and receiving model as parameter. But the first time you call it is by get without model, hence model is null. Typically I have an action method for displaying the form by get and another action for saving the model by post. Both have the same name but parameters and verb are different. – derloopkat Jul 05 '16 at 19:47
  • @derloopkat can you post an example? Are you saying pass the model in the get also? I am initializing the model in the get and sending the partial view the model. Just don't have the model in the parameter – cxwilson Jul 05 '16 at 19:51
  • Depends on what you want to do. If the form is for creating a record, fields must be empty first time. If the form is for editing, then you receive an id, get the item from db and pass it to the view (passing model or using viewbag, viewdata, etc). In any case when user press save, you will be running a different action method, the one that receives model by post. – derloopkat Jul 05 '16 at 20:01
  • See this article https://blog.michaelckennedy.net/2012/01/20/building-asp-net-mvc-forms-with-razor/ Note there are two methods "Create". One is for displaying an empty form for the user to enter data. The second is for saving the form after user clicks save. That makes sense because in the method you need to do different things. The one that receives the model as parameter is going to save. Then user is redirected to default page indicating information was saved. – derloopkat Jul 05 '16 at 20:04
  • @derloopkat on my httpget, I actually need to pass it some data for display purposes though. I will updated with the get – cxwilson Jul 05 '16 at 20:24
  • MVC is not Web Forms...there is no ViewState concept to hold on to data between requests. Your Razor view is generating a plain HTML form. You'll need to add inputs to it so they're submitted when the submit button is clicked. MVC will try to match up the input names with the property names on your model. – Spivonious Jul 05 '16 at 20:33
  • @Spivonious example? there Is a way to pass back the model with the input data as stated above. were doing it in other place in the app but for some reason here it's null. – cxwilson Jul 05 '16 at 20:35
  • You cannot use a `foreach` loop to generate form controls for a collection (refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943)). Then change the property to `public List Addresses { get; set; }` and remove `new { pplModel = Model })` from `BeginForm()` (which is adding html attributes) –  Jul 05 '16 at 22:27
  • @masta_coda - http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ should help you out. – Spivonious Jul 06 '16 at 12:27
  • @StephenMuecke This is not the problem, I have removed the parameter and the foreach actually renders the name value just fine. – cxwilson Jul 06 '16 at 14:13
  • Did you even bother to read the link. It might show the correct values in the view but its utterly pointless because nothing else works (it cannot bind to your model when you submit the form)! –  Jul 06 '16 at 21:38

0 Answers0