【问题标题】:ASP .NET WebAPI Route Data SchemaASP .NET WebAPI 路由数据架构
【发布时间】:2016-02-05 05:21:15
【问题描述】:

目前,我们正在使用这样的路线:

[HttpPost]
[Route("upload")]
public async Task<dynamic> Upload(dynamic uploadedData)
{
    JArray files = uploadedData.pdfs;
    // ...
}

我不想使用dynamic,而是希望对传入的数据有一个大致的了解。所以我可以使用这样的设置,并使用一个定义架构的类:

public class UploadRequest : JObject
{
    public JArray pdfs { get; set; }
}

[HttpPost]
[Route("upload")]
public async Task<dynamic> Upload(UploadRequest uploadedData)
{
    // Now can access the JArray via uploadedData.pdfs directly
    // ...
}

这是解决这种情况的正确方法吗?或者是否有另一种通过 ASP .NET WebAPI 接收 JSON 数据的标准最佳实践?

具体来说,这种方法目前不起作用。虽然我的小型架构类扩展了 JObject,但我得到了一个错误

参数字典包含“EditPdfServer.Controllers.PdfFileController”中方法“System.Threading.Tasks.Task`1[System.Object] Upload(UploadRequest)”的参数“uploadedData”的无效条目。字典包含“Newtonsoft.Json.Linq.JObject”类型的值,但参数需要“EditPdfServer.Controllers.PdfFileController+UploadRequest”类型的值。

首先,这似乎是一种合适的方法吗?其次,有没有更好的?第三,为什么这种方法不起作用?提前致谢。

【问题讨论】:

标签: c# asp.net asp.net-web-api routes schema


【解决方案1】:

你走上正轨了。

您无需过分关注 Newtonsoft.Json 的内部实现。特别是,你应该尽量避免使用 JObject/JToken/其他 J-types,你绝对不需要继承 JObject。

您的请求对象类可以是:

public class UploadRequest
{
    [JSONProperty("pdfs")]
    public SomePDFClass PDFs[] { get; set; }
}

这将映射到以下请求:

{
    "pdfs": [
        { <some PDF object here> },
        { <some PDF object here> },
        { <some PDF object here> }
    ]
}

JSONPropertyAttribute 的字符串参数定义了属性在 JSON 文档中出现的名称,因此您不需要在代码中使用与在 JSON 中相同的名称。您可以在代码中更改名称,只要该属性仍使用与文档相同的名称即可。

【讨论】:

    【解决方案2】:

    我建议为您的 pdfs 属性使用 JSONproperty 属性:

    public class UploadRequest : JObject
    {
       [JSONProperty("<name of the property in the JSON object>")]
       public JArray pdfs { get; set; }
    }
    

    还可以查看这篇文章以获取有关该属性的更多信息:JSON.NET deserialize/serialize JsonProperty JsonObject

    【讨论】:

      【解决方案3】:

      由于您的方法使用后置动词,您应该在方法参数上添加属性[FromBody]

      [HttpPost]
      public async Task<dynamic> Upload([FromBody] UploadRequest UploadedData)
      {
          // Now can access the JArray via uploadedData.pdfs directly
          // ...
      }
      

      【讨论】:

      • 值得一提的是,您只能以这种方式标记 1 个参数。如果您需要多个参数,请考虑创建一个包含所有参数的包装器对象。
      猜你喜欢
      • 2016-02-03
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多