ASP.NET MVC - pass an external model to an editor template

I use custom template templates for most of my forms, but when I tried to use them to render a custom item selector, I did not find an easy way to pass information about the containing context to the editor template.

In particular, my main form does editing for a domain object, and the editor template should display an AJAX picker that contains a list of objects that depend on the identifier of the domain object. I pass in the identifier using the additionalViewData parameter at the moment, which in my opinion is error prone and therefore pretty ugly.

My form contains code similar to the following:

 @Html.EditorFor(model => model.CategoryId, new { id = model.id }) 

The editor template contains the following code:

 @{ var domainObjectId = ViewData["id"] as int?; } 

I use a custom ModelMetadataProvider to select an object selection editor template and hope to use a similar method to transfer information about the containing model to the editor template, but this is not possible.

So my questions are:

  • Can I use ModelMetadataProvider to pass information about the model containing the editor template?
  • If not, is there any neat / simpler way to achieve what I am trying, except for passing each piece of additional information through a weakly typed additionalViewData parameter?

Thanks in advance!

+4
source share
2 answers

You need to understand that EditorTemplates are designed as type-specific, not contextual. Some thought has been given to this AdditionalViewData parameter, but this is the best thing you are going to get.

If you're worried about type safety, use the ViewBag instead, which is a type-safe dynamic wrapper around ViewData.

 @{ var domainObjectId = ViewBag.Id; } 
+5
source

It is interesting, perhaps, that the controller creating this view model should first select what selects the list of objects. Therefore, instead of having an integer property in your view model, you might have a sub property of another type of view model, that is:

 public class OuterViewModel { public CategoryViewModel Category { get; set; } } public class CategoryViewModel { public int CategoryId { get; set; } public IEnumerable<SelectListItem> ListOfThings { get; set; } } 

Then your original view may simply have:

 @Html.EditorFor(model => model.Category) 

Using the EditorTemplate for CategoryViewModel, which looks like this:

 @model CategoryViewModel @Html.DropDownFor(m => m.CategoryId, Model.ListOfThings) 

The only thing you need to remember is that if you are validating business logic on the server side, adding model errors and returning to your view, you will need to re-populate your list of things in your post after the action with the controller.

0
source

All Articles