Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Razor Component Server Side : Inject HttpClient in service broke entire application #7851

Closed
julienGrd opened this issue Feb 22, 2019 · 8 comments

Comments

@julienGrd
Copy link

commented Feb 22, 2019

Describe the bug

When I try to inject HttpClient in a service, then inject the service in a page, it's broke the rendering (blank page, no error in browser console)

To Reproduce

1 : Create a Razor Components project, with .net core 3 preview and Visual studio 2019. It create normally two project *.App and *.Server
2 : launch application, everything is OK
3 : Update the WeatherForecastService to inject HttpClient in the constructor (in the App project)
public WeatherForecastService(HttpClient httpClient) { }
4 : Inject the service in the index.cshtml (in the App project)
@inject WeatherForecastService ForecastService
5 : launch the application. It's result in a blanck screen without errors

Expected behavior

an application wich works, or at least an exception on why it can't be possible

Additional context

I read the HttpClient is not natively registered in the server side razor. so i tried registred one in the startup.cs with this piece of code find somewhere. It's seem changing nothing
if (!services.Any(x => x.ServiceType == typeof(HttpClient))) { // Setup HttpClient for server side in a client side compatible fashion services.AddScoped<HttpClient>(s => { // Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it. var uriHelper = s.GetRequiredService<IUriHelper>(); return new HttpClient { BaseAddress = new Uri(uriHelper.GetBaseUri()) }; }); }

@sven5

This comment has been minimized.

Copy link

commented Feb 22, 2019

I cannot reproduce your error. Your code is running without issues on my side (Razor Components 0.8, .Net Core 3.0 Preview 2, VS 2019).

It's hard to find your issue without seeing some more code, so please share your solution.
Are you able to find out at which point your code fails? Try debugging with Visual Studio.

However, it's enough to register the HttpClient with services.AddScoped<HttpClient>(); in ConfigureServices.

@julienGrd

This comment has been minimized.

Copy link
Author

commented Feb 22, 2019

To reproduce this error, there is no really code, just create an empty SERVERSIDE razor project and follow the step to reproduce. (I precise server-side because you speak about 0.8 version, however with server side razor components there is no dependency to 0.8 library)

I have only these dependencies in the App Project (front project on server Side)

  • AspNetCore.Components.Browser 3.0.0-preview-19075-0444
  • AspNetCore.Components.Build 3.0.0-preview-19075-0444

Honestly, I'm really surprised about the complexity to switch my client-side project to server side, its seem really more difficult compare to what peope say with older version (the type of project are different : console/library, the wwwroot is not in the same project, the dependecy off the App project are different, and now the HttpClient who seem not work on the server side).

I test actually inject an IHttpClientFactory instead

@darren-zdc

This comment has been minimized.

Copy link

commented Feb 22, 2019

Inside the App project,
You should have

    <PackageReference Include="Microsoft.AspNetCore.Blazor" Version="0.8.0-preview-19104-04" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Build" Version="3.0.0-preview-19075-0444" />

Inside the server project,

    <PackageReference Include="Microsoft.AspNetCore.Blazor.Server" Version="0.8.0-preview-19104-04" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Server" Version="3.0.0-preview-19075-0444" />

(Optional) <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview-19075-0444" />

@julienGrd

This comment has been minimized.

Copy link
Author

commented Feb 22, 2019

@darren-zdc i'm not agree, with the last framework (.net core 3 preview), when you create a razor component project, there is no dependency to something like blazor. Try yourself, create a new razor component project in your visual studio (but maybe there is something i don't understand).

Server :

  • AspNetCore.Components.Server 3.0.0-preview-19075-0444

App:

  • AspNetCore.Components.Browser 3.0.0-preview-19075-0444
  • AspNetCore.Components.Build 3.0.0-preview-19075-0444

I still not understand good how i can design a server side razor component application. There is a lack of documentation, example, tutorial, for exemple how to manage data from server, manage authentication, things like that.
With client side (web assembly), I don't have this kind of problem (client and server are clearly separate, I can reproduce architecture i have i angular application for example).

but i definitively not understand how structure my application. With the client-side version of blazor, i called a rest login service which create a JWT and return them to the client. with the server side, it seem weird to call a web service whereas i'm already on the server)

If someone have a good example i can read and understand i take it ! (with the last version of course).

PS : I finally solve my problem by injecting an IHttpClientFactory in my service and register with services.AddHttpClient(); in Startup.

@darren-zdc

This comment has been minimized.

Copy link

commented Feb 22, 2019

Maybe you can look at here
They explain how to convert a client blazor to server blazor

@julienGrd

This comment has been minimized.

Copy link
Author

commented Feb 22, 2019

I already migrate my application, it's not really the problem.
It's more the philosophy of server side components i don't understand. For example:

design of my actual client side blazor application

Server :

  • render the app project (blazor)
  • expose some api controller called by the App project, including authentication. In my case the controllers calls Wcf services hosted by another server

Client (App) :

  • Hierarchy of component to create the entire webSite
  • some services, called by the components, wich call the api controller of the server. the services also add to the header the JWT if the user is connected.

For me, this kind of design is really clear, it was really simple to do that with blazor.

Now i really need to debug with efficiency my application because I retrieve like a hundred thousand of line of code (c# models and silverlight ViewModels adapted to work with no dependency), My project is to rewrite a silverlight application without rewriting the business code because the silverlight application will continue evolve during my development and the code is really complicated, so the two project (the old silverlight and my new Blazor app) will share the same code until the end of the migration (wich can be at least one year).

so I decided to switch to razor components to debug the viewModel included in my blazor app.

but now, there is lot of things i don't know how to design.
It seem really stupid to call an http get or post on my App.Services because i'm already on the server, so there is no reason to do that, and no reason to have a step of serialisation/deserialization in addition.

I'm really surprised to not find good example of a project on razor component (except the classic project with a button wich increment an integer, but this exemple is definitively too simple).

I don't know if i am the only who block on the server-side logic....

definitively a good example will be welcoming (for example, migrate the flightFinder project in the last server side razor components with the good guidelines of design)

@khenzar

This comment has been minimized.

Copy link

commented Mar 26, 2019

I'm really surprised to not find good example of a project on razor component (except the classic project with a button wich increment an integer, but this exemple is definitively too simple).

I don't know if i am the only who block on the server-side logic....

definitively a good example will be welcoming (for example, migrate the flightFinder project in the last server side razor components with the good guidelines of design)

Agree with you buddy. They say Razor Components is no longer experimental (on the contrary to Blazor) but in my opinion they are doing a lot more breaking changes to Razor Components between different preview versions than they were doing between Blazor minor versions. For example in Preview 3 the app and server are now in one project and the routing pipeline has changed which for example broke MVC/API controllers in lot of libraries etc.
At the end of the day I think we just need to wait for release 1, when things settle down.

@danroth27 danroth27 self-assigned this Apr 3, 2019
@danroth27 danroth27 added the question label Apr 3, 2019
@danroth27 danroth27 added this to the 3.0.0-preview5 milestone Apr 12, 2019
@danroth27

This comment has been minimized.

Copy link
Member

commented May 21, 2019

The original issue described by this bug appears to now provide a much better error:

image

As for the design question, you are correct that there is no point in calling into an API hosted on the server when running a server-side Blazor app. Instead you can inject services into your components that access server-side resources directly. To maintain symmetry with client-side Blazor you can inject different implementations of the service interface that either call APIs or access server-side resources as appropriate for the given environment.

Closing as there doesn't appear to be anything else to do here.

@danroth27 danroth27 closed this May 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.