ASP.. NET MVC不能将Http Get请求解析为Json模型



我正在通过Http get请求获取电影列表向公共themoviedb api发送get请求。我的电影模型:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace CSApp.Models;
using Newtonsoft.Json;
[Table("Movies")]
public class Movie
{
public bool? adult { get; set; }
public string? backdrop_path { get; set; }
[JsonIgnore]
[NotMapped]
public IList<int>? genre_ids { get; set; }
[Key]
[Required]
public int id;
public string? original_language { get; set; }
public string? original_title { get; set; }
public string? overview { get; set; }
public decimal? popularity { get; set; }
public  string? poster_path { get; set;}
[Column(TypeName = "datetime")]
public DateTime? release_date { get; set;}
public string? title{ get; set;}
public bool? video { get; set; }
public decimal? vote_average { get; set; }
public int?  vote_count{ get; set;}
}

Make request goes to:https://api.themoviedb.org/3/discover/movie?api_key=XXXXXXXXXXXXXXXXXX

我的控制器:

using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using CSApp.Models;
using static System.Console;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace CSApp.Controllers;
//[ApiController]
//[Route("/api/[controller]")]
public class MovieController: Controller
{
private ILogger<MovieController> _logger;
private IHttpClientFactory _clientFactory;
private readonly MovieDBContext _db;
public MovieController( ILogger<MovieController> logger,
IHttpClientFactory httpClientFactory, MovieDBContext db)
{
_logger = logger;
_clientFactory = httpClientFactory;
_db = db;
}
public IActionResult Index()
{
ViewData["Title"] = "Movies List";
ViewData["DayName"] = DateTime.Now.ToString("dddd");
IList<Movie> model = _db.DBMovies.ToList();        
return View(model);
}

[HttpGet]
[ProducesResponseType(200, Type = typeof(IEnumerable<Object>))]
public async Task<IActionResult> Movies()
{

string api_key = "XXXXXXXXXXXX";
string uri = $"discover/movie?api_key={api_key}";
HttpClient client = _clientFactory.CreateClient("MoviesDBClient");

HttpRequestMessage request = new(method: HttpMethod.Get, uri );
HttpResponseMessage response = await client.SendAsync(request);

if (response.IsSuccessStatusCode)
{
dynamic result = response.Content.ReadAsStringAsync().Result;
var jsonObject = JObject.Parse(result);
Movie moviesList = (jsonObject["results"]).toArray()[0];
//string[]? titles = moviesList.Select(m => m.title).ToArray();
Console.WriteLine( moviesList);
//var movies = JsonConvert.DeserializeObject<Movie>(moviesList);
////return View(result);
//IEnumerable<Movie>? model = await response.Content.ReadFromJsonAsync<IEnumerable<Movie>>().Result;
//return View(model);
return View();
}
else
{
return NotFound();
}

//return View(model);

}
}

Finally My Movies View:

@using CSApp
@model Movie[]
@{
ViewData["Title"] = "Movies from Json Requests";
Movie[]? movies = ViewData["Movies"] as Movie[];
}
<div class="text-center">
<h1 class="display-4">@ViewData["Title"]</h1>
<p>Other List of movies:</p>
<table class="table">
<thead class="thead-inverse">
<tr><th>Movie Name</th></tr>
</thead>
<tbody>
@if (Model is not null)
{
<table class="table table-info">
@foreach (Movie m in Model)
<tr>
<td>@m.title has a avg rating of @m.vote_average</td>
</tr>
</table>
}
else
{
<p>No movies found.</p>
}
</tbody>
</table>
</div>

moviesdb JSON响应如下所示:

{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/wcKFYIiVDvRURrzglV9kGu7fpfY.jpg",
"genre_ids": [
14,
28,
12
],
"id": 453395,
"original_language": "en",
"original_title": "Doctor Strange in the Multiverse of Madness",
"overview": "Doctor Strange, with the help of mystical allies both old and new, traverses the mind-bending and dangerous alternate realities of the Multiverse to confront a mysterious new adversary.",
"popularity": 12833.993,
"poster_path": "/9Gtg2DzBhmYamXBS1hKAhiwbBKS.jpg",
"release_date": "2022-05-04",
"title": "Doctor Strange in the Multiverse of Madness",
"video": false,
"vote_average": 7.5,
"vote_count": 3596
},
{
"adult": false,
"backdrop_path": "/zGLHX92Gk96O1DJvLil7ObJTbaL.jpg",
"genre_ids": [
14,
12,
28
],
"id": 338953,
"original_language": "en",
"original_title": "Fantastic Beasts: The Secrets of Dumbledore",
"overview": "Professor Albus Dumbledore knows the powerful, dark wizard Gellert Grindelwald is moving to seize control of the wizarding world. Unable to stop him alone, he entrusts magizoologist Newt Scamander to lead an intrepid team of wizards and witches. They soon encounter an array of old and new beasts as they clash with Grindelwald's growing legion of followers.",
"popularity": 3338.797,
"poster_path": "/jrgifaYeUtTnaH7NF5Drkgjg2MB.jpg",
"release_date": "2022-04-06",
"title": "Fantastic Beasts: The Secrets of Dumbledore",
"video": false,
"vote_average": 6.8,
"vote_count": 2067
},...

当试图将响应转换为JsonConvert<IList<Movie>>()... or Movie[]时,我在试图解析时得到一个错误的属性消息…我如何从json中选择结果数组,然后将其解析为电影列表以传递给视图????

你必须修改你的代码

var jsonObject = JObject.Parse(result);
List<Movie> moviesList = jsonObject["results"].ToObject<List<Movie>>();
//if you want the first movie
Movie firstMovie=moviesList[0];

为了完整起见,我还展示了返回View(Model)的其他方法:Serge的回答是正确的:

HttpRequestMessage request = new(method: HttpMethod.Get, uri);
HttpResponseMessage response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
dynamic result = response.Content.ReadAsStringAsync().Result;
var jsonObject = JObject.Parse(result);
var movie = jsonObject["results"];
JArray? jArray = JArray.FromObject(movie);
List<Movie>? movies = jArray?.ToObject<List<Movie>>();
//or simply:
List<Movie> moviesList = jsonObject["results"].ToObject<List<Movie>>();
return View(moviesList);
}

另一种(可能更好)的方法是为您的响应创建一个接口,它与您的响应对象的结构相匹配:

public class MovieIndexViewModel
{
public int? page { get; set; }
public int? total_pages { get; set; }
public int? total_results { get; set; }
public IEnumerable<Movie>? results { get; set; }
}
然后,您可以访问IEnumerable属性,并且它还正确地将Movie对象的响应数组(来自Http请求)转换为电影列表:
if (response.IsSuccessStatusCode)
{
MovieIndexViewModel? model = await response.Content.ReadFromJsonAsync<MovieIndexViewModel>();
IEnumerable<Movie> movies = model?.results;
Console.WriteLine(movies.Count());
return View(movies);
}

最新更新