How to model the binding of a class that implements an interface?

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 there are interfaces, I get 500 (Internal Server Error)

The javascript that I use to bind to the model is as follows:

 $('#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 action of the controller is as follows:

  [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?

+4
source share
1 answer

what am I doing wrong?

You cannot expect the IQuestionAnswer to know that when it encounters the IQuestionAnswer interface on your SurveyAnswer view SurveyAnswer , it must use the QuestionAnswer type. It's nice that you announced this implementation of the interface, but the model’s middleware has no idea about this.

So, you will need to write a custom IQuestionAnswer for the IQuestionAnswer interface (the same for the IHiddenAnswer interface) and indicate which implementation you want to use:

 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()); 
+12
source

Source: https://habr.com/ru/post/1415095/


All Articles