Blazor项目中如何调用服务方法?自定义TmdbService调用异常排查
问题核心原因
你的GetAllMovieInfo服务方法存在逻辑漏洞:
- 方法内部实例化的
MovieDataDetail是仅在方法域内有效的临时对象,赋值完成后既没有作为返回值传出,也没有存储到外部可访问的作用域,方法执行结束后该临时对象会被垃圾回收。Blazor页面中持有的detail仍然是初始化时的空对象,所有属性均为默认值,自然无法正常渲染,甚至会触发空引用报错。 - 控制台项目运行正常是因为你的控制台测试逻辑中大概率直接持有了该局部对象的引用,没有跨作用域传递的问题,所以表现符合预期。
修复方案
1. 改造服务方法,返回处理后的电影数据
将无返回值的GetAllMovieInfo改为返回Task<MovieDataDetail>,直接传递处理好的对象给调用方,同时去掉无意义的循环,直接取第一条匹配结果:
public class TmdbService { private static JsonConfig _config = new JsonConfig(); private readonly TMDbClient _client = new TMDbClient(_config.Settings.TApiKey); public async Task<MovieDataDetail?> GetAllMovieInfo(string title, string lang = "ru") { SearchContainer<SearchMovie> results = await _client.SearchMovieAsync(title, lang); var firstMatch = results.Results.FirstOrDefault(); // 无匹配结果时返回空,避免空引用 if (firstMatch == null) return null; return new MovieDataDetail { Id = firstMatch.Id, Title = firstMatch.Title, OriginalTitle = firstMatch.OriginalTitle, ReleaseDate = firstMatch.ReleaseDate, Image = firstMatch.PosterPath, Popularity = firstMatch.Popularity, Overview = firstMatch.Overview }; } }
2. 改造Blazor页面代码
- 等待服务返回的数据,直接赋值给页面的
detail变量 - 改用Blazor原生依赖注入获取服务实例,避免手动实例化带来的生命周期问题
- 增加可空引用判断,适配无搜索结果的场景
@page "/counter" @using MovieApp.Shared.Services.TmdbApi @using MovieApp.Shared.Models.MovieData <div> <h1>电影名称:@detail?.OriginalTitle</h1> <h1>@title 简介:@detail?.Overview</h1> @*<h1>评分:@detail?.IMDbRating</h1>*@ </div> @code { [Inject] public TmdbService service { get; set; } MovieDataDetail? detail; string title = "lucy"; protected override async Task OnInitializedAsync() { // 接收服务返回的实例,直接赋值给页面变量 detail = await service.GetAllMovieInfo(title); } }
额外排查提示:
- 若使用Blazor WebAssembly(浏览器端托管)架构,直接调用第三方API会受浏览器同源策略限制,如控制台报跨域错误,需要通过后端API代理转发TMDB请求,或确认TMDB开放了对应跨域权限。
- 依赖注入需要在项目入口(
Program.cs)注册对应服务,否则会无法解析实例:builder.Services.AddScoped<TmdbService>();
内容的提问来源于stack exchange,提问作者SweetPony
相关产品推荐
相关产品推荐

