我有以下控制器方法
public ActionResult Index(){
var survey = new Survey() {
Name = "Survey for Testing",
Sections = new List<ISection>()
};
var section = new List<Section>();
var section1 = new Section() {
Name = "Section A",
ElementType = ElementType.Section,
Elements = new List<IElement>(),
FieldAssemblyName = section.GetType().Assembly.FullName,
FieldClassName = section.GetType().FullName
};
var section2 = new Section()
{
Name = "Section B",
ElementType = ElementType.Section,
Elements = new List<IElement>(),
FieldAssemblyName = section.GetType().Assembly.FullName,
FieldClassName = section.GetType().FullName
};
var Question1 = new QuestionYesNo() {
QuestionText = "Do you like apples?",
ElementType = ElementType.AnswerableQuestion,
Id = 1
};
var Question2 = new QuestionYesNo()
{
QuestionText = "Do you like getting hit in the face?",
ElementType = ElementType.AnswerableQuestion,
Id = 2
};
var Question3 = new QuestionMultipleSelect()
{
QuestionText = "Do you like getting hit in the face?",
ElementType = ElementType.AnswerableQuestion,
Options = new List<QuestionOption>(),
Answers = new List<QuestionOption>(),
ToolTip = new QuestionToolTip(){Text="You need more info?"},
Id = 3
};
var Question3Options = new List<QuestionOption>();
Question3Options.Add(new QuestionOption(){ DisplayText = "Option 1", Value = "1"});
Question3Options.Add(new QuestionOption() { DisplayText = "Option 3", Value = "2" });
Question3Options.Add(new QuestionOption() { DisplayText = "Option 4", Value = "3" });
Question3Options.Add(new QuestionOption() { DisplayText = "Option 5", Value = "4" });
Question3Options.Add(new QuestionOption() { DisplayText = "Option 5", Value = "5" });
Question3.Options = Question3Options;
section1.Elements.Add(Question1);
section2.Elements.Add(Question2);
section2.Elements.Add(Question3);
survey.Sections.Add(section1);
survey.Sections.Add(section2);
return View(survey);
}
然后我使用EditorFor来显示不同类型的问题,如下拉列表,复选框,单选按钮等,它们显示正常
@for (var i = 0; i < Model.Sections.Count; i++)
{
@Html.EditorFor(model => model.Sections[i])
@Html.HiddenFor(model => model.Sections[i].FieldAssemblyName)
@Html.HiddenFor(model => model.Sections[i].FieldClassName)
}
@Html.HiddenFor(m => m.SurveyId)
<input class="btn btn-success" type="submit" value="Save Survey" />
</div>
目前我正在通过覆盖CreatModel方法来创建以下自定义模型,因此我应该将接口替换为类对象及其工作正常,但是此方法返回的实例没有任何价值,请你让它我知道当我点击Save Survey按钮时如何将发布的值分配给新实例。
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var type = bindingContext.ModelType;
if (type.IsInterface)
{
// Get the posted 'class name' key - bindingContext.ModelName will return something like Section[0] in our particular context, and 'FieldClassName' is the property we're looking for
var fieldClassName = bindingContext.ModelName + ".FieldClassName";
// Do the same for the assembly name
var fieldAssemblyName = bindingContext.ModelName + ".FieldAssemblyName";
// Check that the values aren't empty/null, and use the bindingContext.ValueProvider.GetValue method to get the actual posted values
if (!String.IsNullOrEmpty(fieldClassName) && !String.IsNullOrEmpty(fieldAssemblyName))
{
HttpRequestBase request = controllerContext.HttpContext.Request;
string name = request.Form.Get("Name");
// The value provider returns a string[], so get the first ([0]) item
var className = ((string[])bindingContext.ValueProvider.GetValue(fieldClassName).RawValue)[0];
// Do the same for the assembly name
var assemblyName =
((string[])bindingContext.ValueProvider.GetValue(fieldAssemblyName).RawValue)[0];
// Once you have the assembly and the class name, get the type -
modelType = Type.GetType(className + ", " + assemblyName);
// Finally, create an instance of this type
List<Section> instance = (List<Section>)Activator.CreateInstance(modelType);
Section section = new Section();
section.Name = bindingContext.ValueProvider.GetValue(sectionName) == null ? "" : ((string[])bindingContext.ValueProvider.GetValue(sectionName).RawValue)[0];
section.ElementType = bindingContext.ValueProvider.GetValue(elementType) == null ? Licensure.Business.Survey.ElementType.Section : GetElementType(((string[])bindingContext.ValueProvider.GetValue(elementType).RawValue)[0]);
instance.Add(section);
// Update the binding context's meta data
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, modelType);
// Return the instance //
return instance;
}
}
return null;
}