How to Use @Html.EditorFor() without the view model

Peter picture Peter · Apr 20, 2012 · Viewed 7.6k times · Source

I want to do something like this so I can create a modal dialog that I'll invoke late with jQuery

<div class="modal" id="modalName" style="display: none;">
<div class="modal-header">
    <a class="close" data-dismiss="modal">×</a>
    <h3>Edit Contacts</h3>
</div>
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new Dictionary<string, object> { { "class", "form-horizontal" } }))
{
    <div class="modal-body">
    @Html.EditorFor(model => new ViewModel(), "ViewModelTemplateName")
    </div>
    <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
        <button type="submit" class="btn btn-primary">
            Submit</button>

    </div>
}
</div>

On this line

@Html.EditorFor(model => new ViewModel(), "ViewModelTemplateName")

I get the error

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

I don't understand why it would care where or what the instance is (as long as its the right type)

@Html.Partial("~/Views/Shared/EditorTemplates/ViewModel.cshtml", new ViewModel()) does the trick, but I have to declare the full path the the template...this sucks a bit.

so is there a better way to do it?

Answer

Andras Zoltan picture Andras Zoltan · Apr 20, 2012

Technically it's not the instance that's the problem. It's an expression, not a function, that you're passing there and the expression parser used by EditorFor, to get the meta data it uses to identify the properties etc, doesn't support new expressions.

You can simply declare a new instance of the model outside of the EditorFor statement and do this:

@{ var emptyViewModel = new ViewModel(); }
@Html.EditorFor(model => emptyViewModel, "ViewModelTemplateName") 

That should work.

That said - not using part of the model in the expression is a little weird. You should perhaps consider extracting the dialog out to it's own partial view that has ViewModel as it's model type, and then you can use EditorForModel in that, and call it from this parent view using a new ViewModel() as the model you pass to it.