2013-10-12 81 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);