При публикации в веб-приложении ASP. NET Core 3.1 "[FromBody] MyClass data" часто имеет значение null - PullRequest
0 голосов
/ 05 марта 2020

Я столкнулся с этой интересной (расстраивающей) проблемой недавно после обновления. NET Core 2.2 до 3.1. Ранее я отправлял данные POST в веб-приложение с методом получения, который выглядел примерно так:

public IActionResult OnPostAddNewDataAsync([FromBody]MyClass data)
{
    //...
}

, где MyClass может выглядеть примерно так:

public class MyClass
{
    public string Field1 {get; set;}
    public integer Value1 {get; set;}
}

(для справки Чтобы достичь конечной точки из Javascript, вы можете сделать это следующим образом:

 await PostDataAsync("AddNewData", {
      "Field1": "Hello I am",
      "Value1": 7
 });

async function PostDataAsync(handler, data)
{
    return await $.ajax({
        url: window.location.pathname + "?handler=" + handler,
        type: "POST",
        contentType: "application/json",
        headers:
        {
            RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
        },
        data: JSON.stringify(data)
    });
}

Мне потребовалось некоторое время, чтобы понять это!).

Это сработало нормально.

После обновления. NET Core 3.1, многие из моих методов POST перестали работать, и значение [FromBody] было бы нулевым.

Примечание: как часть моего обновления до. NET Core 3.1 Я удалил ссылки на Newtonsoft.Json, решив вместо этого попробовать и использовать новый System.Text.Json. Это окажется важным!

1 Ответ

3 голосов
/ 05 марта 2020

Как уже упоминалось, ссылки на Newtonsoft.Json были удалены, в результате чего любое автоматическое преобразование c Json было обработано System.Text.Json. Оказывается, это было причиной проблемы, поскольку System.Text.Json не так гибок (сами Microsoft так говорят, и что это должно быть так: Как перейти с Newtonsoft. Json на System.Text . Json) .

До. NET Ядро 3, ASP. NET Ядро использовало Newtonsoft.Json для внутреннего использования, и теперь оно использует System.Text.Json вместо.

Примером является поле с цифрой c, например, MyClass.Value1. Если из Javascript вы передадите «10» или 10, Newtonsoft.Json справится с этим и распознает оба значения как 10. При System.Text.Json по умолчанию это поле не может содержать окружающие кавычки, и если в Json вы разместили, оно сделало вы получите нулевое значение [FromBody].

Самое быстрое решение этой проблемы - вернуться к Newtonsoft.Json для этих случаев, и это легко сделать:

  • установив пакет Nuget Microsoft.AspNetCore.Mvc.NewtonsoftJson
  • в Startup.cs, обновите следующий метод следующим образом:

.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages().AddNewtonsoftJson();

    //All your other code:
    //...
}

Это взято непосредственно из здесь .

После внесения этого изменения все снова заработало, как и ожидалось.

Я знаю, что System.Text.Json можно настроить с помощью пользовательских анализаторов для обработки подобных ситуаций ( который я использую в другом месте), но у меня есть десятки методов POST, и вместо того, чтобы обновлять их все для работы с новым способом, это было намного проще сделать, как описано выше.

...