2013-08-26 28 views
3

用的WebAPI,可以使用任何JObjectdynamic为您的参数类型为POST动态JSON到一个动作:发布动态JSON到MVC4行动

Passing Dynamic JSON Object to Web API - Newtonsoft Example

如果我试试这一个非API在MVC4中这似乎不起作用。我的动作签名是:

public async Task<ActionResult> Post(JObject requestObj) 

当我使用动态时,我只是看到一个看似非动态的对象。如果我尝试JObject我得到以下错误:

[MissingMethodException]: Cannot create an abstract class. 

是在MVC4非API作用与此类似可能的东西吗?

+0

护理讲解下投票,所以我可以改善这个问题? – mutex

+0

检查一下,它可能会帮助你。 [反序列化JSON到C#动态对象?](http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object) –

+0

@ RezaShirazian:谢谢,我知道如何反序列化为动态对象,只是想知道是否有一种方法来自动执行它。我目前的做法是实现一个自定义模型绑定器来做到这一点,但正在寻找其他想法。 – mutex

回答

0

这似乎是不可能的。阅读MSDN文档https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.aspx

Action methods cannot have unbounded generic type parameters. An unbounded generic type parameter has an empty parameter list. An unbounded generic type is also known as an open generic type. For information about unbounded generic type parameters, see the section "Unbounded Type Parameters" in Constraints on Type Parameters.

您应该APIController获得,或者创建一个CustomModelBinder(我不知道这一个)

看看下面的链接:

posting a JObject to an action

.NET MVC Action parameter of type object

Can abstract class be a parameter in a controller's action?

希望它有帮助!

+0

如果我有一个属性强类型模型,我想要绑定为JObject? – Serhiy

+0

等等,动作的参数是一个自定义类还是一个JObject? –

+0

在我的情况下,有一个模型和JObject属性的自定义类。 – Serhiy

3

在之前的项目中,我们需要将动态JSON发布到Web Api控制器。我们最终做的是在客户端使用JSON,并使用Base64对其进行编码。然后,我们可以简单地将Base64编码的JSON发布到我们的后端。然后,我们的后端解码Base64输入,并使用Newtonsoft JSON将其转换为动态对象(实际上它已转换为强类型类并且后退是动态​​的)。我同意,这是哈克,但它的工作。

2

我不确定它是否会有所帮助,但我在上面的评论中提到,我最终使用自定义模型联编程序来执行此操作。我挖出了什么,我相信是促使这个问题的原代码,而这也正是我结束了:

public async Task<ActionResult> Post(dynamic request) 
    { 
     return await ExecuteRequest(request, "application/json"); 
    } 

和一个自定义的模型绑定如下(它的工作原理上称为“后”或“公共行为“尽管你可以选择自己的约定 - 回退到默认的所有其他行动)

public class MyModelBinder : DefaultModelBinder 
{   
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var actionName = controllerContext.RouteData.Values["Action"]; 
     if (controllerContext.Controller.GetType() == typeof(MyController) && actionName != null && 
      (string.Compare(actionName.ToString(), "post", StringComparison.OrdinalIgnoreCase) == 0 || 
      string.Compare(actionName.ToString(), "public", StringComparison.OrdinalIgnoreCase) == 0)) 
     { 
      string contentText; 

      using (var stream = controllerContext.HttpContext.Request.InputStream) 
      { 
       stream.Seek(0, SeekOrigin.Begin); 
       using (var reader = new StreamReader(stream)) 
        contentText = reader.ReadToEnd(); 
      } 

      if (string.IsNullOrEmpty(contentText)) return (null); 

      return JObject.Parse(contentText); 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

然后注册自定义模型粘合剂的Application_Start的开头:

System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new MyModelBinder();