Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor in MVC: Component gets rendered, but @onclick not working. Problem with connection

I'm trying to use Blazor in a .net core 3 MVC project. I used a few tutorials to do this, like https://fizzylogic.nl/2019/08/18/integrating-blazor-in-an-existing-asp-net-core-application/ and https://chrissainty.com/using-blazor-components-in-an-existing-mvc-application/ .

What is working: The initialization of the Blazor component is working. The OnInitializedAsync() function gets triggered and the component gets rendered fine.

This is the call from the MVC View:

@(await Html.RenderComponentAsync<MyProject.Components.Locations>(RenderMode.ServerPrerendered))

What isn't working: using @onclick in the Blazor component. This is some sample code:

<span @onclick="AddLocation"></span>

@code {
    private void AddLocation(){

    }
}

The reason it probably doesn't work is that I get errors in the initialization of the connection. The component gets rendered not from the base path, but from the url of the specific view, and I think that messes with the connection. I receive these errors in the console of Chrome:

  • [2019-12-02T09:26:08.117Z] Information: Normalizing '_blazor' to 'https://localhost:44375/Locations/_blazor'. _blazor/negotiate:1 Failed to load resource: the server responded with a status of 404 () blazor.server.js:1
  • [2019-12-02T09:26:08.155Z] Error: Failed to complete negotiation with the server: Error e.log @ blazor.server.js:1 blazor.server.js:1
  • [2019-12-02T09:26:08.156Z] Error: Failed to start the connection: Error e.log @ blazor.server.js:1 blazor.server.js:15
  • [2019-12-02T09:26:08.156Z] Error: Error e.log @ blazor.server.js:15 blazor.server.js:1 -Uncaught (in promise) Error: Cannot send data if the connection is not in the 'Connected' State.

The main fault is probably the 'Normalizing '_blazor' to 'https://localhost:44375/Locations/_blazor''. Requesting _blazor from the base path works. Does anyone know how to set the basepath in such a situation?

(Yes, Blazor in a normal Razor page environment is probably easier, but I want to try Blazor in MVC.)

edit 1

<base href="/" /> in the header seems to have fixed the errors in the console. I hoped it would fix the onclick issue, but not yet... I think the component gets somehow treated like a normal razor component, and not as a blazor component. If I look at the generated html, I can find this: <span @onclick="AddLocation" ></span>, and I think that is wrong (with a normal razor/blazor project, the @onclick dissapears from the html). Anyone knows the solution for this? Tried this: https://stackoverflow.com/a/58444907/1794246 , but that didn't do much.

edit 2

Having a _imports.razor file in the root of the MVC project did obviously nothing. Adding these using statements to the Blazor component actually fixed the problem with the onclick (also Intellisense recognized things in the component a bit better):

@using Microsoft.AspNetCore.Components
@using Microsoft.AspNetCore.Components.Web;
like image 923
Rub3s Avatar asked Dec 02 '19 09:12

Rub3s


People also ask

Can you use Blazor components in MVC?

Blazor components can be used in existing ASP.NET MVC applications.

How do you use onclick in Blazor?

Adding a button onclick event The first thing we need to is to create a NewComment property. This will store the textarea value. We then need to bind our NewComment property to the textarea value. We do that by using the @bind attribute.


2 Answers

The solution to the problem was changing two things:

  • To fix the errors in the console I had to put <base href="/" /> in the header of _Layout.cshtml
  • To fix the actual @onclick issue I had to put these using statements in the Blazor component:
@using Microsoft.AspNetCore.Components
@using Microsoft.AspNetCore.Components.Web;

After that the @onclick was working and intellisense recognized stuff a bit better in the Blazor component.

like image 145
Rub3s Avatar answered Oct 12 '22 02:10

Rub3s


From the docs: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/blazor/index?view=aspnetcore-3.0&tabs=visual-studio#app-base-path

App base path

The app base path is the app's root URL path. Consider the following ASP.NET Core app and Blazor sub-app:

  • The ASP.NET Core app is named MyApp:
    • The app physically resides at d:/MyApp.
    • Requests are received at https://www.contoso.com/{MYAPP RESOURCE}.
  • A Blazor app named CoolApp is a sub-app of MyApp:
    • The sub-app physically resides at d:/MyApp/CoolApp.
    • Requests are received at https://www.contoso.com/CoolApp/{COOLAPP RESOURCE}.

Without specifying additional configuration for CoolApp, the sub-app in this scenario has no knowledge of where it resides on the server. For example, the app can't construct correct relative URLs to its resources without knowing that it resides at the relative URL path /CoolApp/.

To provide configuration for the Blazor app's base path of https://www.contoso.com/CoolApp/, the <base> tag's href attribute is set to the relative root path in the Pages/_Host.cshtml file (Blazor Server) or wwwroot/index.html file (Blazor WebAssembly):

<base href="/CoolApp/">

Blazor Server apps additionally set the server-side base path by calling in the app's request pipeline of Startup.Configure:

app.UsePathBase("/CoolApp");

By providing the relative URL path, a component that isn't in the root directory can construct URLs relative to the app's root path. Components at different levels of the directory structure can build links to other resources at locations throughout the app. The app base path is also used to intercept selected hyperlinks where the href target of the link is within the app base path URI space. The Blazor router handles the internal navigation.

In many hosting scenarios, the relative URL path to the app is the root of the app. In these cases, the app's relative URL base path is a forward slash (<base href="/" />), which is the default configuration for a Blazor app. In other hosting scenarios, such as GitHub Pages and IIS sub-apps, the app base path must be set to the server's relative URL path of the app.

To set the app's base path, update the <base> tag within the <head> tag elements of the Pages/_Host.cshtml file (Blazor Server) or wwwroot/index.html file (Blazor WebAssembly). Set the href attribute value to /{RELATIVE URL PATH}/ (the trailing slash is required), where {RELATIVE URL PATH} is the app's full relative URL path.

For an Blazor WebAssembly app with a non-root relative URL path (for example, <base href="/CoolApp/">), the app fails to find its resources when run locally. To overcome this problem during local development and testing, you can supply a path base argument that matches the href value of the <base> tag at runtime. Don't include a trailing slash. To pass the path base argument when running the app locally, execute the dotnet run command from the app's directory with the --pathbase option:

dotnet run --pathbase=/{RELATIVE URL PATH (no trailing slash)}

For a Blazor WebAssembly app with a relative URL path of /CoolApp/ (<base href="/CoolApp/">), the command is:

dotnet run --pathbase=/CoolApp

The Blazor WebAssembly app responds locally at http://localhost:port/CoolApp.

like image 26
Flores Avatar answered Oct 12 '22 02:10

Flores