Solved

ASP.NET MVC Create/Edit ViewModel

Posted on 2016-09-23
7
69 Views
Last Modified: 2016-10-03
Hello Experts,

I'm trying to create one Action to handle my Create/Edit instead of having two separate actions one for Create and the other for Edit. Currently, my CustomerController Action below shows that two Action Methods (Create/Edit) which both work. I would like to be able to combine both of those into just one Action.

Customer Model:

    public class Customer
    {
        public int CustId { get; set; }
        public string CustDisplayName { get; set; }
        public string CustFirstName { get; set; }
        public string CustLastName { get; set; }
        public string CustCompanyName { get; set; }
        public string CustAddress { get; set; }
        public string CustPhoneNumber { get; set; }
        public string CustMobileNumber { get; set; }
        public string CustEmailAddress { get; set; }

        public int StId { get; set; }
        public State State { get; set; }
    }

Open in new window


State Model:

    public class Customer
    {
        public int CustId { get; set; }
        public string CustDisplayName { get; set; }
        public string CustFirstName { get; set; }
        public string CustLastName { get; set; }
        public string CustCompanyName { get; set; }
        public string CustAddress { get; set; }
        public string CustPhoneNumber { get; set; }
        public string CustMobileNumber { get; set; }
        public string CustEmailAddress { get; set; }

        public int StId { get; set; }
        public State State { get; set; }
    }

Open in new window


Manufacturer Model:

    public class Manufacturer
    {
        public int MfrId { get; set; }
        public string MfrCompanyName { get; set; }
        public string MfrWebsiteDomainName { get; set; }
    }

Open in new window


CustomerFormViewModel:

public class CustomerFormViewModel
    {
        public int CustId { get; set; }

        [Required(ErrorMessage = "Display Name is required!")]
        [Display(Name = "Display Name")]
        [StringLength(100)]
        public string CustDisplayName { get; set; }

        [Display(Name = "First Name")]
        [StringLength(50)]
        public string CustFirstName { get; set; }

        [Display(Name = "Last Name")]
        [StringLength(50)]
        public string CustLastName { get; set; }

        [Display(Name = "Company Name")]
        [StringLength(50)]
        public string CustCompanyName { get; set; }

        [Display(Name = "Phone Number")]
        [DataType(DataType.PhoneNumber)]
        [StringLength(12)]
        [RegularExpression(@"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid Phone Number format!")]
        public string CustPhoneNumber { get; set; }

        [Display(Name = "Mobile Number")]
        [DataType(DataType.PhoneNumber)]
        [StringLength(12)]
        [RegularExpression(@"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid  Number!")]
        public string CustMobileNumber { get; set; }

        [Display(Name = "Email Address")]
        [DataType(DataType.EmailAddress)]
        [StringLength(320)]
        public string CustEmailAddress { get; set; }

        [Required(ErrorMessage = "Address is required!")]
        [Display(Name = "Address")]
        [StringLength(100)]
        public string CustAddress { get; set; }

        [Required(ErrorMessage = "State is required!")]
        [Display(Name = "State")]
        public int StId { get; set; }

        public IEnumerable<State> States { get; set; }
    }

Open in new window


CustomerController:

public class CustomerController : Controller
    {
        private WebAppDbContext _context;

        public CustomerController(WebAppDbContext context)
        {
            _context = context;
        }



        // GET: /<Customer>/
        public IActionResult Index()
        {
            return View(_context.Customers.ToList());
        }



        public ActionResult Create()
        {
            var states = _context.States.ToList();
            var viewModel = new CustomerFormViewModel
            {
                States = states
            };

            return View(viewModel);
        }



        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(CustomerFormViewModel vm)
        {
            if (ModelState.IsValid)
            {
                var customer = new Customer();
                {
                    customer.CustDisplayName = vm.CustDisplayName;
                    customer.CustFirstName = vm.CustFirstName;
                    customer.CustLastName = vm.CustLastName;
                    customer.CustCompanyName = vm.CustCompanyName;
                    customer.CustAddress = vm.CustAddress;
                    customer.CustPhoneNumber = vm.CustPhoneNumber;
                    customer.CustMobileNumber = vm.CustMobileNumber;
                    customer.CustEmailAddress = vm.CustEmailAddress;
                    customer.StId = vm.StId;
                }
                _context.Customers.Add(customer);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }

            else
            {
                vm.States = _context.States.ToList();
                return View(vm);
            }
        }



        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var customervm = new CustomerFormViewModel();
            {
                Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
                if (customer == null)
                {
                    return NotFound();
                }

                customervm.CustId = customer.CustId;
                customervm.CustDisplayName = customer.CustDisplayName;
                customervm.CustFirstName = customer.CustFirstName;
                customervm.CustLastName = customer.CustLastName;
                customervm.CustCompanyName = customer.CustCompanyName;
                customervm.CustAddress = customer.CustAddress;
                customervm.CustPhoneNumber = customer.CustPhoneNumber;
                customervm.CustMobileNumber = customer.CustMobileNumber;
                customervm.CustEmailAddress = customer.CustEmailAddress;

                var states = _context.States.ToList();
                customervm.States = states;

                //Set the selected state
                customervm.StId = customer.StId;
            }
            return View(customervm);
        }
    }

Open in new window


CustomerForm View:

@using (Html.BeginForm("Save", "Customer"))
{
    <div class="form-group">
        @Html.LabelFor(c => c.CustDisplayName)
        @Html.TextBoxFor(c => c.CustDisplayName, new { @class = "form-control" })
        @Html.ValidationMessageFor(c => c.CustDisplayName)
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustFirstName)
        @Html.TextBoxFor(c => c.CustFirstName, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustLastName)
        @Html.TextBoxFor(c => c.CustLastName, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustCompanyName)
        @Html.TextBoxFor(c => c.CustCompanyName, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustAddress)
        @Html.TextBoxFor(c => c.CustAddress, new { @class = "form-control" })
        @Html.ValidationMessageFor(c => c.CustAddress)
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustPhoneNumber)
        @Html.TextBoxFor(c => c.CustPhoneNumber, new { @class = "form-control" })
        @Html.ValidationMessageFor(c => c.CustPhoneNumber)
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustMobileNumber)
        @Html.TextBoxFor(c => c.CustMobileNumber, new { @class = "form-control" })
        @Html.ValidationMessageFor(c => c.CustMobileNumber)
    </div>

    <div class="form-group">
        @Html.LabelFor(c => c.CustEmailAddress)
        @Html.TextBoxFor(c => c.CustEmailAddress, new { @class = "form-control" })
        @Html.ValidationMessageFor(c => c.CustEmailAddress)
    </div>

    <div class="form-group">
        @Html.LabelFor(s => s.StId)
        @Html.DropDownListFor(s => s.StId, new SelectList(Model.States, "StId", "StAbbr"), "", new { @class = "form-control" })
        @Html.ValidationMessageFor(s => s.StId)
    </div>

    @Html.HiddenFor(c => c.CustId)

    <div class="form-group">
        <button type="submit" class="btn btn-primary">Save</button>
    </div>
}

Open in new window

0
Comment
Question by:asp_net2
  • 4
  • 3
7 Comments
 
LVL 11

Expert Comment

by:louisfr
ID: 41815454
You can have the same action for creating and editing.
        public ActionResult Edit(int? id)
        {
            var customervm = new CustomerFormViewModel
            {
                States = _context.States.ToList();
            }

            if (id != null)
            {
                Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
                if (customer == null)
                {
                    return NotFound();
                }

                customervm.CustId = customer.CustId;
                customervm.CustDisplayName = customer.CustDisplayName;
                customervm.CustFirstName = customer.CustFirstName;
                customervm.CustLastName = customer.CustLastName;
                customervm.CustCompanyName = customer.CustCompanyName;
                customervm.CustAddress = customer.CustAddress;
                customervm.CustPhoneNumber = customer.CustPhoneNumber;
                customervm.CustMobileNumber = customer.CustMobileNumber;
                customervm.CustEmailAddress = customer.CustEmailAddress;

                //Set the selected state
                customervm.StId = customer.StId;
            }
            return View(customervm);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Save(CustomerFormViewModel vm)
        {
            if (ModelState.IsValid)
            {
                Customer customer;
                if (vm.CustId == null)
                    customer = new Customer();
                else
                    customer = _context.Customers.SingleOrDefault(c => c.CustId == id);

                customer.CustDisplayName = vm.CustDisplayName;
                customer.CustFirstName = vm.CustFirstName;
                customer.CustLastName = vm.CustLastName;
                customer.CustCompanyName = vm.CustCompanyName;
                customer.CustAddress = vm.CustAddress;
                customer.CustPhoneNumber = vm.CustPhoneNumber;
                customer.CustMobileNumber = vm.CustMobileNumber;
                customer.CustEmailAddress = vm.CustEmailAddress;
                customer.StId = vm.StId;

                if (vm.CustId == null)
                    _context.Customers.Add(customer);
                else
                    db.Entry(customer).State = EntityState.Modified;

                _context.SaveChanges();
                return RedirectToAction("Index");
            }
            else
            {
                vm.States = _context.States.ToList();
                return View(vm);
            }
        }

Open in new window

0
 
LVL 4

Author Comment

by:asp_net2
ID: 41815912
@louisfr,

Sorry, just a little confused. You are showing 2 Actions (Edit / Save). Is there a way to just have 1 Action for retrieving Data based on an ID and if no ID exist create new customer?
0
 
LVL 11

Expert Comment

by:louisfr
ID: 41815925
That Save action was in your View.
You can remove the parameters of BeginHtml in your view.
@using (Html.BeginForm())

Open in new window

and rename the Save method in my code to Edit.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(CustomerFormViewModel vm)

Open in new window

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 4

Author Comment

by:asp_net2
ID: 41816040
Ok, I modified the Edit Action to what you supplied but with giving me errors. Please see attached code with errors below:

CustomerController:

private WebAppDbContext _context;

        public CustomerController(WebAppDbContext context)
        {
            _context = context;
        }


        // GET: /<Customer>/
        public IActionResult Index()
        {
            return View(_context.Customers.ToList());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(CustomerFormViewModel vm)
        {
            if (ModelState.IsValid)
            {
                Customer customer;
                if (vm.CustId == null)
                    customer = new Customer();
                else
                    customer = _context.Customers.SingleOrDefault(c => c.CustId == id);

                customer.CustDisplayName = vm.CustDisplayName;
                customer.CustFirstName = vm.CustFirstName;
                customer.CustLastName = vm.CustLastName;
                customer.CustCompanyName = vm.CustCompanyName;
                customer.CustAddress = vm.CustAddress;
                customer.CustPhoneNumber = vm.CustPhoneNumber;
                customer.CustMobileNumber = vm.CustMobileNumber;
                customer.CustEmailAddress = vm.CustEmailAddress;
                customer.StId = vm.StId;

                if (vm.CustId == null)
                    _context.Customers.Add(customer);
                else
                    _context.Entry(customer).State = EntityState.Modified;

                _context.SaveChanges();
                return RedirectToAction("Index");
            }
            else
            {
                vm.States = _context.States.ToList();
                return View(vm);
            }
        }
    }

Open in new window


Errors:

The result of this expression is always "false" since a value of type "int" is never equal to "null" of type "int?"
if (vm.CustId == null)

Open in new window

0
 
LVL 11

Accepted Solution

by:
louisfr earned 500 total points
ID: 41819356
If CustId cannot be 0, you could change the line to
if (vm.CustId == 0)

Open in new window

However I recommend instead changing the type in the ViewModel to nullable int:
public int? CustId { get; set; }

Open in new window

0
 
LVL 4

Author Comment

by:asp_net2
ID: 41824412
@louisfr,

I think I'm just going to stick with having 2 separate Actions (Create and Edit) instead of combining both Actions into one. I modified my code for that purpose, could you please feel in what I would need for my Edit Action [HttpPost]?

If this needs to be another ticket then please let me know and I'll post another ticket for strictly Edit Action.

CustomerController

public class CustomerController : Controller
    {
        private WebAppDbContext _context;

        public CustomerController(WebAppDbContext context)
        {
            _context = context;
        }


        // GET: /<Customer>/
        public IActionResult Index()
        {
            return View(_context.Customers.ToList());
        }


        public ActionResult Create()
        {
            var states = _context.States.ToList();
            var viewModel = new CustomerFormViewModel
            {
                States = states
            };

            return View(viewModel);
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(CustomerFormViewModel vm)
        {
            if (ModelState.IsValid)
            {
                var customer = new Customer();
                {
                    customer.CustDisplayName = vm.CustDisplayName;
                    customer.CustFirstName = vm.CustFirstName;
                    customer.CustLastName = vm.CustLastName;
                    customer.CustCompanyName = vm.CustCompanyName;
                    customer.CustAddress = vm.CustAddress;
                    customer.CustPhoneNumber = vm.CustPhoneNumber;
                    customer.CustMobileNumber = vm.CustMobileNumber;
                    customer.CustEmailAddress = vm.CustEmailAddress;
                    customer.StId = vm.StId;
                }
                _context.Customers.Add(customer);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }

            else
            {
                vm.States = _context.States.ToList();
                return View(vm);
            }
        }


        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var customervm = new CustomerFormViewModel();
            {
                Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);

                if (customer == null)
                {
                    return NotFound();
                }

                customervm.CustId = customer.CustId;
                customervm.CustDisplayName = customer.CustDisplayName;
                customervm.CustFirstName = customer.CustFirstName;
                customervm.CustLastName = customer.CustLastName;
                customervm.CustCompanyName = customer.CustCompanyName;
                customervm.CustAddress = customer.CustAddress;
                customervm.CustPhoneNumber = customer.CustPhoneNumber;
                customervm.CustMobileNumber = customer.CustMobileNumber;
                customervm.CustEmailAddress = customer.CustEmailAddress;

                // Retrieve list of States
                var states = _context.States.ToList();
                customervm.States = states;

                // Set the selected state
                customervm.StId = customer.StId;
            }
            return View(customervm);
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(CustomerFormViewModel vmEdit)
        {
            if (ModelState.IsValid)
            {

            }
            return View();
        }


    }

Open in new window

0
 
LVL 4

Author Comment

by:asp_net2
ID: 41826391
I was able to get this issue resolved. Thank you for your help though.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

896 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now