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

获取用户投资组合时遇Newtonsoft.Json序列化异常求助

问题:获取投资组合数据时API序列化报错

我有Stocks表、AppUsers表,以及作为两者多对多关联表的Portfolios表。尝试获取投资组合数据时API报错,错误信息如下:

Newtonsoft.Json.JsonSerializationException: Error getting value from 'Context' on 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.Collections.Generic.List`1[api.Models.Stock],API.Repositories.Concrete.PortfolioRepository+<GetUserPortfolio>d__2]'.
 ---&gt; System.InvalidOperationException: Could not create getter for System.Threading.ExecutionContext&amp; Context. ByRef return values are not supported.
   at Newtonsoft.Json.Utilities.ReflectionDelegateFactory.CreateGet[T](MemberInfo memberInfo)
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract&amp; memberContract, Object&amp; memberValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
   at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State&amp; next, Scope&amp; scope, Object&amp; state, Boolean&amp; isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

控制器代码

[HttpGet]
[Authorize]
public async Task<IActionResult> GetUserPortfolio()
{
    var username = User.GetUsername();
    var appUser = await userManager.FindByNameAsync(username);
    var userPortfolio = portfolioReposiotry.GetUserPortfolio(appUser);
    return Ok(userPortfolio);
}

仓储代码

public class PortfolioRepository : IPortfolioRepository
{
    private readonly AppDbContext context;

    public PortfolioRepository(AppDbContext context)
    {
        this.context = context;
    }

    public async Task<List<Stock>> GetUserPortfolio(AppUser user)
    {
        var val = context.Portfolios.Where(u => u.AppUserId == user.Id)
            .Select(stock => new Stock
            {
                Id = stock.StockId,
                Symbol = stock.Stock.Symbol,
                CompanyName = stock.Stock.CompanyName,
                Purchase = stock.Stock.Purchase,
                LastDiv = stock.Stock.LastDiv,
                Industry = stock.Stock.Industry,
                MarketCap = stock.Stock.MarketCap
            });
        return await val.ToListAsync();
    }
}

解决方案

问题核心是控制器中调用异步仓储方法时未使用await。GetUserPortfolio返回的是Task<List<Stock>>,直接将这个Task对象传给Ok()方法会导致Newtonsoft.Json尝试序列化Task的内部状态(包括AsyncStateMachineBox中的Context成员),而Task内部的某些ByRef类型成员无法被序列化,从而抛出错误。

修改控制器代码,给仓储方法调用加上await:

[HttpGet]
[Authorize]
public async Task<IActionResult> GetUserPortfolio()
{
    var username = User.GetUsername();
    var appUser = await userManager.FindByNameAsync(username);
    var userPortfolio = await portfolioReposiotry.GetUserPortfolio(appUser); // 添加await
    return Ok(userPortfolio);
}

加上await后,代码会等待异步任务完成,获取到实际的List<Stock>数据,再返回给序列化器,就能正常完成JSON序列化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:28:20