Search code examples
c#asp.netasp.net-mvcmvc-editor-templates

How create a complex EditorTemplate in ASP.NET MVC 5 with db query?


I would like to create a more complex EditorTemplate to select a customer from a list.

I'm aware of the DropDownListFor, but I would like to show cards with customer pictures and some data not just a regular select list.

What I would like to do:

create an EditorTemplate for customer selecting, for instance... In any POCO Class

public class X{

    [Key] int Id {get;set;}

    [UIHint("CustomerSelector")] int Custumer_Id {get;set;}

}

And the "CustomerSelector" Editor template be able to query all clients and show them into a rich list.

Customer List

What is the problem:

  • It's not a good idea to add querying logic from inside a view. This is against MVC pattern.
  • It's not very modular to query the customer list in every controller and pass it as argument to the EditorTemplate.

How can I create this EditorTemplate without mess up with the MVC pattern nor duplicate code in every controller?


Solution

  • Unfortunately, there is no truly good way to handle something like this. Your are correct that it's improper for database access to happen within a view. Not only does this violate MVC, but it would also require creating an additional instance of your context in the view, when you should really have just one per request.

    The alternative, as you've mentioned, would be to do the query in the controller and then pass that into your view. Honestly, this is probably your best of bad options here.

    Another choice I see is to use a child action. A child action allows you to confine the logic of querying the users and passing to a view in just one place. The downside is that that you would have to handle the field naming manually, because the rendering of the child actions view will be outside the scope of the form you're building. In other words, you'd have to do something like:

    @Html.Action("CustomerSelect", new { fieldName = "Customer_Id" })
    

    That's not really ideal, either, as now you've got a string that you've got to keep track of, and you'll have to be careful about actually providing the right name. For example, if this was a collection of items, then you'd actually need to pass something like "MyCollection[" + i.ToString() + "].Customer_Id". You can see that this starts to get messy quick. For this reason alone, I'd pretty much nix this as a possible solution.

    One final option is to use an HtmlHelper extension. This has the same problem as an editor template would in that you're going to have to new up an instance of your context, but it's at least better in the respect that it's not being done inside a Razor view.