5

我正在尝试在示例应用程序中实现一个小杂物。

我在应用程序中使用 blazor,但发现服务器调用存在一些问题。

我创建了一个简单的 API 控制器,名称为 Employee 和带有 HTTP 动词的方法。

 [ApiController]
    [Route("[controller]")]
    public class EmployeeController : ControllerBase
    {
        EmployeeRepository objemployee = new EmployeeRepository();   
        [HttpGet]
        [Route("api/Employee/Index")]
        public IEnumerable<Employee> Index()
        {
            return objemployee.GetAllEmployees();
        }
   }  

empList = await Http.GetJsonAsync<Employee[]>("/api/Employee/Index"); 

line 报告了一个问题,我不知道,因为我是 blazor 的新手。我应该在我的代码中做什么?

用asp构建的应用程序。Net core 3.0”、“blazor 预览版 9”。

输出:我尝试按照指南查找示例实现,但无法解决问题。

我收到以下异常:

  WASM: Unhandled exception rendering component:
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM: 
    System.Text.Json.JsonException: 
    '<' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0. ---> 
    System.Text.Json.JsonReaderException: '<' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
d.printErr @ blazor.webassembly.js:1
    blazor.webassembly.js:1 WASM:   at.    System.Text.Json.ThrowHelper.ThrowJsonReaderException (System.Text.Json.Utf8JsonReader& json, System.Text.Json.ExceptionResource resource, System.Byte nextByte, System.ReadOnlySpan`1[T] bytes) <0x2398fc8 + 0x00020> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.Utf8JsonReader.ConsumeValue (System.Byte marker) <0x1fa7718 + 0x0028e> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.Utf8JsonReader.ReadFirstToken (System.Byte first) <0x1fa6d60 + 0x001ec> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.Utf8JsonReader.ReadSingleSegment () <0x1fa6618 + 0x00234> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.Utf8JsonReader.Read () <0x1fa61d0 + 0x00012> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x1fa5b40 + 0x00062> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:    --- End of inner exception stack trace ---
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.ThrowHelper.ReThrowWithPath (System.Text.Json.ReadStack& readStack, System.Text.Json.JsonReaderException ex) <0x23e6bc8 + 0x00116> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x1fa5b40 + 0x002a8> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.JsonSerializer.ReadCore (System.Type returnType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader) <0x1fa4e70 + 0x0003e> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.JsonSerializer.ParseCore (System.String json, System.Type returnType, System.Text.Json.JsonSerializerOptions options) <0x1fa1698 + 0x00086> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at System.Text.Json.JsonSerializer.Deserialize[TValue] (System.String json, System.Text.Json.JsonSerializerOptions options) <0x2398808 + 0x00022> in <81e9245ca982431695a55cc67ffb3b86>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync[T] (System.Net.Http.HttpClient httpClient, System.String requestUri) <0x2270e18 + 0x000fa> in <900d091618e14952821fd2fc9b26598c>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at EMS.Client.Pages.FetchEmployee.OnInitializedAsync () [0x0002a] in C:\ES\Client\Pages\FetchEmployee.razor:51 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x1f4ed10 + 0x00176> in <cc81133ac6304aada69282c517e2b811>:0 
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM:   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x224b4e8 + 0x000f4> in <cc81133ac6304aada69282c517e2b811>:0 
 `
4

5 回答 5

6

我认为这不是 Blazor 问题,我假设您使用的是 Blazor WebAssembly 托管模板?

如果您尝试通过在浏览器中导航到 API 端点来加载它,您会看到什么?我猜是 404 not found 还是 500 错误?

我认为问题在于您如何在 API 控制器上定义路由。尝试以下设置。

[ApiController]
[Route("[controller]")]
public class EmployeeController : ControllerBase
{
    EmployeeRepository objemployee = new EmployeeRepository();  

    [HttpGet]
    public IEnumerable<Employee> Index()
    {
        return objemployee.GetAllEmployees().ToArray();
    }

}

然后打个电话employees = await Http.GetJsonAsync<Employee[]>("Employee");,如果一切顺利,你应该把你的员工名单拿回来。

于 2019-10-13T16:18:53.937 回答
3

我猜这个问题与您返回 Html 而不是 JSON 的 Web Api 有关。GetJsonAsync 方法运行良好,JSON 解析器也运行良好。也许员工模型是错误的......

尝试使用这个:

[ApiController]
public class EmployeeController: ControllerBase
{
   EmployeeRepository objemployee = new EmployeeRepository();   
        [HttpGet("/")]
        public IEnumerable<Employee> Index()
        {
            return objemployee.GetAllEmployees();
        }

}

并像这样调用 Web Api:

empList = await Http.GetJsonAsync<Employee[]>("api/Employee"); 

请注意删除 url 中的前导“/”。这可能是问题的根源。

  • 在代码中使用异步编程可能是个好主意
  • 注入总是比在您的应用程序中创建对象更好,例如 EmployeeRepository
于 2019-10-13T12:39:34.340 回答
2

看起来您正在请求错误的 API 点。只需检查您的终点是返回 json 而不是 html:打开 navigator 并 go http://localhost:5000/api/Employee/Index

查看您的代码,我建议您更改:

Route("[controller]"...

经过:

Route("/api/[controller]"...
于 2019-10-13T12:40:13.013 回答
0

解决方案是将所有 Nuget 包更新到 5.0.4。此外,请确保将 Visual Studio 2019 更新到最新版本。此外,您必须确保您的证书有效,即自签名 PFX。您不必使用dot-net dev-certs,但您需要一个为 HTTPS 正确注册的证书才能运行。这是一个在 Web 和 YouTube 上有详细记录的程序。此外,您可能希望将日志记录代码添加到相关的服务器端位置,以便查看发生了什么。

下面显示的是来自控制台的 Kestrel HTTPS 启动,作为我的输出功能的证据。学习很好也很有趣——赞美耶稣!

服务器端代码现在可见并且断点正在工作。在我将所有附加的 Nuget 包更新到 5.0.4 之后,这一切都在 2021 年 3 月 25 日星期二开始工作。请参阅创建脚本的最底部。

您还将看到各种Console.Writeline指令的输出,注释为“First Hit”、“Second Hit”等。这些是查看最新情况的方法。日志技术也开始发挥作用,但您需要学习如何附加它并自己输出。

..\dotnet watch --verbose run -c Debug
watch : Evaluating dotnet-watch file set.
watch : Running MSBuild target 'GenerateWatchList' on 'C:\Beachgoo.Authority\Server\Authority.Server.csproj'
watch : Started 'C:\Program Files\dotnet\dotnet.exe' 'msbuild /nologo C:\Beachgoo.Authority\Server\Authority.Server.csproj /p:_DotNetWatchListFile=D:\Global_TMP\h4f00m3z.2oq /nologo /v:n /t:GenerateWatchList /p:DotNetWatchBuild=true /p:DesignTimeBuild=true "/p:CustomAfterMicrosoftCommonTargets=C:\Program Files\dotnet\sdk\5.0.201\DotnetTools\dotnet-watch\5.0.201-servicing.21123.24\tools\net5.0\any\DotNetWatch.targets" "/p:CustomAfterMicrosoftCommonCrossTargetingTargets=C:\Program Files\dotnet\sdk\5.0.201\DotnetTools\dotnet-watch\5.0.201-servicing.21123.24\tools\net5.0\any\DotNetWatch.targets"' with process id 10188
watch : Process id 10188 ran for 3629ms
watch : Watching 39 file(s) for changes
watch : Watch command can be configured to use --no-restore.
watch : No restore arguments: run --no-restore -c Debug
watch : dotnet-watch is configured to launch a browser on ASP.NET Core application startup.
watch : Refresh server running at ws://127.0.0.1:23993.
watch : Started 'C:\Program Files\dotnet\dotnet.exe' 'run -c Debug' with process id 9768
watch : Running dotnet with the following arguments: run -c Debug
watch : Started
Building...
First hit: now in Server Program.Main() method of Program.cs
Second hit: IPAddress.Parse
Third hit: now in ConfigureKestrel() => listopt lambda
Certificate Path is: /wwwroot/<yourssc>.pfx, <yourpassword>
Fourth Hit: Added WebAssemblyDebugging in development should be: True
Fifth Hit: Inside the UseEndoints Lambda in Startup.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://192.168.2.3:5000
watch : Launching browser.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://192.168.2.3:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Beachgoo.Authority\Server
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside constructor for ApiController ResortQualitiesController. This type is: Authority.Server.Controllers.ResortQualitiesController
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside HTTP Get(), on server side Kestrel.
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside constructor for ApiController ResortQualitiesController. This type is: Authority.Server.Controllers.ResortQualitiesController
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside HTTP Get(), on server side Kestrel.
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside constructor for ApiController ResortQualitiesController. This type is: Authority.Server.Controllers.ResortQualitiesController
trce: Authority.Server.Controllers.ResortQualitiesController[0]
      Inside HTTP Get(), on server side Kestrel.

我的创作脚本在这里。我也在坚持不懈地玩,但你可以从头开始。

@ECHO OFF
@CLS
@REM Rename / create the word <Trial> as you need.
@REM C:\Trial.bat
@ECHO -------------------------
@ECHO  Trial System Build
@ECHO -------------------------
@ECHO.
C:
CD C:\
@ECHO ------Build WASM---------
dotnet new blazorwasm -lang "C#" -o <your.folder.<Trial> -n <Trial> -f net5.0 -ho -p
@ECHO ----Create Persistence----
cd C:\<yourfolder.<Trial>
dotnet new classlib -lang "C#" -n Persistent -f net5.0
dotnet add .\Persistent\Persistent.csproj package Microsoft.EntityFrameworkCore --version 5.0.4
dotnet add .\Persistent\Persistent.csproj package Microsoft.AspNetCore.Identity.UI --version 5.0.4
dotnet add .\Persistent\Persistent.csproj package Microsoft.Extensions.Configuration --version 5.0.0
dotnet add .\Persistent\Persistent.csproj package Microsoft.EntityFrameworkCore.Tools --version 5.0.4
dotnet add .\Persistent\Persistent.csproj package Microsoft.EntityFrameworkCore.SqlServer --version 5.0.4
dotnet add .\Persistent\Persistent.csproj package Microsoft.AspNetCore.Identity.EntityFrameworkCore --version 5.0.4
dotnet add .\Persistent\Persistent.csproj package Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore --version 5.0.4
@ECHO.
@ECHO -----Combine Projects-----
dotnet sln <Trial>.sln add .\Persistent\Persistent.csproj
@ECHO.
CD \
@ECHO.
@ECHO Done! Completed <Trial> Solution Build.
于 2021-03-25T12:23:32.790 回答
0

我有错误

System.Text.Json.JsonReaderException:“<”是一个无效的值开始

在我对控制器方法的返回类型进行了有效的代码更改后,发生了几次,只是为了似乎没有理由停止发生错误,即使没有进行进一步的代码更改。

我猜测会发生某种缓存,一段时间以来,Blazor WASM 客户端正在寻找一个控制器端点,该端点现在需要不同的参数或返回不同的对象类型。

我尝试重新启动 VS,删除 obj、bin 和 .vs 文件等,但没有帮助,所以我猜这可能是 Chrome 缓存问题,或者 Blazor WebAssembly 创建的调试电路上的某种缓存。

因此,如果您进行这些检查:

  • 您的控制器上的路由属性是否与requestUri客户端中使用的匹配?因此,例如,如果您的路线是,[Route("api/[controller]")]那么您使用的 requestUri 也需要包含api\在其中
  • 控制器的名称(减去“控制器”)是否与requestUri您在客户端中调用的名称匹配?
  • 如果您正在使用,控制器方法的返回类型是否与您要反序列化的内容相匹配Http.GetFromJsonAsync<YourType>

一切都如预期的那样,那么在花太多时间追逐可能是幻像错误之前,可能值得终止 Chrome 的进程,甚至重新启动您的 PC 以查看是否清除了异常。

于 2021-02-04T11:04:40.137 回答