Click here to Skip to main content
15,031,687 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Basically, I am working on an Application where I need to display a form for a number of times on a view (like a template). So, I have created a viewcomponent with its Model. Then invoke the method a number of times to render the form html code. The component is also passed an action so the appropriate action will be triggered in the controller. The problem relies when a user enters an invalid data (server side validation using ModelState). Upon returning the view, the validation message will appear on all fields with the same name, and the fields will also contain the data entered in the valid fields. This is I think due to the view operation, as if i clear the model, and redirect, the MVC engine will reinitialize the view, but obviously the error messages are lost. I tried to use the TempData to save the ViewData (but this is not serializable). Thanks in advance for your assistance.

What I have tried:

Component Code:
public class ViewCustomerViewComponent : ViewComponent
    {
        public ViewCustomerViewComponent()
        {
        }

        public async Task<IViewComponentResult> InvokeAsync(Customer data, string actionName)
        {
            ViewData["actionName"] = actionName;
            return View(data);
        }
    }


Controller Code:
public class CustomerController : Controller
    {
        public IActionResult Index()
        { 
            return View(new CustomerViewModel());
        }

        [HttpPost]
        public IActionResult action1(Customer c)
        {
            if (!ModelState.IsValid)
            {
                CustomerViewModel p = new CustomerViewModel();
                p.c1 = c;
                return View("Index", p);
            }

            return RedirectToAction("Index");
        }

        [HttpPost]
        public IActionResult action2(Customer c)
        {
            if (!ModelState.IsValid)
            {
                CustomerViewModel p = new CustomerViewModel();
                p.c2 = c;
                return View("Index", p);
            }

            return RedirectToAction("Index");
        }
    }


Component view:
@model components.Models.Customer
@{
    ViewData["Title"] = "Default";
}

<form asp-action='@ViewData["actionName"]' asp-controller="Customer" method="post">
    <div class="row">
        <label asp-for="@Model.Name" class="col-md-2"></label>
        <input asp-for="@Model.Name" />
        <span asp-validation-for="@Model.Name"></span>
    </div>
    <div class="row">
        <label asp-for="@Model.Surname" class="col-md-2"></label>
        <input asp-for="@Model.Surname" />
        <span asp-validation-for="@Model.Surname"></span>
    </div>
    <div class="row">
        <input type="submit" value="submit" />
    </div>
</form>


view model holding two instances of the form model object
public class CustomerViewModel
    {
        public Customer c1 { get; set; }
        public Customer c2 { get; set; }
        public CustomerViewModel()
        {
            c1 = new Customer();
            c2 = new Customer();
        }
    }


main index.html
@await Component.InvokeAsync("ViewCustomer", new { data= Model.c1, actionName = "action1" })
@await Component.InvokeAsync("ViewCustomer", new { data = Model.c2, actionName = "action2" })


Model
public class Customer
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Surname { get; set; }

    public int n;
}
Posted
Updated 25-Feb-21 4:17am

1 solution

I have the same problem. I can't add button to view componenet!
Did you solve it?
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900