0

我一直在为我公司的网站构建 API。我的所有 GET 都可以正常工作并按照我想要的方式返回 JSON。

不过,在使用 POST 创建新记录时,我遇到了问题。我正在将 JSON 发送到我的控制器。如果我的控制器正在接受字符串或对象参数,这可以正常工作,但在需要模型时不起作用。

在我的 api 控制器中,我有这个方法:

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

从我一直在阅读的内容来看,Web 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
4

2 回答 2

2

与其他 REST 框架一样,Web API 鼓励和支持使用可序列化为 JSON DTO 的 POCO。序列化似乎失败了。

如果没有客户端代码,它应该创建一个格式正确的 JSON 正文以进行 POST,正确设置发布为 application/json 的内容类型,很难判断客户端代码的哪一部分不正确。

作为内部服务器错误报告的错误没有帮助。甚至没有查看 StackTrace 就无法访问您的代码这一事实清楚地表明问题出现在框架代码中。该框架需要一个格式正确的 DTO,因此比较被 POST 的 DTO 与 DTO 的定义 OR 构造并序列化 DTO 的实例并比较实际的字符串。

于 2013-10-12T15:52:54.993 回答
0

我今天遇到了类似的事情,我的问题是我的控制器中有多个可能的操作可以被 Web Api 使用,它无法知道使用哪一个。因此,在我的情况下,我使用最长形式的客户端和服务器端进行操作,而不是依赖默认的 api 路由:

路由器:

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

阿贾克斯调用:

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

return $.ajax(options);
于 2014-01-12T04:31:16.250 回答