2013-10-12 78 views
0

我一直在爲我公司的網站構建API。我已經爲我所有的GET都能正常工作並按照我的要求返回JSON。MVC Web API POST實體(500內部服務器錯誤)

雖然我在使用POST創建新記錄時遇到了問題。我將JSON發送給我的控制器。如果我的控制器正在接受一個字符串或對象參數,這工作正常,但在期望模型時不起作用。

在我的API控制器,我有這樣的方法:

[HttpPost] 
public void POSTEstimate(Estimate estimate) 
{ 
    //never makes it to the first line when expecting a Model (Estimate) 
} 

從我一直在讀它看起來像網頁API應該能夠反序列化時自動張貼JSON(並把它放到我的型號),但相反,我總是得到500內部服務器錯誤。當我告訴它接受一個字符串時,該方法正常工作。

有什麼明顯的我在這裏做錯了嗎?

編輯:下面是我使用調用API方法的測試頁的堆棧跟蹤:

[WebException: The remote server returned an error: (500) Internal Server Error.] 
    System.Net.HttpWebRequest.GetResponse() +6120419 
    PDR.Controllers.AdminController.test() in c:\PDR\PDR\PDR\Controllers\AdminController.cs:714 
    lambda_method(Closure , ControllerBase , Object[]) +96 
    System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17 
    System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +205 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27 
    System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28 
    System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +50 
    System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58 
    System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +237 
    System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +12 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50 
    System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24 
    System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +126 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +45 
    System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +61 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +49 
    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 
    System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +28 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +49 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9042109 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184 
+0

調試應用程序時會發生什麼?調試會告訴你爲什麼會發生500內部服務器錯誤。 – JLe

+0

它在調試過程中從不中斷任何地方。它直接進入錯誤頁面。 –

+0

服務器可能會發回一些有關500的信息。這是什麼意思? – JLe

回答

1

的Web API,像其他REST框架,鼓勵並使用支持POCO序列化到JSON DTO 。序列化似乎失敗了。

沒有客戶端代碼,它應該創建一個正確格式化的JSON主體到POST,正確設置發佈爲application/json的內容類型,很難判斷客戶端代碼的哪個部分不正確。

作爲內部服務器錯誤報告的錯誤沒有幫助。事實上,你的代碼沒有被訪問,甚至沒有看到StackTrace,清楚地表明問題發生在框架代碼中。框架需要一個格式正確的DTO,因此比較DTO被POST'd與DTO的定義OR構造並序列化DTO的一個實例並比較實際的字符串。

+0

我正在創建一個實體,然後使用內置的序列化器JavaScriptSerializer().Serialize(Entity)來創建JSON,所以JSON應該已被正確格式化爲JSON。內容類型也正在設置。對於一些小型號,這種完全相同的方法效果很好。我最終最終在POST方法中接受了一個對象,對它進行了ToStringing,然後反序列化了字符串,該字符串在正好接受我的實體時不能正常工作的情況下工作正常。我不太確定,因爲我已經制定了許多方法可以很好地與模型綁定。 –

+0

根據這些信息(仍然不清楚合同爲什麼是無效的(這將需要涉及特定的類),我會推動分裂問題。數據傳輸對象不需要與實體對象完全相同的對象並且實體內部可能有元素使其不適合在服務邊界進行序列化,而不是通過序列化進行映射(進入字符串並返回到不同的類型),通過代碼進行映射Automapper是一個項目,有助於理解和實施這一點。 – paegun

0

我今天倒在了類似的東西上,我的問題是在我的控制器中有多個可能的動作,可能被Web Api使用,它無法知道使用哪一個。所以在我的情況下,我使用的,而不是依賴於默認的API路線的動作最長形式的客戶端和服務器端,:

路由器:

config.Routes.MapHttpRoute(
      name: "ApiWithAction", 
      routeTemplate: "metadataApi/{controller}/{action}/{id}", 
      defaults: new {id = RouteParameter.Optional}); 

Ajax調用:

[...] 
var options = { 
    url: basePath + 'metadataapi/employee/FetchPage', 
    type: 'POST', 
    data: filter, 
    dataType: 'json' 
}; 

return $.ajax(options);