-1

I have a class "Client" and "Address". Each Client can have more then one address i.e. Postal and Residential.

I have created ModelView of them to use for data entry in razor: MODEL VIEW:

Public class Client
{
    public int ClientID { get; set; }
    public string ClientName {get;set;}
}

Public class Addresses
{
    public int ClientID { get; set; }
    public int AddressType {get;set;}
    public string Addr {get;set;}
}

Public class ClientsInfoModelView
{
public Client clnt{get;set;}
public List<Addresses> addr {get;set;}
}

Controller (ClientsController):

Public ActionResult Index()
{

    ClientsInfoModelView  _MV = new ClientsInfoModelView();
   _MV.clnt = Context.Client.FirstOrDefault(w=> w.ClientID=1);

    _MV.Addr = Context.Addresses.FirstOrDefault(w=> w.ClientID=1);

    return View("index",_MV);

}
Public ActionResult SAVE(ClientsInfoModelView data)
{
// here data.addr is null, where as clnt has data as per filled in the form
}

Razor
@model ModelViews. ClientsInfoModelView
@using (Html.beginform(“SAVE”,”Clients”,FormMethod.post))
{
    @html.TextBoxFor(m=> m. ClientID);
    @html.TextBoxFor(m=> m. ClientName);
Address:
Postal:         @html.TextBoxFor(m=> m. addr(w=> w. AddressType==1). Addr)
Residential:    @html.TextBoxFor(m=> m. addr(w=> w. AddressType==2). Addr)
<button type=”submit”> Save </button>
}

Display works fine. I can see the data populated for Client as well as the address but Issue arises where I click save button . Controller is receiving null for Addr property, which is referring List.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
user3513192
  • 97
  • 2
  • 14
  • Your `@html.TextBoxFor(m=> m. addr(w=> w. AddressType==1). Addr)` does not make sense and would not even compile so this is not your real code. If you wanting to add only a postal and residential address, then you model would have propertoes `Addresses PostalAddress` and Addresses ResidentialAddress`. If your wanting to add unlimited addresses to the collection, then refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Jan 28 '18 at 03:26
  • Refer also [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for general information about how to bind to collections –  Jan 28 '18 at 04:20

1 Answers1

0

Well, I don't think you can use following syntax to bind your text box to your model

@html.TextBoxFor(m=> m. addr(w=> w. AddressType==1). Addr)

This is because addr is type not a method. So obvious next thing comes to mind is to write the same syntax with where clause eg..

@Html.TextBoxFor(m => m.addr.Where(o=>o.AddressType == 1).Select(p=>p.Addr).FirstOrDefault());

But this will also throw run time exception as where clause might return 0 to n number of element and compilar is not able to understand which one to bind.

Solution:

First get the index of residential and postal address block from list and directly use that index to parse addr List.

  @{int postalAddressIndex = @Model.addr.FindIndex(o => o.AddressType == 1);
int residentialAddressIndex = @Model.addr.FindIndex(o => o.AddressType == 2);}
@using (Html.BeginForm("SAVE","Client",FormMethod.Post))
{
@Html.TextBoxFor(m=> m. clnt.ClientID)
@Html.TextBoxFor(m => m.clnt.ClientName)
<br/>
@Html.Label("Address:")
<br/>
@Html.LabelFor(m=> m.addr[postalAddressIndex].AddressType,"Postal:")        
@Html.TextBoxFor(m=> m.addr[postalAddressIndex].Addr);
@Html.HiddenFor(m => m.addr[postalAddressIndex].AddressType); 
@Html.HiddenFor(m => m.addr[postalAddressIndex].ClientID);                                                                                  
<br/>
@Html.LabelFor(m => m.addr[residentialAddressIndex].AddressType, "Residential:") 
@Html.TextBoxFor(m => m.addr[residentialAddressIndex].Addr);
@Html.HiddenFor(m => m.addr[residentialAddressIndex].AddressType);
@Html.HiddenFor(m => m.addr[residentialAddressIndex].ClientID);
<button type="submit"> Save </button>

Output: enter image description here enter image description here