Question

I have made an EditorTemplate in MVC 4 with this code:

@model Drexx.Models.Account
@Html.DropDownListFor(model => model.LevelId, (IEnumerable<SelectListItem>)ViewBag.LevelId, String.Empty)

My View has this code:

@Html.EditorForModel();

My Model has this code:

[UIHint("LevelDropDown")]
[DisplayName("Level")]
public int LevelId { get; set; }
public virtual Level Level { get; set; }

My Controller has this code in the Get:

ViewBag.LevelId = new SelectList(db.Level, "Id", "Name");

My Controller has this code in the Post:

ViewBag.LevelId = new SelectList(db.Level, "Id", "Name", account.LevelId);

This is how the source code looks when i run it:

<select data-val="true" data-val-number="The field Level must be a number." data-val-required="Feltet Level skal udfyldes." id="LevelId_LevelId" name="LevelId.LevelId">
    <option value=""></option>
    <option value="1">Normal</option>
    <option value="2">Admin</option>
</select>
<span class="field-validation-valid" data-valmsg-for="LevelId" data-valmsg-replace="true"></span>

why is it making the id of the dropdown into "LevelId_LevelId" and the name into "LevelId.LevelId"? The dropdown works and shows what it should, but the validation dont work since the id/name is wrong. the validation highlights the dropdown, but it does not display the error message.

The dropdown worked perfectly fine before i moved it into EditorTemplate/before i started using EditorForModel

Im new to EditorTemplates so have a hard time figuring out what could cause this.

Was it helpful?

Solution 2

I found the solution.

Model should look like this:

[DisplayName("Level")]
[UIHint("LevelId")]
[Required]
public int? LevelId { get; set; }

The EditorTemplate should look like this:

@model int?
@Html.DropDownListFor(model => model, (IEnumerable<SelectListItem>)ViewBag.LevelId, String.Empty)

It is very important that i put the "?" after the int because i have a default value in the dropdown.

I didnt have to create a ViewModel for the dropdown.

This is how the source ended up looking after the fix:

<div class="editor-field">
    <select data-val="true" data-val-number="The field Level must be a number." data-val-required="Feltet Level skal udfyldes." id="LevelId" name="LevelId">
        <option value=""></option>
        <option value="1">Normal</option>
        <option value="2">Admin</option>
    </select>
    <span class="field-validation-valid" data-valmsg-for="LevelId" data-valmsg-replace="true"></span>
</div>

Thanks for all the suggestions Darin Dimitrov, but they didnt work for me.

OTHER TIPS

There seem to be some confusion here. You have decorated your LevelId integer property with the UIHint attribute pointing to the custom LevelDropDown.cshtml editor template and yet your editor template seems to be strongly typed to the Drexx.Models.Account model which is incorrect.

Let's have an example of how you could achieve that. As always in ASP.NET MVC you start by designing your view model which will contain the necessary properties that your view might require:

public class AccountViewModel
{
    [DisplayName("Level")]
    public int LevelId? { get; set; }

    public IEnumerable<SelectListItem> Levels { get; set; }
}

then you write a controller action that will populate this view model and pass it to the view:

public ActionResult Index()
{
    var model = new AccountViewModel();
    model.LevelId = 123; // some value that you want to be used to preselect some element of the dropdown
    model.Levels = new SelectList(db.Level, "Id", "Name");

    return View(model);
}

and then in the corresponding view:

@model AccountViewModel
...
@Html.EditorForModel()

and then in the ~/Views/Shared/EditorTemplates/AccountViewModel.cshtml:

@model AccountViewModel
@Html.DropDownListFor(x => x.LevelId, Model.Levels, string.Empty)

You also have the possibility to specify the name of the template:

@Html.EditorForModel("Foo")

which will be looking for the ~/Views/Shared/EditorTemplates/Foo.cshtml template.

The UIHint attribute could be used when you have some more complex parent view model. For example:

public class MyViewModel
{
    UIHint("LevelDropDown")
    public AccountViewModel Account { get; set; }

    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top