为什么这个 Blazor WebAssembly api Get 函数不起作用?

Why doesn't this Blazor WebAssembly api Get function work?

我有一个 Blazor WASM 应用程序,我正在修改模板 weatherforecastcontroller 以添加一个 Get,我可以在其中传递一个 id:

        [HttpGet("{userId}")]

        public string Get(string userId)
        {
            return userId;
        }

在调用它的组件上:

    protected override async Task OnInitializedAsync()
    {   
            var id = await Http.GetFromJsonAsync<WeatherForecast>("WeatherForecast/1);        
    }

但抛出错误:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: The provided ContentType is not supported; the supported types are 'application/json' and the structured syntax suffix 'application/+json'.
System.NotSupportedException: The provided ContentType is not supported; the supported types are 'application/json' and the structured syntax suffix 'application/+json'.
  at System.Net.Http.Json.HttpContentJsonExtensions.ValidateContent (System.Net.Http.HttpContent content) <0x2f6ff90 + 0x0009a> in <filename unknown>:0 

怎么了?如果我手动输入地址栏:

http://localhost:59728/weatherforecast/1

...我得到了我期望的 ID。

这个:

Http.GetFromJsonAsync<WeatherForecast>

应该是 Http.GetFromJsonAsync<string>

换句话说,指示 json 序列化器从 HTTP 调用中期望什么类型的类型说明符是字符串,而不是 class、WeatherForecast

更新:

@page "/"
@inject HttpClient Http


<h1>@output</h1>

@code
{
    private string output;

    protected override async Task OnInitializedAsync()
    {
        var val = "1";
        output = await Http.GetFromJsonAsync<string>($"WeatherForecast?value={val}");

    }
}

WeatherForecastController.cs

[HttpGet]
        public string Get(string value)
        {

            return value;
        }

Startup.ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllersWithViews(options =>
            {
               options.OutputFormatters.RemoveType<StringOutputFormatter>();
            });
            services.AddRazorPages();
        }

注意:也可以添加Produces属性来指定响应类型格式,像这样:

    [HttpGet]
    [Produces("application/json")]
    public string Get(string value)
    {

        return value;
    }

你也应该改变

services.AddControllersWithViews(options =>
                {
                   options.OutputFormatters.RemoveType<StringOutputFormatter>();
                });

services.AddControllersWithViews();

你说直接调用API就可以了,但是返回的是1还是"1"?这很重要,因为只有后者有效 JSON。由于您要求 JSON (GetFromJsonAsync),因此原始值 1 会导致问题。作为 the docs state:

By default, string return types are formatted as text/plain

您可以查看文档以了解可能的解决方案。这是一个片段:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // Removes the special case for strings
    options.OutputFormatters.RemoveType<StringOutputFormatter>();
});

其他选项包括手动返回 HttpResponseMessage 以及在 StringContent.

的实例中指定的字符串值

注意:enet也是对的,需要把WeatherForecast改成string

除了@enet 建议的修复之外,您的控制器也存在问题。当您 return 一个 string 时,Content-Type 被设置为 text/plain 并且您的 HTTP 客户端期望 JSON。这是一个例子:

    [HttpGet("text")]
    public string GetText()
    {
        return "Hello, this is text/plain";
    }


    [HttpGet("maybe-json")]
    public ActionResult<string> GetMaybeJson()
    {
        return Ok("Hello, this is still text/plain.");
    }

    // ** THIS SHOULD WORK ** 
    [HttpGet("json")]
    public ActionResult<string> GetJson()
    {
        return new JsonResult("Hello, this is application/json");
    }

同样,如果您使用端点 returning WeatherForecast 进行了测试,那么 Content-Type 将是 application/json 并且您的 Blazor 代码将起作用。您应该能够在您的控制器中尝试 GetJson() 并查看您的代码工作。