2017-08-16 50 views
2

我正在尋找一種方法來「展開」已發佈到MVC Core服務的JSON。比方說,我有以下方法:「Unwrapping」發佈JSON

[HttpPost]   
public dynamic SayHello(string FirstName, string SecondName) 
{ 
    return $"Hello {FirstName} {SecondName} !"; 
} 

我張貼在下面的JSON:

{ 
    "FirstName":"Joe", 
    "SecondName": "Bloggs" 
} 

,我期望得到的Hello Joe Bloggs !的響應,但我似乎無法找到一個簡單的將JSON對象解包到方法屬性中的方法。

我知道正確的解決方案是有HelloModel與這兩個屬性,巴掌[FromBody]屬性,但由於原因,這是不可能的。

+2

到底爲什麼你不能在這裏創建一個模型?另外,你有沒有嘗試在參數中添加'[FromBody]'? – DavidG

+0

@DavidG我不能在公共論壇上探討原因。遺憾的是FromBody不會改變結果。 –

+0

你可以請包括Chrome開發工具的屏幕截圖,顯示** POST **的'Network - > Headers'? – mjwills

回答

3

這是另一個(稍微複雜的)選項。您可以創建自己的操作篩選器來攔截請求,並根據自己決定JSON的值填充參數。例如:

public class JsonToParametersAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 

     var stream = filterContext.HttpContext.Request.Body; 
     using (var sr = new StreamReader(stream)) 
     using (var jsonTextReader = new JsonTextReader(sr)) 
     { 
      var serializer = new JsonSerializer(); 
      var body = serializer.Deserialize<JObject>(jsonTextReader); 

      if (body == null) return; 

      foreach (var parameter in filterContext.ActionDescriptor.Parameters) 
      { 
       var jsonProperty = body.Properties().SingleOrDefault(p => p.Name == parameter.Name); 

       if (jsonProperty != null) 
       { 
        var param = filterContext.ActionDescriptor.Parameters.OfType<ControllerParameterDescriptor>().FirstOrDefault(e => e.Name == parameter.Name); 

        if (param == null) 
        { 
         continue; 
        } 

        if (!filterContext.ActionArguments.ContainsKey(parameter.Name)) 
        { 
         object value; 

         try 
         { 
          value = jsonProperty.Value.ToObject(param.ParameterInfo.ParameterType); 
         } 
         catch (Exception) 
         { 
          value = GetDefault(param.ParameterInfo.ParameterType); 
         } 

         filterContext.ActionArguments.Add(parameter.Name, value); 
        } 
       } 
      } 
     } 
    } 
    private static object GetDefault(Type type) 
    { 
     if (type.IsValueType) 
     { 
      return Activator.CreateInstance(type); 
     } 
     return null; 
    } 
} 

現在裝飾你的操作方法與這個新的屬性:

[HttpPost]  
[JsonToParameters] 
public dynamic SayHello(string FirstName, string SecondName) 
{ 
    return $"Hello {FirstName} {SecondName} !"; 
} 
+1

我不得不稍微調整你的實現 - https://gist.github.com/surgicalcoder/0ea53d93a6fae663bbf8024f35408a51 - 經過測試,效果非常好! –

+0

哈哈我正準備發佈更新,因爲我注意到你使用的是.Net Core!隨意編輯答案並添加您的代碼,如果你喜歡。 – DavidG