我在Controller中有一个Action函数,它是用AJAX调用的 . 该行动涉及1个参数 . 客户端,我构造了一个JSON对象,应该序列化为该1参数 . 我遇到的问题是参数类被声明为abstract . 因此,它无法实例化 .
当AJAX点击该Action时,我得到以下内容:
无法创建抽象类 . 堆栈跟踪:[MissingMethodException:无法创建抽象类 . ] System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,Boolean publicOnly,Boolean noCheck,Boolean&canBeCached,RuntimeMethodHandleInternal&ctor,Boolean&bNeedSecurityCheck)0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis, Boolean fillCache)98 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,Boolean skipVisibilityChecks,Boolean skipCheckThis,Boolean fillCache)241 System.Activator.CreateInstance(Type type,Boolean nonPublic)69 .............. .
有没有办法在不创建不同参数对象的情况下实现这样的场景,“取消声明”参数对象为抽象,或者深入研究MVC的机制?
更新
我目前正在与后端开发人员一起调整他们的对象 . 无论哪种方式,我认为这将是最终的解决方案 . 谢谢大家的答案 .
5 回答
Update: 示例现在使用AJAX JSON POST
如果必须使用抽象类型,则可以提供custom model binder来创建具体实例 . 一个例子如下所示:
Model / Model Binder
Controller Actions
View
Added to Global.asax.cs
框架无法知道您想要的具体实现,也不会承担此类决策的责任 . 所以你有两种可能性:
使用具体类型作为操作参数
为此抽象类编写自定义模型 Binders ,它基于某些请求参数将返回特定实例 .
您将不得不创建抽象类的子类并将其传递给它 . 从根本上说,抽象类不允许自己实例化 . 但是,如果你有一个C#方法,如:
...然后你仍然可以传递Foo一个派生自MyAbstractClass的类型的实例 . 因此,您可以创建一个具体的子类
MyChildClass : MyAbstractClass
并将其传递给您的方法,它应该仍然有效 . 您不必更改Foo
方法,但您需要访问C#代码,以便创建MyChildClass
.如果您正在使用泛型 - 例如,如果您的方法签名是:
...然后它变得更加复杂,你会想要在C#泛型中查看covariance and contravariance .
如果您有权访问控制器,您可以添加另一个继承抽象类的类而不指定任何成员,并使用它来序列化反序列化,然后将其基础返回到另一个层吗?
我知道这不是一个好习惯,但有些黑客但我不知道抽象类是否可以某种方式序列化 .
不 - 试图将JSON反序列化为抽象类的对象是没有意义的 . 你能不能成为一个合适的 class ?