JSON 值无法转换为 Model Blazor
The JSON value could not be converted to Model Blazor
第一个 Blazor WASM 应用程序。从服务器获取数据时出错:
System.Text.Json.JsonException: Deserialization failed for one of these reasons:
- Invalid property 'result' found within a JSON object that must only contain metadata >properties and the nested JSON array to be preserved.
- The JSON value could not be converted to WeatherBA.Shared.Dtos.ForecastReadDto[]. Path: >$.result | LineNumber: 0 | BytePositionInLine: 10.
FetchData.razor
@code {
private ForecastReadDto[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetFromJsonAsync<ForecastReadDto[]>("api/Forecast");
}
ForecastController.cs
public class ForecastController : ControllerBase
{
private readonly IMediator _mediator;
public ForecastController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public ActionResult<IEnumerable<ForecastReadDto>> GetAllForecasts()
{
var request = new GetAllForecastsQuery();
var result = _mediator.Send(request);
return Ok(result);
}
}
GetAllForecastsQueryHandler.cs
...
public async Task<List<ForecastReadDto>> Handle(GetAllForecastsQuery request,
CancellationToken cancellationToken)
{
var forecasts = await _repo.GetAllAsync();
var forecastsOrdered = forecasts.OrderBy(x => x.Date);
return _mapper.Map<List<ForecastReadDto>>(forecasts);
}
SqlForecastRepo.cs
...
public Task<List<Forecast>> GetAllAsync()
{
return Task.FromResult(_context.Forecasts.ToList());
}
ForecastReadDto.cs
namespace WeatherBA.Shared.Dtos;
public class ForecastReadDto
{
public int Id { get; set; }
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
}
一个API端点returns:
{
"result": [
{
"id": 3,
"date": "2022-01-01T00:00:00",
"temperatureC": 20,
"summary": "Sunny"
}
],
"id": 4639,
"exception": null,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": 0,
"asyncState": null,
"isFaulted": false
}
您出现意外结果的原因是您正在序列化一个 Task
而不是等待任务结束并发送结果。我在下面的示例中对此进行了说明。这就是您在不等待任务的情况下发送数据的方式:
using System.Text.Json;
namespace MyApp;
public class DTO
{
public string Data {get; set;} = default!;
}
public class Program
{
static void Main(string[] args)
{
var result = Task.FromResult(new DTO(){Data="Hi"});
var options = new JsonSerializerOptions { WriteIndented = true };
var result_serialized = JsonSerializer.Serialize(result, options);
System.Console.WriteLine(result_serialized);
}
}
结果:
{
"Result": {
"Data": "Hi"
},
"Id": 1,
"Exception": null,
"Status": 5,
"IsCanceled": false,
"IsCompleted": true,
"IsCompletedSuccessfully": true,
"CreationOptions": 0,
"AsyncState": null,
"IsFaulted": false
}
这是解决问题的方法。要获取数据,您应该等待 Task
结果:
using System.Text.Json;
namespace MyApp;
public class DTO
{
public string Data {get; set;} = default!;
}
public class Program
{
static async Task Main(string[] args)
{
var result = await Task.FromResult(new DTO(){Data="Hi"}); //<-- HERE
var options = new JsonSerializerOptions { WriteIndented = true };
var result_serialized = JsonSerializer.Serialize(result, options);
System.Console.WriteLine(result_serialized);
}
}
结果:
{
"Data": "Hi"
}
第一个 Blazor WASM 应用程序。从服务器获取数据时出错:
System.Text.Json.JsonException: Deserialization failed for one of these reasons:
- Invalid property 'result' found within a JSON object that must only contain metadata >properties and the nested JSON array to be preserved.
- The JSON value could not be converted to WeatherBA.Shared.Dtos.ForecastReadDto[]. Path: >$.result | LineNumber: 0 | BytePositionInLine: 10.
FetchData.razor
@code {
private ForecastReadDto[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetFromJsonAsync<ForecastReadDto[]>("api/Forecast");
}
ForecastController.cs
public class ForecastController : ControllerBase
{
private readonly IMediator _mediator;
public ForecastController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public ActionResult<IEnumerable<ForecastReadDto>> GetAllForecasts()
{
var request = new GetAllForecastsQuery();
var result = _mediator.Send(request);
return Ok(result);
}
}
GetAllForecastsQueryHandler.cs
...
public async Task<List<ForecastReadDto>> Handle(GetAllForecastsQuery request,
CancellationToken cancellationToken)
{
var forecasts = await _repo.GetAllAsync();
var forecastsOrdered = forecasts.OrderBy(x => x.Date);
return _mapper.Map<List<ForecastReadDto>>(forecasts);
}
SqlForecastRepo.cs
...
public Task<List<Forecast>> GetAllAsync()
{
return Task.FromResult(_context.Forecasts.ToList());
}
ForecastReadDto.cs
namespace WeatherBA.Shared.Dtos;
public class ForecastReadDto
{
public int Id { get; set; }
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
}
一个API端点returns:
{
"result": [
{
"id": 3,
"date": "2022-01-01T00:00:00",
"temperatureC": 20,
"summary": "Sunny"
}
],
"id": 4639,
"exception": null,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": 0,
"asyncState": null,
"isFaulted": false
}
您出现意外结果的原因是您正在序列化一个 Task
而不是等待任务结束并发送结果。我在下面的示例中对此进行了说明。这就是您在不等待任务的情况下发送数据的方式:
using System.Text.Json;
namespace MyApp;
public class DTO
{
public string Data {get; set;} = default!;
}
public class Program
{
static void Main(string[] args)
{
var result = Task.FromResult(new DTO(){Data="Hi"});
var options = new JsonSerializerOptions { WriteIndented = true };
var result_serialized = JsonSerializer.Serialize(result, options);
System.Console.WriteLine(result_serialized);
}
}
结果:
{
"Result": {
"Data": "Hi"
},
"Id": 1,
"Exception": null,
"Status": 5,
"IsCanceled": false,
"IsCompleted": true,
"IsCompletedSuccessfully": true,
"CreationOptions": 0,
"AsyncState": null,
"IsFaulted": false
}
这是解决问题的方法。要获取数据,您应该等待 Task
结果:
using System.Text.Json;
namespace MyApp;
public class DTO
{
public string Data {get; set;} = default!;
}
public class Program
{
static async Task Main(string[] args)
{
var result = await Task.FromResult(new DTO(){Data="Hi"}); //<-- HERE
var options = new JsonSerializerOptions { WriteIndented = true };
var result_serialized = JsonSerializer.Serialize(result, options);
System.Console.WriteLine(result_serialized);
}
}
结果:
{
"Data": "Hi"
}