【问题标题】:Blazor HttpClient injection into a ViewModel constructorBlazor HttpClient 注入 ViewModel 构造函数
【发布时间】:2019-10-09 15:44:14
【问题描述】:

我正在关注下面引用的博客/文章,但我无法将 HttpClient 注入我的 ViewModel。它以默认方式工作正常(剃刀文件中的@inject)。但我正在尝试注入 ViewModel。

如果我像下面这样添加到服务中,则默认注入不适用于具有@inject HttpClient 的其他剃须刀视图。

// manually add HttpClient to services.
services.AddTransient<IFetchViewModel, FetchViewModel>();

问题:

如何将默认注入的 HttpClient 注入到我的各种 视图模型?

请注意,我遇到了一个异常:

WASM: Unhandled exception rendering component:
WASM: System.Reflection.TargetParameterCountException: Number of parameters specified does not match the expected number.

参考:

https://itnext.io/a-simple-mvvm-implementation-in-client-side-blazor-8c875c365435

更新

在做出建议的更改并在期间深入挖掘之后 调试,我可以看到json有问题 反序列化。这可能是一个问题吗? https://github.com/aspnet/Blazor/issues/225

请注意,在异常堆栈跟踪的更深处,我看到以下内容:

WASM:在 SimpleJson.SimpleJson.DeserializeObject (System.String json,System.Type 类型,SimpleJson.IJsonSerializerStrategy jsonSerializerStrategy) 在 :0 WASM:在 SimpleJson.SimpleJson.DeserializeObject[T] (System.String json) 在 :0 WASM:
在 Microsoft.JSInterop.Json.Deserialize[T] (System.String json) 在 :0 WASM:
在 Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync[T] (System.Net.Http.HttpClient httpClient, System.String requestUri) 在 :0 WASM:
在 WebUI.Features.Fetch.FetchViewModel.LoadAsync () 在 :0

更新 2

所以我现在可以确认我是barking up the wrong tree。 本质上,我有一个反序列化问题。一旦我解决了这个问题,一切正常。不确定我是否从一开始就有 DI 问题。尽管如此,我的问题现在解决了。感谢所有启发性的观点。

【问题讨论】:

  • 按照Louis在文章中解释的方式进行是否有效?
  • 文章没有明确提到如何通过构造函数传入 HttpClient。他刚刚提到没有其他提及它,因为它被注入了。
  • 当然可以,但它在标题为“添加模型”部分的 FetchDataModel 构造函数中,而不是在视图模型中。
  • 使用接口添加服务,以便DI可以通过接口解析请求,否则你绑定到直接引用你的具体类,这不是很好
  • 我真的建议您坚持博客中代码的结构方式,并在尝试调整之前尝试理解它。如果您需要有关特定代码的帮助,请在您的问题中添加一个完整的示例,以便我们查看您有什么。目前我们只能看到错误。

标签: asp.net-core razor dependency-injection razor-pages blazor


【解决方案1】:

这不是您问题的真正答案;如果没有完整显示您的代码,就没有真正的答案是可能的。但是让我涉及到下面的代码sn-p;也许问题出在那儿:

// manually add HttpClient to services.
services.AddTransient<IFetchViewModel, FetchViewModel>(); 

HttpClient 服务由 Blazor 框架作为单例 (CSB) 提供。因此,您不能将 HttpClient 注入到您作为瞬态添加到应用程序中的服务中。您的服务也应该添加为 Singleton...

希望这会有所帮助...

[编辑]

How can i inject the default injected HttpClient 
to my various ViewModels?
  • 如果您的 ViewModel 是组件,您可以像这样使用 @inject 指令:

@inject HttpClient httpClient

  • 如果您的 ViewModel 是普通类 (.cs),您可以 要么从调用组件方法传递对 HttpClient 对象的引用,要么将 HttpClient 服务注入到 ViewModel 的构造函数中。不要忘记在 Startup 类中添加您的服务或视图模型: services.AddSingleton<IFetchViewModel, FetchViewModel>();

再次使用 AddSingleton

不,您的问题与问题 225 无关。 这个 issue 很老了,而且这个 issue 中提到的所有 bug 早在我听说 Blazor 之前就已经修复了……

注意:异常堆栈跟踪清楚地指出 HttpClient 是罪魁祸首。执行我上面的建议,并告诉我们问题是否仍然存在。

您为什么不按照其他人的要求显示您的代码。请查找有关如何在堆栈溢出中提问的说明。

【讨论】:

    【解决方案2】:

    模式很简单。

    我从标准的入门模板开始就是这样工作的。
    在 FetchData.razor 中:

    @page "/fetchdata"
    @using ClientBlazor1.ViewModels
    @inject FetchDataViewModel vm
    
    ... the html
    
    protected override async Task OnInitAsync()
    {
        forecasts = await vm.GetForecasts();
    }
    

    ViewModel 在下面。您似乎在这里缺少构造函数(-injection)部分。
    使用接口是可选的,我没有。

    public class FetchDataViewModel
    {
        private HttpClient _httpClient;
    
        public FetchDataViewModel(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }
    
        public async Task<WeatherForecast[]> GetForecasts()
        {
            return await _httpClient.GetJsonAsync<WeatherForecast[]>("sample-data/weather.json");
        }
    }
    

    最后,Startup.cs 中的注册部分:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<FetchDataViewModel>();
    }
    

    一般来说,这不应该是单例。

    【讨论】:

      猜你喜欢
      • 2017-07-31
      • 2020-11-09
      • 1970-01-01
      • 2021-12-23
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      相关资源
      最近更新 更多