为什么 RestSharp 返回 text/html 而不是 json?

Why is RestSharp returning text/html instead of json?

我正在尝试使用 TMDB API 构建微服务。

代码:

using System.Text.Json;
using Microsoft.Extensions.Options;
using Net5Micro.Config;
using RestSharp;

namespace Net5Micro.Services
{
    public class ApiClient : IApiClient
    {
        private readonly ServiceSettings _settings;
        
        public ApiClient(IOptions<ServiceSettings> settings)
        {
            _settings = settings.Value;
        }
        
        public Movie GetById(string id)
        {
            //Init rest client
            var client = new RestClient($"{_settings.TMDBhost}/movie/{id}");
            
            //Init rest request
            var request = new RestRequest(Method.GET);
            request.RequestFormat = DataFormat.Json;

            //Add Request params
            request.AddParameter("api_key", _settings.ApiKey, ParameterType.GetOrPost);

            //Calling Api 
            var response = client.Get(request);
            
            var movies = JsonSerializer.Deserialize<Movie>(response.Content);
            
            return movies;
        }

        // Za najpopularnije
        public Movies Discover(string sort)
        {
            //Init rest client
            var client = new RestClient($"{_settings.TMDBhost}/discover/movie/");
            
            //Init rest request
            var request = new RestRequest(Method.GET);
            request.RequestFormat = DataFormat.Json;
            
            //Add Request params
            request.AddParameter("api_key", _settings.ApiKey, ParameterType.GetOrPost);
            request.AddParameter("sort_by", sort, ParameterType.GetOrPost);
            
            //Calling Api 
            var response = client.Get(request);
            
            var movies = JsonSerializer.Deserialize<Movies>(response.Content);
            
            return movies;
        }
        
        public record Movie(int id, string original_title, string poster_path);
        public record Movies(int page, Movie[] results);
    }
}

GetById() 工作正常,但 Discover() 会抛出错误。在调试时我发现返回的值是 text/html 而不是 json;我认为这就是问题所在。

这里是错误

Exception has occurred: CLR/System.Text.Json.JsonException

An exception of type 'System.Text.Json.JsonException' occurred in System.Text.Json.dll but was not handled in user code: 'The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.'

Inner exceptions found, see $exception in variables window for more details.

Innermost exception
System.Text.Json.JsonReaderException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. LineNumber: 0 | BytePositionInLine: 0.

at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan1 bytes) at System.Text.Json.Utf8JsonReader.Read() at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state))

我是 .NET 的新手,所以我不知道如何修复它。提前致谢。

它 returns HTTP 301 已永久移动。也许您应该遵循该移动响应并访问不同的 URL。从 location header as defined in RFC2616.

获取

您的代码缺少错误处理。它可能应该只在 HTTP 200 OK 的情况下处理响应。从 HTTP 401 Forbidden 解析 JSON 可能也没有意义。

您可以尝试一些事情...

  1. 确保您使用的 URL 是正确的,例如,删除尾部斜杠。
  2. object :Movies 的返回值真的是 json 吗?还是 List<Movie>?即,object 的 { json } 与 object 列表的 [json]
  3. 您希望 'Accept' header 成为 'application/json' 而不是内容类型,但由于您的 GET 示例有效,我真的认为它是 #1 或 #2 .

试试这个:

        public Movies Discover(string sort)
        {
            //Init rest client
            var client = new RestClient($"{_settings.TMDBhost}/discover/movie"); // no trailing slash
            
            //Init rest request
            var request = new RestRequest(Method.GET);
            //request.RequestFormat = DataFormat.Json; // not required
            
            //Add Request params
            request.AddParameter("api_key", _settings.ApiKey, ParameterType.GetOrPost);
            request.AddParameter("sort_by", sort, ParameterType.GetOrPost);
            
            //Calling Api - can deserialize directly to your Movies var.
            var movies = client.GetAsync<Movies>(request).Result;
            // #2 - might be a list that you get back? if so .. something like this:
            // var mlist = client.GetAsync<List<Movie>>(request).Result;
            // var movies = new Movies(); // add your mlist as needed to movies.                        
            return movies;
        }

您也可以尝试在 Postman 中测试 .../movie 端点以查看实际返回的内容。