运行时的编辑器模板

时间:2013-11-25 14:27:56

标签: asp.net-mvc generics model-binding mvc-editor-templates

这个问题有点难以解释,所以我试着举个例子。说我有以下类型:

public class FieldResult<T> {
    public Field Field { get; set; }
    public T Answer { get; set; }

    public FieldResult(Field field) {
        Field = field;
    }
}

现在说我有以下视图模型:

public class Form {
    public IList<FieldResult<object>> Results { get; set; }

    public Form(IList<Field> fields) {
        Results = fields.Select(f => new FieldResult<object>(f)).ToList();
    }
}

如果我在视图中说出以下内容:

@foreach (var result in Model.Results) {
    @Html.EditorFor(m => result, "CheckBoxField")
}

现在说我有以下CheckBoxField编辑器模板:

@model FieldResult<bool>
@Html.CheckBoxFor(m => m.Answer)

这一切都很好但是我在运行时遇到以下错误:

  

传递到字典中的模型项是类型的   'FieldResult 1[System.Object]', but this dictionary requires a model item of type 'FieldResult 1 [System.Boolean]'。

如果有人能说出这是否可能并且可能提出一种解决方法,我会很感激。感谢

1 个答案:

答案 0 :(得分:1)

您尝试在模型类型为FieldResult<object>的模板中传递FieldResult<bool>值,它们的类型不同,因此您会收到该错误。您可以更改Results媒体资源并将其设为IList<FieldResult<bool>>,也可以在视图中投放收藏品。

如果需要构建不同类型的结果,还可以考虑使用类继承:

public abstract class FieldResult {
    public Field Field { get; set; }

    public FieldResult(Field field) {
        Field = field;
    }
}

public class BooleanFieldResult : FieldResult {
    public bool Answer { get; set; }

    public FieldResult(Field field) : base(field) {
    }
}

您的Form课程将如下所示:

public class Form {
    public IList<FieldResult> Results { get; set; }

    public Form(IList<Field> fields) {
        Results = // ... you choose which child class inherited from FieldResult you want to use
    }
}

您的视图会检查它的类型:

@foreach (var result in Model.Results) {
    if(result is BooleanFieldResult) {
        var booleanResult = (BooleanFieldResult)result;
        @Html.EditorFor(m => booleanResult , "CheckBoxField")
    }
}

然后您的CheckBoxField模板将如下所示:

@model BooleanFieldResult
@Html.CheckBoxFor(m => m.Answer)