Home > DeveloperSection > Forums > One-to-many relationship in the create action method
Tom Cruser
Tom Cruser

Total Post:28

Points:196
Posted on    December-05-2014 10:13 PM

 ASP.Net SQL Server  Relationship  Relational Database 
Ratings:


 2 Reply(s)
 550  View(s)
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?



Pooja Malohtra
Pooja Malohtra

Total Post:47

Points:331
Posted on    December-06-2014 4:46 AM

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" />


Goti Bandu

Total Post:119

Points:835
Posted on    December-06-2014 5:42 AM

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>


Don't want to miss updates? Please click the below button!

Follow MindStick