ONE-TO-MANY RELATIONSHIP IN THE CREATE ACTION METHOD

Tom Cruser

Total Post:28

Points:196
Posted by  Tom Cruser
 760  View(s)
Ratings:
Rate this:

I'm currently working on a project that requires add multiple addresses for one client. I have three models: here is a link to my class diagram: http://sdrv.ms/1fWioA2

 

Person model:

 

public class Person

{   

    public Person()

    {

        this.Adresses = new HashSet<Address>();

    }

 

    public int PersonID { get; set; }

 

    [Required(ErrorMessage = "Name is required")]

    public string Name { get; set; }

 

    [Required(ErrorMessage = "Email Address is required")]

    [DisplayName("Email Address")]

    //[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",

    //ErrorMessage = "Email is is not valid.")]

    [DataType(DataType.EmailAddress)]

    public string Email { get; set; }

 

    public string Mobile { get; set; }

    public string Phone { get; set; }

    public string Fax { get; set; }

 

    public virtual ICollection<Address> Adresses { get; set; }

}

address:

 

public class Address

{

    [HiddenInput(DisplayValue = false)]

    public int ID { get; set; }

    public string Street { get; set; }

    public string Building  { get; set; }

 

    public int PersonID { get; set; }

    public int CityID { get; set; }

 

    public virtual City City { get; set; }

    public virtual Person Person { get; set; }

}

I created modelview to bind to my Create view:

 

public class PersonViewModel

{

    public Person Person { get; set; }

    public ICollection<Address> Adresses { get; set; }

}

My question is how to bind the viewmodel to the create view in order to be able to save multiple addresses for the same Person?

  1. Pooja Malohtra

    Post:47

    Points:331
    Re: One-to-many relationship in the create action method

    For this purpose, create an editor template in /Shared/Editor called Address.cshtml:

     

    @model Address

     

    <div class="address">

    @Html.HiddenFor(model => model.ID)

    @Html.HiddenFor(model => model.PersonID)

    @Html.HiddenFor(model => model.CityID)

    @Html.TextBoxFor(model => model.Street) <br />

    @Html.TextBoxFor(model => model.Building  ) <br />

    </div>

    Now, in your View, all you need to do is this:

     

    @Html.EditorFor(v => v.Addresses)

    This will create form fields like this:

     

    <input type="hidden" name="address[0].Id" />

    <input type="hidden" name="address[0].PersonId" />

    <input type="hidden" name="address[0].CityId" />

    <input type="text" name="address[0].Street" />

    <input type="text" name="address[0].Building" />

    <input type="hidden" name="address[1].Id" />

    <input type="hidden" name="address[1].PersonId" />

    <input type="hidden" name="address[1].CityId" />

    <input type="text" name="address[1].Street" />

    <input type="text" name="address[1].Building" />

  1. Goti Bandu

    Post:119

    Points:835
    Re: One-to-many relationship in the create action method

    i recommend you to use client side approach using knockout as example: Server side:

     

     public class HomeController : Controller

    {

        //

        // GET: /Home/

     

        public ActionResult Index()

        {

            var model = new

            {

                person = new { firstName = "123", secondName = "" },

                addresses = new dynamic[1] { new { street = "", building = "", selectedCityId = "" } },

                cities = new dynamic[2] { new { cityName = "Kiev", cityId = "1" }, new { cityName = "Moskow", cityId = "2" } }

     

            };

            return View(model);

        }

     

        public ActionResult Save(YourType model)

        {

            .....

        }

     

    }

    And client side:

     

    @{

    Layout = null;

    }

    @using Newtonsoft.Json;

     

    <!DOCTYPE html>

     

    <html>

    <head>

    <meta name="viewport" content="width=device-width" />

    <title>Index</title>

    </head>

    <body>

    <div style="margin-left:100px">

        <p>First name:</p>

        <input data-bind="value:person.firstName" />

     

        <p>Second name:</p>

        <input data-bind="value:person.secondName" />

        <h3>Addresses</h3>

        <div data-bind="foreach:addresses">

            <p>

                Street

            </p>

            <input data-bind="value:street" />

            <p>

                Building

            </p>

            <input data-bind="value:building" />

            <p>

                City

            </p>

            <select data-bind="options: $parent.cities, optionsText:

               'cityName',optionsValue:'cityId',

                  value: selectedCityId , optionsCaption: 'Choose...'"></select>

            <div>

                <div style="float:left;">

                    <button data-bind="click:$parent.add">

                        Add

                    </button>

                </div>

                <div style="float:left;">

                    <button data-bind="click: $parent.remove">

                        Delete

                    </button>

                </div>

            </div>

            <div style="clear:both"></div>

        </div>

        <button style="width:100px"data-bind="click:save">

            Save

        </button>

     

     </div>

     <script src="~/Scripts/jquery-1.8.2.js"></script>

     <script src="~/Scripts/knockout-3.0.0.js"></script>

     <script src="~/Scripts/knockout.mapping-latest.js"></script>

     <script type="text/javascript">

        //This create javascript object from your model

        var personModel=@Html.Raw(JsonConvert.SerializeObject(Model))

        //Parse javascript object to knockout viewModel

        var viewModel=ko.mapping.fromJS(personModel);

        // Create new address

        function Address(){

            this.selectedCityId=ko.observable("");

            this.street=ko.observable("");

            this.building=ko.observable("");

        }

        //Add new address

        viewModel.add=function(){

            viewModel.addresses.push(new Address());

     

        };

        //Remove address

        viewModel.remove =function(item){

            if(viewModel.addresses().length>1){

                viewModel.addresses.remove(item)

            }        

        };

        //save model

        viewModel.save=function(){

            unmapped=ko.mapping.toJSON(viewModel);

            $.post('/home/save',unmapped)

        };

        ko.applyBindings(viewModel);

    </script>

    </body>

    </html>

Answer

NEWSLETTER

Enter your email address here always to be updated. We promise not to spam!