Внедрение Blazor HttpClient в конструктор ViewModel - PullRequest
0 голосов
/ 23 мая 2019

Я слежу за ссылками на указанный ниже блог / статью и не могу внедрить HttpClient в свою ViewModel.Он отлично работает по умолчанию (@inject в файле бритвы).Но вместо этого я пытаюсь внедрить его в ViewModel.

Если я добавлю к службам, как показано ниже, то внедрение по умолчанию не будет работать для других видов бритвы, которые имеют @inject HttpClient.

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

Вопрос:

Как я могу добавить встроенный HttpClient по умолчанию в мои различные модели ViewMels?

Обратите внимание, что я получаю исключение:

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) <0x2ebc4f0 + 0x00068> в <8f8c03446dbf45f5bbcb1e109a064f6e>: 0 WASM: в SimpleJson.SimpleJson.DeserializeObject [Т] (System.String JSON) <0x2ef2490 + 0x0000a> в <8f8c03446dbf45f5bbcb1e109a064f6e>: 0 WASM:
в Microsoft.JSInterop.Json.Deserialize [T] (System.String json) <0x2ef2458 + 0x00004> в <8f8c03446dbf45f5bbcb1e109a064f6e>: 0 WASM:
в Microsoft.AspNetCex.Ceff.Ceff.Ceff.Ceff.Ceff.Ceff.Ceff.Ceff.Ceff.Ceff.Ce.System.Net.Http.HttpClient httpClient, System.String requestUri) <0x33182e0 + 0x000fa> в <13ab8f8dacb6489b93c9655168c56037>: 0 WASM:
в WebUI.Features.Fetch.

Обновлено 2

Так что теперь я могу подтвердить, что я был кораподнимать не то дерево .По сути, у меня была проблема десериализации.Как только я решил эту проблему, все работает нормально.Не уверен, если у меня была проблема DI с самого начала или нет.Тем не менее, моя проблема решена сейчас.Спасибо за все просвещающие перспективы.

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

Это не совсем ответ на ваш вопрос;без полного отображения вашего кода, ответ не представляется возможным.Но позвольте мне обратиться к следующему фрагменту кода;возможно, проблема заключается в следующем:

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

Сервис HttpClient предоставляется в виде Singleton (CSB) средой Blazor.Таким образом, вы не можете внедрить HttpClient в сервис, который вы добавляете в свое приложение как Transient.Ваш сервис также должен быть добавлен как Singleton ...

Надеюсь, это поможет ...

[Изменить]

How can i inject the default injected HttpClient 
to my various ViewModels?
  • Если ваши ViewModels являются Компонентами,вы можете использовать директиву @inject следующим образом:

@ inject HttpClient httpClient

  • Если ваши ViewModels - это обычные классы (.cs), вы можете передать ссылку наобъект HttpClient из методов вызывающего компонента или внедрить службу HttpClient в конструкторы ViewModels.Не забудьте добавить ваши Services или ViewModels в класс Startup: services.AddSingleton<IFetchViewModel, FetchViewModel>();

Еще раз, используйте AddSingleton

Нет, ваша проблема получилане имеет ничего общего с проблемой 225. Эта проблема очень старая, и все ошибки, упомянутые в этой проблеме, были исправлены задолго до того, как я услышал о Blazor ...

Примечание: трассировка стека исключений ясно указывает нав направлении HttpClient, являющегося виновником.Сделайте то, что я предложил выше, и скажите нам, если проблема все еще сохраняется.

Почему бы вам не показать свой код, как вас просят другие.Пожалуйста, обратитесь к инструкции о том, как задать вопрос в переполнении стека.

0 голосов
/ 23 мая 2019

Шаблон прост.

Я получил это так, начиная со стандартного стартового шаблона.
В 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>();
}

В общем, это не должен быть синглтон.

...