【问题标题】:Internal Server Error when posting variables to Web API将变量发布到 Web API 时出现内部服务器错误
【发布时间】:2017-09-19 22:53:02
【问题描述】:

我之前发布了一个类似的帖子并得到了一些很好的答案,但我不小心删除了我的帖子,所以我发布了一个包含更多数据的修订版。

我正在构建一个 Web API 来发布和从我的视图中获取数据。与 API 通信效果很好,但我遇到了问题。

每当我通过发布请求发送数据时,都会收到 500:内部服务器错误。如果我从请求中删除数据,它工作正常。

有效的示例方法:

[HttpPost]
public string Test()
{
    return "this works";
}

因为我没有将任何数据传递到上述方法中,所以我没有遇到任何问题。但是,每当我向请求中添加一些数据时,就像这样:

API方法:

[HttpPost]

public string TestWithVariables(string test)
{
    return test;
}

AJAX 调用:

 $.post({
        url: myUrl + "/api/my-api/TestWithVariables",
        data: { test: "123456" },
        success: function (html) {
            console.log("y")
        },
        error: function () {
            console.log("n");
        }
    });

上面的代码在我的浏览器中输出这些错误:HTTP/1.1 500 Internal Server Error and XML Parsing Error: Root element not found。问题是,如果我在 API 方法的第一行设置断点,它永远不会被命中,这意味着该方法没有找到,或者由于某种原因被执行......?

我尝试过的一些东西:将我的参数分解为一个 TestClass 并使用[FromBody]。我也尝试过使用[FromUri],它实际上使方法执行,但我无法从那里访问值,因为我的值已发布在正文中。

任何想法可能导致这些问题?

【问题讨论】:

  • 您的路线定义正确吗?
  • 路由都很好 - 如果我将方法从它们执行的参数中剥离出来。
  • 使用数据为:JSON.Stringify({ test: "123456" });

标签: asp.net-mvc asp.net-web-api


【解决方案1】:

根据您提供的数据,可能的问题可能是: 您没有使用 stringify 将您的数据转换为 ajax 请求中的字符串 json。 使用以下

data:JSON.stringify({ test: "123456" });

如果它不起作用,则共享您可以共享的控制器和其他数据。

【讨论】:

  • 或发送完整的 url.... myUrl + "/api/my-api/TestWithVariables" 和控制器 + 类的授权属性(如果有)。
  • 谢谢!我现在在发布之前对数据进行字符串化,但我仍然遇到同样的问题。
  • @maskinen999 你能尝试一下你的操作方法上的 [allowanonymous] 属性吗
【解决方案2】:

控制器:

[HttpPost]
public string TestWithVariables([FromBody]string test) // added FromBody 
{
return test;
}

阿贾克斯:

$.post({
    url: myUrl + "/api/my-api/TestWithVariables",
    data: { test: "=123456" }, //prefix data with = sign
    success: function (html) {
        console.log("y")
    },
    error: function () {
        console.log("n");
    }
});

【讨论】:

    【解决方案3】:

    你可以做几件事,首先确保将请求的内容类型设置为json,如果不设置默认为xml。

    如果不需要,也可以完全删除 xml 格式化程序。

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                config.Formatters.Clear();
                config.Formatters.Add(new JsonMediaTypeFormatter());
            }
        }
    

    这个类位于 App_Start 中。

    无论哪种方式,请确保内容类型设置正确。

    最后确保在发送之前对数据进行字符串化:

    var model = JSON.stringify({ test: "123456" });
    
    $.post({
            url: myUrl + "/api/my-api/TestWithVariables",
            data: model,
            success: function (html) {
                console.log("y")
            },
            error: function () {
                console.log("n");
            }
        });
    

    如果您仍然无法正确点击控制器,请检查您的路线。

    从不带参数的 POST 方法开始。一旦你可以点击它,给它添加一个参数并添加一个 [FromBody] 属性。

    如果您收到 500 错误,则表示您在某处存在内部错误。在你的方法中设置一个断点,看看你是否命中它。

    现在,关于路线。假设您的控制器名为 SomeController

    您的路线将成为 /Some/method 名称。 您可以使用控制器上的 RoutePrefix 属性和方法上的 Route 属性来完全控制您的路由。

    说实话,我不会有这样的路线:/api/my-api/

    是的,它是一个 api,它是你的,不需要把它放在路由中。

    因此,将您的 RoutePrefix 设置为 api 并将方法上的 Route 设置为 test-param 然后您的 url 变为:例如 /api/test-param

    [RoutePrefix("api")]
    public class TestController : ApiController
    
        [HttpPost]
        Route["test-param"]
        public string TestWithVariables([FromBody] string test)
        {
            return test;
        }
    

    然后你的js:

    var model = JSON.stringify({ test: "123456" });
    
    $.post({
            url: myUrl + "/api/test-param",
            data: model,
            contentType: "application/json",
            success: function (html) {
                console.log("y")
            },
            error: function () {
                console.log("n");
            }
        });
    

    我不确定 contentType 的正确语法,但我认为它应该足够接近。

    对于我个人喜欢 Elmah 的错误处理,一旦配置它就会记录所有异常,您只需调用 url/elmad.axd 即可查看所有错误报告。

    最后一件事,在构建 API 时使用好的客户端是个好主意。我更喜欢 Postman,因为它可以让您轻松制作所需的任何请求。一旦你在 Postman 中完成所有工作,你就可以简单地在 Javascript 中构建该请求。

    【讨论】:

    • 你的回答有什么特别之处?
    • 感谢您的快速回答。我现在在传递数据之前使用 JSON.stringify,但我仍然遇到同样的错误。我还将 JSON 格式化程序添加到 WebApiConfig,但这也无济于事。还有其他可能的问题吗?
    • 添加了更多细节
    • 谢谢哥们。我将路线重组为您更清洁的方法。但是,我仍然没有找到方法。设置新路线后,我: 发布到没有参数的方法——这有效。之后,我用参数发布到它,我立即得到内部服务器错误 500,即使尝试使用 [FromBody] 也是如此。我在方法的第一行有一个断点,但它没有被命中,所以该方法甚至没有被执行......
    • 错误消息中除 500 代码之外的任何详细信息?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 2015-09-02
    • 2017-08-26
    • 1970-01-01
    相关资源
    最近更新 更多