I have an image uploader editor template, which is currently strongly typed to the MultiImageUploader view model. The problem is I have some custom data validation attributes that I’d like to use in the view model that calls the editor template directly, instead of routing through the MultiImageUploader view model.
Instead of calling the MultiImageUploader view model with preset validation attributes, I’d like to do something like this:
public class CreateBrandViewModel
{
.....<snipped>.....
[PermittedFileExtensions("jpg, jpeg, png, gif")]
[MaxFileSize("2MB")]
[UIHint("MultiImageUploader")]
public HttpPostedFileBase Image { get; set; }
//Currently this view model looks like this:
//public MultiImageUploader Image { get; set; } <-- seperate view model
}
I can’t use my preferred way currently because my editor template isn’t strongly typed against the CreateBrandViewModel. Is there a way I can pass the calling view model’s @model into the editor templates view? :
@model // Here? //
<div class="editor-field">
@Html.TextBoxFor(x => x.Image, new { type = "file" })
@Html.ValidationMessageFor(x => x.Image)
</div>
Edit 1
Just for clarification, the reason I want to do this is because I’d like to change from an Image uploader to a general purpose file uploader – which would require different validation attributes on different view models. To do this currently I’d need to create a different view model and editor template for each slightly different validation parameter variation.
Edit 2: Regarding @Joel Athertons answer
I’ve run into a few problems trying to implement this (or maybe I’m just not understanding correctly).
I’ve created the interface and the abstract class. My CreateBrandViewModel now inherits from FileUpload. FileUpload is currently empty with no shared properties. When I try model.GetType().Name I get an “Object reference not set to an instance of an object.” error. Code is as follows:
Controller passes a CreateBrandViewModel to the view:
[HttpGet]
public ActionResult Create()
{
var model = new CreateBrandViewModel();
model.IsActive = true;
return View(model);
}
The Create view then calls the EditorTemplate:
@model CumbriaMD.Infrastructure.ViewModels.BrandViewModels.CreateBrandViewModel
@Html.EditorFor(model => model.File, "EditorTemplates/MultiImageUploader")
The template then just (for simplicities purpose) looks like this:
@model CumbriaMD.Infrastructure.ViewModels.FileUploadViewModels.FileUpload
@{
var partialView = Model.GetType().Name;
}
<h1>@partialView</h1>
Any ideas would be appreciated 🙂
The way I would handle this would be to have an interface which all of your models that will allow uploads would implement. If you actually have common functionality, I would also couple this with an abstract model that has any common properties, attributes, etc. Then each of your individual models would either inherit the abstract class (or implement the interface if you didn’t use a class), and then you could use that as your @model statement. Then you could simply split off any one-off pieces into partial views that could do their own thing.
Then in your template.