E. Biagi
E. Biagi

Reputation: 482

Problem receiving form data in the controller. C# - MVC

Friends, I have 3 tables. Person, Student and Address. Person is a general table, has the fields of name, email, phone, etc. And I have an address table to save the student's address. I'm having trouble bringing the information from the address fields dynamically and finalizing a new student registration.I appreciate if anyone can analyze.

This is my code: I created an AddressViewModel class to join the person and address fields. AddressViewModel.cs

public class AddressViewModel
    {

        public string PES_NAME { get; set; }
        public string PHONE { get; set; }
        public string PES_EMAIL { get; set; }
.
.
        //Address
        public string STREET { get; set; }
        public string CITY { get; set; }
        public string STATE{ get; set; }
.
.
    }

AddressContext.cs

public class AddressContext : DbContext
    {
        /*
         * EF Core - ORM
         * ORM -> Bibliteca mapear Objetos para Banco de Dados Relacionais
         */
        public AddressContext(DbContextOptions<AddressContext> options) : base(options)
        {
            
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>()
                .HasOne<Address>(s => s.Address)
                .WithOne(ad => ad.Person)
                .HasForeignKey<Address>(ad => ad.PES_COD);

            modelBuilder.Entity<Person>()
                .HasOne<Aluno>(s => s.Student)
                .WithOne(ad => ad.Person)
                .HasForeignKey<Student>(ad => ad.PersonID);

        }
        public DbSet<Person> Person { get; set; }
        public DbSet<Student> Student { get; set; }
        public DbSet<Address> Address { get; set; }
    }
}

Here I don't know what to do to bring the form data in the right way:

PersonRepository.cs

 public void create(Person person)
        {
            _banco.Add(person);
            
            Student student = new Student();
            student.Status = "A";
            student.DataCadastro = "10/10/2020";
            student.noFormularioRenach = "1010101";
            student.CodSetor = 10;
            student.PersonID = person.PES_COD;

            _banco.Student.Add(student);

            Address address = new Address();
            address.STREET = ????????;
            address.CITY = ????????;

            _banco.Address.Add(address);

            _banco.SaveChanges();
        }

In the case of the student, the information is inserted in the bank because I inform directly in the code, but the student's address I do not know how to bring from the form!

I generated my form automatically like this:

@model LojaVirtual.Models.ViewModels.Student.AddressViewModel

@{
    ViewData["Title"] = "Add";
}

<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Add">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="PES_NAME" class="control-label"></label>
                <input asp-for="PES_NAME" class="form-control" />
                <span asp-validation-for="PES_NAME" class="text-danger"></span>
            </div>
.
.
.
          
            <div class="form-group">
                <label asp-for=PHONE" class="control-label"></label>
                <input asp-for="PHONE" class="form-control" />
                <span asp-validation-for="PHONE" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="PES_EMAIL" class="control-label"></label>
                <input asp-for="PES_EMAIL" class="form-control" />
                <span asp-validation-for="PES_EMAIL" class="text-danger"></span>
            </div>


.
.
            <div class="form-group">
                <label asp-for="CITY" class="control-label"></label>
                <input asp-for="CITY" class="form-control" />
                <span asp-validation-for="CITY" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="STATE" class="control-label"></label>
                <input asp-for="STATE" class="form-control" />
                <span asp-validation-for="STATE" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="STREET" class="control-label"></label>
                <input asp-for="STREE" class="form-control" />
                <span asp-validation-for="STREE" class="text-danger"></span>

.
.
.
.
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>


PersonController.cs

public IActionResult Add([FromForm]Models.Person person, string returnUrl = null)
        {
            if (ModelState.IsValid)
            {
                _clienteRepository.Add(person);
                _loginCliente.Login(person);

                TempData["MSG_S"] = "Success";

                if (returnUrl == null)
                {
                    return RedirectToAction("Index", "Home", new { area = "" });
                }
                else
                {
                    return LocalRedirectPermanent(returnUrl);
                }
            }
            return View();
        }

I appreciate if anyone can help!

Upvotes: 1

Views: 925

Answers (2)

mj1313
mj1313

Reputation: 8459

You can receive these two parameters (Person and Address) separately, then, add address to person.

public IActionResult Add([FromForm] Person person, [FromForm] Address address)
{
    person.Address = address;

    //...

    return View();
}

Upvotes: 2

LinkedListT
LinkedListT

Reputation: 691

Person has a navigation property to Address and Student entities mapped. When you query the database, take advantage of the relationship the Address/Student entity's have to Person entity by using Linq.

Person.cs should look something like this:

public Address Address {get;set;}
public Student Student {get;set;}

Populating Person entitiy:

public void Add(Person person)
{
     //instead initialize person.Student if the form doesn't pass this object
      person.Student = new Student();
        student.Status = "A";
        student.DataCadastro = "10/10/2020";
        student.noFormularioRenach = "1010101";
        student.CodSetor = 10;
        student.PersonID = person.PES_COD;
        //same thing with address
        person.Address = new Address();
        address.STREET = "123 street dr";
        address.CITY = "toronto";

        _context.SaveChanges();
}

Then when retrieving the person object and you need the foreign entities populated too, should look something like this:

using System.Linq;

_context.Person
.Include(x => x.Student)
.Include(x => x.Address)
.Where(x => x.Id == PersonId)
.FirstOrDefault();

Form, should be a view model that is almost identical to your Person DTO:

@model Person


<input asp-for="Address.Street" type="text"/>
<input asp-for"Student.Name" type="text" />

this populates the Foreign key properties in

Upvotes: 0

Related Questions