简体   繁体   English

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

[英]MVC Web API POST Entity (500 internal server error)

I've been working on building an API for my company's website. 我一直在为我公司的网站构建API。 I've got actions for all of my GETs working fine and returning JSON like I want. 我已经为我的所有GET工作做得很好,并按照我想要的方式返回JSON。

I'm having problems when it comes to using POST to create new records though. 我在使用POST创建新记录方面遇到了问题。 I'm sending JSON to my controller. 我正在向我的控制器发送JSON。 This works fine if my controller is accepting a string or object parameter, but doesn't work when it is expecting a Model. 如果我的控制器接受字符串或对象参数,这可以正常工作,但是当它期待模型时不起作用。

Inside my api controller, I have this method: 在我的api控制器中,我有这个方法:

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

From what I've been reading it looks like Web API should be able to deserialize the JSON that is posted automatically (and put it into my Model), but instead I always get a 500 Internal Server Error. 从我一直在阅读它看起来Web API应该能够反序列化自动发布的JSON(并将其放入我的模型中),但我总是得到500内部服务器错误。 The method works fine when I tell it to accept a string. 当我告诉它接受一个字符串时,该方法工作正常。

Is there something obvious I'm doing wrong here? 有什么明显的东西我在这里做错了吗?

Edit: Here's the stack trace from the test page I'm using to call the API Method: 编辑:这是我用来调用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

Web API, like other REST frameworks, is encouraging and supporting using a POCO serializable to JSON DTO. 与其他REST框架一样,Web API鼓励并支持使用可序列化为JSON DTO的POCO。 The serialization seems to be failing. 序列化似乎失败了。

Without the client code, which should be creating a properly formatted JSON body to POST, properly setting the content type being posted as application/json, it is hard to tell which part of the client code isn't correct. 如果没有客户端代码(应该为POST创建格式正确的JSON主体),正确设置发布为application / json的内容类型,则很难分辨客户端代码的哪个部分不正确。

The error being reported as an internal server error isn't helpful. 报告为内部服务器错误的错误没有帮助。 The fact that your code isn't being reached, without even looking at the StackTrace, clearly indicates that the issue is occurring in framework code. 甚至没有查看StackTrace就无法访问您的代码这一事实清楚地表明问题出现在框架代码中。 The framework is expecting a properly formatted DTO, so compare the DTO being POST'd vs the DTO's definition OR construct and serialize an instance of the DTO and compare the actual strings. 该框架期望格式正确的DTO,因此比较POST的DTO与DTO的定义OR构造并序列化DTO的实例并比较实际的字符串。

I fell on something similar today, and my issue was that there were multiple possible actions in my controller that could be used by Web Api and it wasn't able to know which one to use. 今天我遇到了类似的问题,我的问题是我的控制器中有多个可能被Web Api使用的操作,并且它无法知道使用哪一个。 So in my case I used the longest form client-side and server-side for the action, instead of relying on default api route : 所以在我的情况下,我使用最长的客户端和服务器端进行操作,而不是依赖于默认的api路由:

Router: 路由器:

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

Ajax call: Ajax调用:

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

return $.ajax(options);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM