Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any good reason NOT to use a ViewComponent instead of a Partial View in core MVC?

I'm new to MVC and decided to start with .net-core, so I don't have much understanding of the differences in core vs. older versions. I did find the below question which offers some insight but hasn't helped me to decide whether I can basically ignore partial views.

Why should we use MVC 6 Feature View Components over Partial View: What is the difference?

My question is simply - if I can do something with a ViewComponent, is there any good reason not to?

Many Thanks!

Example provided below for context.

Main view calls:

ViewComponent:

<div class="modal-body" ID="modalPersonInner">
       @await Component.InvokeAsync("CreatePerson", new Person())
</div>

Versus Partial View:

<div class="modal-body" ID="modalPersonInner">
    @{ await Html.RenderPartialAsync("People/CreatePartialView", new Person());}
</div>

Javascript (personCreateForm is a form within the partial view/view component):

 var submitPersonCreate = function(evt) {

        evt.preventDefault();
        if ($(this).valid())
        {
            $.ajax({
                type: "POST",
                url: '@Url.Action("CreatePartial", "People")',
                data: $('#personCreateForm').serialize(),
                success(data) {
                    if (data === true)
                        window.location.reload();
                    else
                        $('#modalPersonInner').html(data);
                }
            });
        }

        return false;
    }
$('#personCreateForm').submit(submitPersonCreate);

Controller code:

  public async Task<IActionResult> CreatePartial(
        [Bind("AddressLine1,AddressLine2,AddressLine3,AddressLine4,City,Country,Email,Forename,MobileNumber,Postcode,Region,Surname,TelephoneNumber")] Person person)
    {
        if (ModelState.IsValid)
        {
            _context.Add(person);
            await _context.SaveChangesAsync();
            return Json(true);
        }
        //PARTIAL VIEW VERSION
        //return PartialView("People/CreatePartialView",person);

        //VIEWCOMPONENT VERSION
        return ViewComponent("CreatePerson", person);
    }

ViewComponent code:

 public class CreatePersonViewComponent : ViewComponent
    {
        private readonly AppDbContext db;

        public CreatePersonViewComponent(AppDbContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(Person person )
        {

            return View(person ?? new Person());
        }

    }

And finally the Razor page which is the same for both:

@model Person

<form ID="personCreateForm">
    <div class="form-horizontal">
        <h4>Customer</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Forename" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Forename" class="form-control" />
                <span asp-validation-for="Forename" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Surname" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Surname" class="form-control" />
                <span asp-validation-for="Surname" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Country" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Country" class="form-control" Value="UK" />
                <span asp-validation-for="Country" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Region" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Region" class="form-control" />
                <span asp-validation-for="Region" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="City" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="City" class="form-control" />
                <span asp-validation-for="City" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AddressLine1" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AddressLine1" class="form-control" />
                <span asp-validation-for="AddressLine1" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AddressLine2" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AddressLine2" class="form-control" />
                <span asp-validation-for="AddressLine2" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Postcode" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Postcode" class="form-control" />
                <span asp-validation-for="Postcode" class="text-danger" />
            </div>
        </div>

        <div class="form-group">
            <label asp-for="Email" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger" />
            </div>
        </div>

        <div class="form-group">
            <label asp-for="MobileNumber" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="MobileNumber" class="form-control" />
                <span asp-validation-for="MobileNumber" class="text-danger" />
            </div>
        </div>



        <div class="form-group">
            <label asp-for="TelephoneNumber" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="TelephoneNumber" class="form-control" />
                <span asp-validation-for="TelephoneNumber" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>
like image 544
David Kirkpatrick Avatar asked Jul 06 '16 11:07

David Kirkpatrick


People also ask

When should partial views be used?

Partial views are an effective way to: Break up large markup files into smaller components. In a large, complex markup file composed of several logical pieces, there's an advantage to working with each piece isolated into a partial view.

What is the difference between partial view and view component?

View components are similar to partial views, but they're much more powerful. View components don't use model binding, they depend on the data passed when calling the view component. This article was written using controllers and views, but view components work with Razor Pages.

What is the difference between RenderPartial and partial?

The primary difference between the two methods is that Partial generates the HTML from the View and returns it to the View to be incorporated into the page. RenderPartial, on the other hand, doesn't return anything and, instead, adds its HTML directly to the Response object's output.

What is advantage of partial view in MVC?

using Partial View in ASP.NET MVC has following advantages: Enhances reusability by packaging up common website code instead of repeating the same in different pages. Easy to maintain. Changes in future are simple to accommodate.


1 Answers

It's a really good question. Yes, there are cases where you are better off implementing your code with a partial view than with a View Component. If the View Component isn't going to have any appreciable amount of logic (as is the case in your example) then you should use a partial view instead.

View Components are a great way to compartmentalize logic, and in some ways can be thought of as a partial view that contains it's own logic. But if there isn't any logic that needs to be compartmentalized with the partial view then it's probably best to not use a View Component. In such a case using a View Component increases the coding complexity (there is another place to look to see how the code works) but doesn't provide any real benefit. In general, you should only increase code complexity to the extent that the benefits received from that added complexity are greater than the "cost" of that complexity.

I hope that doesn't sound too theoretical. It basically boils down to this: if there is logic that you want to package up with the partial view so that you can use that component over and over, then use a View Component, but if there isn't any logic that you need to package up with it then use a partial view.

like image 70
RonC Avatar answered Nov 09 '22 22:11

RonC