3

使用 webapi,可以将动态 JSON 发布到使用JObjectdynamic作为参数类型的操作:

将动态 JSON 对象传递给 Web API - Newtonsoft 示例

如果我在 MVC4 中的非 api 操作上尝试此操作,这似乎不起作用。我的动作签名是:

public async Task<ActionResult> Post(JObject requestObj)

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

[MissingMethodException]: Cannot create an abstract class.

在 MVC4 中的非 api 操作上是否可能出现类似的情况?

4

3 回答 3

3

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

于 2015-08-20T22:16:07.743 回答
3

我不确定它是否会有所帮助,但我在上面的评论中提到我最终使用自定义模型绑定器来执行此操作。我挖出了我认为是引发这个问题的原始代码,这就是我最终得到的:

    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();
于 2015-08-21T02:39:04.070 回答
0

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

动作方法不能有无界的泛型类型参数。无界泛型类型参数有一个空参数列表。无界泛型类型也称为开放泛型类型。有关无界泛型类型参数的信息,请参阅类型参数约束中的“无界类型参数”部分。

您应该从 APIController 派生,或者创建一个 CustomModelBinder(我不确定这个)

看看以下链接:

将 JObject 发布到操作

.NET MVC Action 类型对象的参数

抽象类可以作为控制器动作中的参数吗?

希望能帮助到你!

于 2015-08-20T20:02:09.900 回答