如何绑定模型实现接口的类? [英] How to model bind a class that implements an interface?

查看:114
本文介绍了如何绑定模型实现接口的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该模型绑定工作正常,直到我上实现以下类的顶部接口:

 公共类问题答案:IQuestionAnswer
    {        公众的Int32 ROW_ID {搞定;组; }
        公众的Int32 COLUMN_ID {搞定;组; }
        公共字符串值{搞定;组; }    }    公共类HiddenAnswer:IHiddenAnswer
    {        公众的Int32 Hidden_​​Field_ID {搞定;组; }
        公共字符串Hidden_​​Field_Value {搞定;组; }    }    公共类SurveyAnswer:ISurveyAnswer
    {        公共字符串的SessionID {搞定;组; }        公开名单< IQuestionAnswer> QuestionAnswerList {搞定;组; }        公开名单< IHiddenAnswer> HiddenAnswerList {搞定;组; }        公共SurveyAnswer()
        {
            QuestionAnswerList =新的List< IQuestionAnswer>();
            HiddenAnswerList =新的List< IHiddenAnswer>();
        }
    }

现在其接口​​有,我收到了 500(内部服务器错误)

这是我使用模型绑定的javascript如下:

  $('#提交按钮')。点击(函数(){            VAR答案=新的Array();
            VAR hiddenfields =新的Array();            变种表格名称=#+ $(#表格名称)VAL();            $(':输入',表格名称)。每个(函数(){                如果($(本)。是(:文本)|| $(本)。是(:电台)|| $(本)。是(:复选框))
                {
                    VAR answerObject = {
                        COLUMN_ID:$(本).attr('数据COLUMN_ID'),
                        ROW_ID:$(本).attr('数据ROW_ID'),
                        价值:$(本).attr('数据theValue')
                    };                    answers.push(answerObject);
                }                否则,如果($(本)。是(:隐藏)){
                    VAR hiddenObject =
                    {
                        Hidden_​​Field_ID:$(本).attr('数据hidden_​​field_id'),
                        Hidden_​​Field_Value:$(本).attr('数据hidden_​​field_value')
                    }                    hiddenfields.push(hiddenObject);
                }
            });            $('textarea的,表格名称)。每个(函数(){
                VAR answerObject = {
                    COLUMN_ID:$(本).attr('数据COLUMN_ID'),
                    ROW_ID:$(本).attr('数据ROW_ID'),
                    价值:$(本).VAL()
                };                answers.push(answerObject);
            });            VAR allAnswers = {
                的SessionID:0,
                QuestionAnswerList:答案,
                HiddenAnswerList:hiddenfields
            }            postForm(allAnswers);
        });

控制器中的操作是这样的:

 的[AcceptVerbs(HttpVerbs.Post)
        公众的ActionResult SubmitSurvey(SurveyAnswer答案)
        {
            //德特tillader CORS
            Response.AppendHeader(访问控制允许原产地,*);            bc.SaveSurvey(答案);            返回null;
        }

我在做什么错了?


解决方案

  

我在做什么错了?


您不能指望模型绑定要知道,当它遇到你的 SurveyAnswer 视图模式 IQuestionAnswer 接口,它应该使用问题答案键入。这是很好,你已经声明此接口的实现,但模型绑定有没有关于它的线索。

所以,你将不得不写的 IQuestionAnswer 界面自定义模型粘合剂(同为 IHiddenAnswer 接口)并注明你要使用哪个实现:

 公共类QuestionAnswerModelBinder:DefaultModelBinder
{
    保护覆盖对象CreateModel(ControllerContext controllerContext,ModelBindingContext的BindingContext,类型modelType)
    {
        VAR类型= ty​​peof运算(问题答案);
        VAR模型= Activator.CreateInstance(类型);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(()=>型号,类型);
        回归模型;
    }
}

这将在注册

的Application_Start

  ModelBinders.Binders.Add(typeof运算(IQuestionAnswer),新QuestionAnswerModelBinder());

The model binding worked fine until i implemented interfaces on top of the following classes:

public class QuestionAnswer : IQuestionAnswer
    {

        public Int32 Row_ID { get; set; }
        public Int32 Column_ID { get; set; }
        public String Value { get; set; }

    }

    public class HiddenAnswer : IHiddenAnswer
    {

        public Int32 Hidden_Field_ID { get; set; }
        public String Hidden_Field_Value { get; set; }

    }

    public class SurveyAnswer : ISurveyAnswer
    {

        public string SessionID { get; set; }

        public List<IQuestionAnswer> QuestionAnswerList { get; set; }

        public List<IHiddenAnswer> HiddenAnswerList { get; set; }

        public SurveyAnswer()
        {
            QuestionAnswerList = new List<IQuestionAnswer>();
            HiddenAnswerList = new List<IHiddenAnswer>();
        }
    }

Now that the interfaces are there, i get a 500 (Internal Server Error)

The javascript that i use to model bind is the following:

$('#submitbutton').click(function () {

            var answers = new Array();
            var hiddenfields = new Array();

            var formname = "#" + $("#formname").val();

            $(':input', formname).each(function () {

                if ($(this).is(":text") || $(this).is(":radio") || $(this).is(":checkbox")) 
                {
                    var answerObject = {
                        Column_ID: $(this).attr('data-column_id'),
                        Row_ID: $(this).attr('data-row_id'),
                        Value: $(this).attr('data-theValue')
                    };

                    answers.push(answerObject);
                }

                else if($(this).is(":hidden")) {
                    var hiddenObject = 
                    {
                        Hidden_Field_ID: $(this).attr('data-hidden_field_id'),
                        Hidden_Field_Value: $(this).attr('data-hidden_field_value')
                    }

                    hiddenfields.push(hiddenObject);
                }
            });

            $('textarea', formname).each(function () {
                var answerObject = {
                    Column_ID: $(this).attr('data-column_id'),
                    Row_ID: $(this).attr('data-row_id'),
                    Value: $(this).val(),
                };

                answers.push(answerObject);
            });

            var allAnswers = {
                SessionID: 0,
                QuestionAnswerList: answers,
                HiddenAnswerList: hiddenfields
            }

            postForm(allAnswers);
        });

The Controller Action looks like this:

 [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SubmitSurvey(SurveyAnswer answers)
        {
            // Dette tillader CORS
            Response.AppendHeader("Access-Control-Allow-Origin", "*");

            bc.SaveSurvey(answers);

            return null;
        }

what am i doing wrong?

解决方案

what am i doing wrong?

You cannot expect the model binder to know that when it encounters the IQuestionAnswer interface on your SurveyAnswer view model it should use the QuestionAnswer type. It's nice that you have declared this implementation of the interface but the model binder has no clue about it.

So you will have to write a custom model binder for the IQuestionAnswer interface (same for the IHiddenAnswer interface) and indicate which implementation do you want to be used:

public class QuestionAnswerModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var type = typeof(QuestionAnswer);
        var model = Activator.CreateInstance(type);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
        return model;
    }
}

which will be registered in your Application_Start:

ModelBinders.Binders.Add(typeof(IQuestionAnswer), new QuestionAnswerModelBinder());

这篇关于如何绑定模型实现接口的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆