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();