【问题标题】:ASP .NET MVC controller model parameter is nullASP .NET MVC 控制器模型参数为空
【发布时间】:2015-04-24 16:53:54
【问题描述】:

我想要实现的最终目标是从 HTTP POST 请求中获取 MULTIPLE PARAMS,所以如果您知道任何其他方法,请告诉我。

我正在使用

  • ASP .NET 自托管 MVC,最新版本。
  • 本地主机
  • 用于路由的属性映射_
  • 一些用于 POST 消息测试的 chrome 扩展,我没有忘记在标题中添加 Content-Type: application/json

我尝试的第一个代码如下所示:

[RoutePrefix("report")]
public class DefaultController : ApiController
{
    [HttpPost, Route("error")]
    public HttpResponseMessage Echo(string uid, string buildNumber, string log,
        string stack, string context, ...)
    {
        Console.WriteLine("received message: ");
        Console.WriteLine(" uid: " + uid);
        Console.WriteLine(" buildNumber: " + buildNumber);
        Console.WriteLine(" log: " + log);
        Console.WriteLine(" stack: " + stack);
        ...

        return Request.CreateResponse(HttpStatusCode.OK);
    }
}

但如果我尝试访问路由到控制器的http://localhost:XXX/report/error,我会收到以下消息:

No HTTP resource was found that matches the request URI

我有点想通了,对于 POST 消息,我必须使用 Model 使用单个参数(这是真的吗??),所以我添加了一个名为 ReportModel 的模型并修改如下:

[RoutePrefix("report")]
public class DefaultController : ApiController
{
    [HttpPost, Route("error")]
    public HttpResponseMessage Echo(ReportModel report)
    {
        Console.WriteLine("received message: ");
        Console.WriteLine(" uid: " + report.Uid);
        Console.WriteLine(" buildNumber: " + report.BuildNumber);
        Console.WriteLine(" log: " + report.Log);
        Console.WriteLine(" stack: " + report.Stack);
        ...

        return Request.CreateResponse(HttpStatusCode.OK);
    }
}

现在我得到了参数reportnull 值。请帮我弄清楚如何在 HTTP POST 中获取多个参数。

[(也许?)已解决]

原始数据如下所示:

POST /report/error HTTP/1.1
Host: localhost:10999
Content-Type: application/json
Accept: application/json
Cache-Control: no-cache

{ "Uid":"asdf", "BuildNumber":"qwer", "Log":"hoo", "Stack":"asdfasdf", ...

我在 Postman Chrome 扩展程序中发送了一个“form-data”标签,但它一次又一次地无法工作。 然后我改为“原始”标签,然后它就可以正常工作了。

我仍然不知道是什么问题。不过,还是非常感谢您的帮助。

【问题讨论】:

  • 另一种选择是FormCollection,但这更适用于没有固定模型的情况。
  • 实际的 POST 是什么样的?
  • 首先要检查的是您在 Fiddler 中的 POST 正文。此外,ReportModel 类必须具有用于反序列化的公共属性。
  • @Padraic 我忘了说我已经做到了!
  • @ParkJongBin 如果你已经解决了,你能不能把你的答案发给别人。

标签: c# asp.net-mvc


【解决方案1】:

确保发布到 Web API 操作的数据结构与模型的数据结构相匹配。

为了帮助您进行调试,您可以安装一个名为 Swashbuckle 的 Nuget 包。 Swashbuckle 记录您当前基于 MVC/Web API 的控制器和操作,同时考虑到每个控制器的输入和输出。最好的部分(也是对您最有帮助的一点)是它提供了一个 UI 供您测试每个操作,甚至可以根据您的操作参数的结构创建所需的数据结构。

安装包会创建一个路由(例如http://myrooturl/swagger)供您访问 UI 本身,因此无需配置,因为它开箱即用。

如果您可以使用 API 操作并填充参数,那么您创建 POST 的手动方法有问题。如果由于某种原因它仍然失败,那么至少你有一种自我记录的方法,因为 Swagger UI 会自动更新操作列表。

【讨论】:

    【解决方案2】:

    您需要配置您的 Web API 路由以接受 ReportModel 参数。

    config.Routes.MapHttpRoute(name: "newont",
                    routeTemplate: "api/{controller}/{ReportModel}/{id}",
                    defaults: new { controller = "Controllername", ReportModel= "ReportModel", new { id = RouteParameter.Optional }}
                );
    

    For more info

    【讨论】:

    • 我正在使用属性进行路由(如httpConfig.MapHttpAttributeRoutes();)。我还需要显式配置路由吗?我想处理没有MapHttpRoute()函数的代码。
    • @ParkJongBin 无需同时添加
    • 实际上路由正在工作。我可以在控制器代码上附加调试器,在那里我发现report 参数为空。
    • @ParkJongBin 在发布时您的 ReportModel 对象可能为空
    • “在发布时”是什么意思?参数report为null的时间是在函数调用的开始,我希望POST调用应该在那个时候已经被解析。
    【解决方案3】:

    你可以从 jquery 中调用 post 方法并在数据字段中传递参数。

    $.ajax(
    {
        url: "report/error",
        type: "POST",
        data: { uid: "1", buildNumber: "123", log ="log string", context = "context", stack = { property: "value"} },
        success: function (result) {
            alert(result);
        },
        error: function (xhr, status, p3, p4) {
            var err = "Error " + " " + status + " " + p3;
            if (xhr.responseText && xhr.responseText[0] == "{")
                err = JSON.parse(xhr.responseText).message;
            alert(err);
        }
    });
    

    【讨论】:

      【解决方案4】:

      使用 API 时,最好将模型用于多个参数。

      如果您使用的是 Javascript,则在模型中使用相同的名称构建对象,它们将根据请求进行映射。

      此外,如果您需要返回相同的数据来操作前端,您可以构建一个对象并像这样返回它

      return Request.CreateResponse(HttpStatusCode.OK, myObject);

      【讨论】:

      • 只是补充一点:我看到你的模型的属性是 CamelCased 而你收到的参数不是;映射区分大小写。
      • 模型具有 CamalCased 属性,并且我还更改了我的 HTTP POST 发件人以发送 CamalCased 密钥。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多