MVC将子类型集合绑定到发布模型

时间:2015-08-10 13:52:09

标签: c# asp.net-mvc inheritance model model-binding

我的问题: 要获得问题的当前子类型,我不能只调用GetValue(" ModelType"),因为Questions是一个集合。那么如何在自定义模型绑定器中获取集合中当前问题的子类型?所以这不会起作用:

var typeValue = bindingContext.ValueProvider.GetValue("ModelType");

这是我的代码的一个简化版本..我有一个以下模型:

public class PostViewModel
{
    public string Title { get; set; }
    public List<Question> Questions { get; set; }
}

public class Question
{
    public int Id { get; set; }
}

public class SingleChoice : Question
{
    public List<Answers> AnswerOptions { get; set; }
}
public class TextQuestion : Question
{
    public string Value { get; set; }
}

然后我创建了以下模型绑定器:

public class QuestionModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        if (modelType.Equals(typeof(Question)))
        {

            var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
            var type = Type.GetType(
                (string)typeValue.ConvertTo(typeof(string)),
                true
            );
            if (!typeof(Question).IsAssignableFrom(type))
            {
                throw new InvalidOperationException("Bad Type");
            }


            var obj = Activator.CreateInstance(type);                
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => obj, type);
            bindingContext.ModelMetadata.Model = obj;
            return obj;
        }

        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

我的观点如下:

//查看A.

@model PostModel

@Html.EditorFor(m => m.Questions)

//查看B.

@model QuestionViewModel
<div>
@Html.HiddenFor(m => m.Id)
@Html.Hidden("ModelType", Model.GetType())
@switch (Model.QuestionType)
{
    case QuestionType.OpenText:
        @Html.Partial("EditorTemplates/Types/TextViewModel", Model)
        break;
    case QuestionType.SingleChoice:
    @Html.Partial("EditorTemplates/Types/SingleChoiceViewModel", Model)
        break;

}
</div>

0 个答案:

没有答案