MVC Web API POST 实体(500 内部服务器错误)

本文关键字:内部 服务器 错误 Web API POST 实体 MVC | 更新日期: 2023-09-27 18:35:09

我一直在为我公司的网站构建API。我已经为我的所有 GIT 执行了操作,并且可以像我想要的那样返回 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

MVC Web API POST 实体(500 内部服务器错误)

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

如果没有客户端代码(应该为 POST 创建一个格式正确的 JSON 正文),正确设置要发布的内容类型作为应用程序/json,很难判断客户端代码的哪个部分不正确。

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

我今天遇到了类似的事情,我的问题是我的控制器中有多个可能的操作可以被 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);