You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps部署ASP.NET Core 6 MVC+MudBlazor应用登录异常排查

环境配置

我拥有一个包含多个Azure Functions微服务、若干共享项目,以及一个集成MudBlazor的ASP.NET Core 6 MVC Web应用的解决方案。

问题现象

通过Visual Studio 2022单独部署所有组件时,一切运行正常。但使用Azure DevOps发布流水线部署后,Azure Functions部署正常,Web应用可正常启动,然而尝试登录时出现以下异常:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]

Unhandled exception rendering component: ExpectedStartOfValueNotFound, < Path: $ | LineNumber: 0 | BytePositionInLine: 0.

System.Text.Json.JsonException: ExpectedStartOfValueNotFound, < Path: $ | LineNumber: 0 | BytePositionInLine: 0.

---> System.Text.Json.JsonReaderException: ExpectedStartOfValueNotFound, < LineNumber: 0 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& , ExceptionResource , Byte , ReadOnlySpan1 ) at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte ) at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte ) at System.Text.Json.Utf8JsonReader.ReadSingleSegment() at System.Text.Json.Utf8JsonReader.Read() at System.Text.Json.Serialization.JsonConverter1[[MyProject.Platform.Shared.Wrapper.Result`1[[MyProject.Platform.Application.Features.Accounts.Queries.GetById.GetProjectByIdResponse, PublicKeyToken=null]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) Exception_EndOfInnerExceptionStack at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& , JsonReaderException ) at System.Text.Json.Serialization.JsonConverter`1[[MyProject.Platform.Shared.Wrapper.Result`1[[MyProject.Platform.Application.Features.Accounts.Queries.GetById.GetProjectByIdResponse,
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task , ComponentState )

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Unexpected character encountered while parsing value: T. Path '', line 0, position 0.
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: T. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[Object](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[Object](String value)
   at 
   at Toolbelt.Blazor.HttpClientInterceptor.InvokeAsync(HttpClientInterceptorEventHandler asyncEventHandler, HttpClientInterceptorEventArgs args)
   at Toolbelt.Blazor.HttpClientInterceptor.InvokeAfterSendAsync(HttpClientInterceptorEventArgs args)
   at Toolbelt.Blazor.HttpClientInterceptorHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage , HttpCompletionOption , CancellationTokenSource , Boolean , CancellationTokenSource , CancellationToken )
   at 
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task , ComponentState )

 Failed to load resource: the server responded with a status of 405 (Method Not Allowed)

同时还返回了405(Method Not Allowed)状态码错误。

部署流水线YAML

以下是我使用的Azure DevOps流水线YAML配置:

trigger:
- development
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Debug'
  publishPath: '$(Build.ArtifactStagingDirectory)/publish'

stages:

- stage: BuildApp
  displayName: Build Apps
  jobs:
  - job: BuildApp
    displayName: Build App
    steps:
    - task: DotNetCoreInstaller@2
      displayName: 'Install .NET 6 SDK'
      inputs:
        version: '6.x'

    - task: DotNetCoreInstaller@2
      displayName: 'Install .NET 7 SDK'
      inputs:
        version: '7.x'

    - task: DotNetCoreCLI@2
      displayName: 'Install WebAssembly tools for .NET 6'
      inputs:
        command: 'custom'
        custom: 'workload'
        arguments: 'install wasm-tools-net6'
        workingDirectory: '$(Agent.ToolsDirectory)/dotnet'
    - task: DotNetCoreInstaller@2
      displayName: 'Install .NET 3 SDK'
      inputs:
        version: '3.x'
    - task: NuGetToolInstaller@1
      inputs:
        versionSpec: '6.5'

    - task: NuGetCommand@2
      inputs:
        command: 'restore'
        restoreSolution: '$(System.DefaultWorkingDirectory)/WebApp/MyProject.Platform.sln'
        feedsToUse: 'config'
        nugetConfigPath: '$(System.DefaultWorkingDirectory)/nuget.config'
        arguments: '-Parallel'
    - task: MSBuild@1
      displayName: 'BUILD!!'
      inputs:
        solution: '$(System.DefaultWorkingDirectory)/WebApp/MyProject.Platform.sln'
        msbuildArchitecture: 'x64'
        platform: 'any cpu'
        configuration: $(buildConfiguration)
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        projects: '$(System.DefaultWorkingDirectory)/WebApp/MyProject.Platform.WebApp/Server/MyProject.Platform.Server.csproj'
        arguments: '--configuration Debug --output $(Build.ArtifactStagingDirectory)'
    - task: DotNetCoreCLI@2
      displayName: 'Publish'
      inputs:
        command: 'publish'
        publishWebProjects: True
        projects: '$(System.DefaultWorkingDirectory)/WebApp/MyProject.Platform.WebApp/Server/MyProject.Platform.Server.csproj'
        arguments: '--configuration Debug --output $(Build.ArtifactStagingDirectory)'
        zipAfterPublish: true
    - task: CopyFiles@2
      inputs:
        targetFolder: '$(Build.ArtifactStagingDirectory)'

    - task: PublishBuildArtifacts@1    
      displayName: 'Publish Artifact: drop'
问题咨询

请问我在部署流程中存在哪些错误操作,导致了上述问题?


问题分析与解决建议

1. 重复构建/发布引发文件冲突

流水线中连续执行了MSBuild、dotnet build和dotnet publish三个构建/发布步骤,会导致$(Build.ArtifactStagingDirectory)目录下的文件被多次覆盖,可能丢失WebAssembly客户端静态资源或后端API路由配置文件,进而引发API请求的405错误和JSON解析失败。

正确做法是只保留dotnet publish步骤,因为publish命令会自动完成restore、build和打包的完整流程,无需额外执行build或MSBuild。

2. Debug配置部署的潜在问题

流水线使用Debug配置发布,而Visual Studio部署通常默认用Release配置。Debug配置下可能包含调试钩子、未优化代码,甚至部分API路由行为与Release模式不同,也可能引发CORS或路由匹配问题。建议将buildConfiguration变量改为Release。

3. 冗余SDK安装导致版本混淆

项目基于ASP.NET Core 6,无需安装.NET 3和.NET 7 SDK,多余的SDK可能导致构建时使用错误的.NET版本,引发兼容性问题。应移除.NET 3和.NET 7的安装步骤,只保留.NET 6 SDK和对应的wasm-tools-net6 workload。

4. 无效的CopyFiles步骤

当前CopyFiles步骤未指定源文件路径,相当于没有执行任何操作,应直接删除该步骤,避免流程混淆。

修正后的流水线核心步骤示例

variables:
  buildConfiguration: 'Release' # 改为Release配置

stages:
- stage: BuildApp
  displayName: Build Apps
  jobs:
  - job: BuildApp
    displayName: Build App
    steps:
    - task: DotNetCoreInstaller@2
      displayName: 'Install .NET 6 SDK'
      inputs:
        version: '6.x'

    - task: DotNetCoreCLI@2
      displayName: 'Install WebAssembly tools for .NET 6'
      inputs:
        command: 'custom'
        custom: 'workload'
        arguments: 'install wasm-tools-net6'
        workingDirectory: '$(Agent.ToolsDirectory)/dotnet'

    - task: NuGetToolInstaller@1
      inputs:
        versionSpec: '6.5'

    - task: DotNetCoreCLI@2
      displayName: 'Publish Web App'
      inputs:
        command: 'publish'
        projects: '$(System.DefaultWorkingDirectory)/WebApp/MyProject.Platform.WebApp/Server/MyProject.Platform.Server.csproj'
        arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
        zipAfterPublish: true

    - task: PublishBuildArtifacts@1    
      displayName: 'Publish Artifact: drop'

额外排查点

  • 检查Web应用的API路由配置,确认登录接口的HTTP方法(POST/GET)是否与前端请求一致,405错误通常是请求方法不匹配导致的。
  • 确认Azure App Service的启动命令是否正确,避免因启动参数错误导致后端API未正常加载。

内容的提问来源于stack exchange,提问作者mkr231

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:20:03