我在Controller内部有一个Action函数,该函数被AJAX调用。该操作采用1个参数。在客户端,我构造了一个JSON对象,该对象应序列化为该1参数。我遇到的问题是参数类被声明为抽象。因此,它不能被实例化。
当AJAX击中该动作时,我得到以下信息:
无法创建抽象类。 堆栈跟踪: [MissingMethodException:无法创建抽象类。] System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔publicOnly,布尔noCheck,布尔&canBeCached,RuntimeMethodHandleInternal&ctor,布尔&bNeedSecurityCheck)+0 System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔skipCheckThis,布尔)+98 System.RuntimeType.CreateInstanceDefaultCtor(布尔publicOnly,布尔skipVisibilityChecks,布尔skipCheckThis,布尔fillCache)+241 System.Activator.CreateInstance(类型,布尔非公共)+69 ............. ..
无法创建抽象类。
堆栈跟踪:
[MissingMethodException:无法创建抽象类。]
System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔publicOnly,布尔noCheck,布尔&canBeCached,RuntimeMethodHandleInternal&ctor,布尔&bNeedSecurityCheck)+0 System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔skipCheckThis,布尔)+98
System.RuntimeType.CreateInstanceDefaultCtor(布尔publicOnly,布尔skipVisibilityChecks,布尔skipCheckThis,布尔fillCache)+241 System.Activator.CreateInstance(类型,布尔非公共)+69 ............. ..
有什么方法可以在不创建其他参数对象,“取消声明”参数对象为抽象或挖掘MVC机制的情况下实现这种情况?
我目前正在与后端开发人员一起调整对象。无论哪种方式,我认为这都是最终的解决方案。谢谢大家的答案。
更新: 示例现在使用AJAX JSON POST
如果必须使用抽象类型,则可以提供自定义模型绑定程序来创建具体实例。一个例子如下所示:
模型/模型粘合剂
public abstract class Student { public abstract int Age { get; set; } public abstract string Name { get; set; } } public class GoodStudent : Student { public override int Age { get; set; } public override string Name { get; set; } } public class BadStudent : Student { public override int Age { get; set; } public override string Name { get; set; } } public class StudentBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var values = (ValueProviderCollection) bindingContext.ValueProvider; var age = (int) values.GetValue("Age").ConvertTo(typeof (int)); var name = (string) values.GetValue("Name").ConvertTo(typeof(string)); return age > 10 ? (Student) new GoodStudent { Age = age, Name = name } : new BadStudent { Age = age, Name = name }; } }
控制器动作
public ActionResult Index() { return View(new GoodStudent { Age = 13, Name = "John Smith" }); } [HttpPost] public ActionResult Index(Student student) { return View(student); }
视图
@model AbstractTest.Models.Student @using (Html.BeginForm()) { <div id="StudentEditor"> <p>Age @Html.TextBoxFor(m => m.Age)</p> <p>Name @Html.TextBoxFor(m => m.Name)</p> <p><input type="button" value="Save" id="Save" /></p> </div> } <script type="text/javascript"> $('document').ready(function () { $('input#Save').click(function () { $.ajax({ url: '@Ajax.JavaScriptStringEncode(Url.Action("Index"))', type: 'POST', data: GetStudentJsonData($('div#StudentEditor')), contentType: 'application/json; charset=utf-8', success: function (data, status, jqxhr) { window.location.href = '@Url.Action("Index")'; } }); }); }); var GetStudentJsonData = function ($container) { return JSON.stringify({ 'Age': $container.find('input#Age').attr('value'), 'Name': $container.find('input#Name').attr('value') }); }; </script>
添加到Global.asax.cs
protected void Application_Start() { ... ModelBinders.Binders.Add(new KeyValuePair<Type, IModelBinder>(typeof(Student), new StudentBinder())); }