Схема данных маршрута ASP.NET WebAPI

В настоящее время мы используем такой маршрут:

[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
    // ...
}

Это правильный подход к этой ситуации? Или существует еще одна стандартная передовая практика для получения данных JSON через ASP.NET WebAPI?

В частности, этот подход в настоящее время не работает. Хотя мой небольшой класс схемы расширяет JObject, я получаю сообщение об ошибке

Словарь параметров содержит недопустимую запись для параметра 'uploadedData' для метода 'System.Threading.Tasks.Task`1 [System.Object] Upload (UploadRequest)' в 'EditPdfServer.Controllers.PdfFileController'. Словарь содержит значение типа "Newtonsoft.Json.Linq.JObject", но для параметра требуется значение типа "EditPdfServer.Controllers.PdfFileController + UploadRequest".

Итак, во-первых, похоже ли это на правильный подход? Во-вторых, есть ли лучший? В-третьих, почему этот подход не работает? Спасибо заранее.

Ответ 1

Вы в пути.

Вам не нужно слишком беспокоиться о внутренней реализации Newtonsoft.Json. В частности, вам следует попытаться избежать использования JObject/JToken/других J-типов, и вам определенно не нужен подкласс 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

Я бы предложил использовать атрибут JSONproperty для вашего свойства pdfs:

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
    // ...
}