使用CreateModel在MVC中为自定义模型赋值

时间:2015-05-11 06:22:25

标签: asp.net-mvc

我有以下控制器方法

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;
    }

0 个答案:

没有答案