Integrate React to an MVC ASP.NET project - c#

i have to use React component in my MVC project. I found out that is possible by installing some Packages with NuGets. I installed:
-React.Web.Mvc4
-JavaScriptEngineSwitcher.V8
-Microsoft.ClearScript.V8.Native.win-x86 and x64
I tried to follow tutorials online but seem that i miss something important cause the simple string that i want to show doesn't appear.
Maybe is only an error of setting so i leave here the codes and the directory folders. In many tutorials the have a Scripts folder, but i don't cause creating an MVC project with VS put js file in 'wwwroot" so i thougth to use that folder to contains my Component.
Program.cs:
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.V8;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddMvc().AddRazorRuntimeCompilation();
JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName;
JsEngineSwitcher.Current.EngineFactories.AddV8();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Index.js:
class Index extends React.Component {
render() {
return (
<h1> Hello Jems </h1>
)
}
}
ReactDOM.render(<Index />, document.getElementById("root"))
Index.cshtml
#using SportData.Web.Models;
#using React.Web.Mvc;
#model SportContainer
<div id="root"></div>
<script src="~/js/index.jsx"></script>
_Layout.cshtml:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - SportData</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/WebApplication1.styles.css" asp-append-version="true" />
<link rel="stylesheet" href="~/css/card.css" asp-append-version="true" />
</head>
<body>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<script crossorigin="anonymous" src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#await RenderSectionAsync("Scripts", required: false)
</body>
</html>
[link to directory foldes]
[1]: https://i.stack.imgur.com/VEQom.png

Related

How can i implement a HCaptcha in Blazor-Server?

I have been trying to implement a hCaptcha to my blazor-server project for the last couple days, but everything i tried failed in one way or another.
My most promising attempt was to just add the HTML-code from the hcaptcha website to the app.
I added
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
inside the <!head> element of the _Layout.cshtml, and
<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
in my index.razor, to show the captcha there.
The odd thing is: Every time I load the site, the captcha is visible for about 0.2 seconds and then becomes invisible.
I also tried the same code in the w3schools.com HTML Simulator and it worked perfectly fine, so I assume this has something to do with blazor.
Here is my code
index.razor
#page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<p>Currently, the <code>ChildContext</code> is temporarily rendered by the week component, and the data-related operating components in all cells are not encapsulated and will be refined later</p>
<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
#code {
protected override async Task OnInitializedAsync()
{
}
void CheckValidity()
{
//GeneralMethods.CheckCaptcha();
}
}
and _Layout.cshtml
#using Microsoft.AspNetCore.Components.Web
#namespace NixPfusch.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="NixPfusch.styles.css" rel="stylesheet" />
<!--Added Script for hCaptcha-->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
#RenderBody()
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
Reload
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
Any help would be apprechiated!

Changing the default page in BlazorWebAssembly not working

using Visual Studio 2019, I created a Blazor Web Assembly project.
I want to use the index.html page for something else, so I removed the <app></app> tag from it.
Then created another page named dashboard.html and added a dashboard.razor page. In this page added #page "/dashboard" and the <app></app> tag.
Now when I navigate to dashboard.html from index.html, am getting message "there is nothing at this address"
How could I make the dashboard.html page as my main app page?
Any ideas most appreciated.
This is how the project properties look:
To get this running I suggest you set up a blank WASM project from the Blazor template. Once you have it running you can make the necessary changes to your project. (My project is called Blazor.Starter.WASM.)
Move the Client project wwwroot to the Server project.
Copy index.html to dashboard.html - here's
serverproject/wwwroot/dashboard.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Blazor.Starter.WASM</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="Blazor.Starter.WASM.Client.styles.css" rel="stylesheet" />
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
Reload
<a class="dismiss">🗙</a>
</div>
<script src="/site.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
My simple index.html looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Blazor.Starter.WASM</title>
<base href="/"/>
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="m-4 p-4">
Go to Dashboard
</div>
</body>
</html>
Index.razor looks like this. Note the two page references
#page "/"
#page "/dashboard/"
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
#code {
}
Counter.razor and all other pages in the SPA - add #page "/dashboard/nnnnn"
#page "/counter"
#page "/dashboard/counter"
.....
NavMenu.razor looks like this (changes to the hrefs):
.....
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="dashboard" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="dashboard/counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="dashboard/fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
......
Finally update Startup.cs on the Server project.
....
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
// New section to map all requests starting with /dashboard to the Blazor Wasm project
app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/dashboard"), app1 =>
{
app1.UseRouting();
app1.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("dashboard.html");
});
});
// default endpoint
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
}
If I have these instructions correct the application should start on the simple index page. Once in the WASM try an F5 to check the Endpoint mapping works correctly - note all #page references within the SPA must be prefixed with /dashboard to ensure the F5 reload works.

Script tag not working ASP.NET core, webpack, typescript and knockout

I have a solution made up of the above technologies. I am using knockout components made up of .html and .ts files. When trying a simple <script> tag on the .html file, nothing happens.
The component is payment-details.html and the code is as simple as follows:
<h1>Payment details</h1>
<script type="text/javascript">
alert("test");
</script>
The underlying payment-details.ts is:
import * as ko from 'knockout';
class PaymentDetailsViewModel {
constructor() {
}
}
export default { viewModel: PaymentDetailsViewModel, template: require('./payment-details.html')};
and the _Layout.cshtml file is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] Contactless Check In</title>
<base href="~/" />
<environment exclude="Development">
<link rel="stylesheet" href="~/dist/site.css" asp-append-version="true" />
</environment>
</head>
<body>
#RenderBody()
<script src="~/dist/vendor.js" asp-append-version="true"></script>
#RenderSection("scripts", required: false)
</body>
</html>
I'm not sure what the issue is or where to start looking. There's something in the solution somewhere that is stopping script execution. Nor does it render in the html.
Thank you!

ASP.NET Core MVC / RAZOR - Styles equivalent of #Section Scripts

MVC & Razor allow for scripts to be composed in a specific view. If using a _Layout, a programmer trigger this section to render from inside the _Layout.cshtml file by inserting #RenderSection("Scripts", required: false)
Example
Index.cshtml (view)
...
#section Scripts{
<script>
var input = document.getElementById("search-bar");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("search-btn").click();
}
});
var searchBtn = document.getElementById("search-btn");
searchBtn.addEventListener("click", function(event) {
alert("click");
});
</script>
}
_Layout.cshtml
...
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
#RenderSection("Scripts", required: false)
I am curious if it is possible to do the same sort of workflow for style sheets. This would enable styles to be composed into the appropriate view making the view a self contained script. This would also prevent the programmer from having to shove every possible css file in the layout and thus loading everything with every route regardless if it is used or not. If this is possible it is unclear to me.
Proposed Example
Index.cshtml
<div>...</div>
#section Scripts {
<script>
...
</script>
}
#section Styles {
<style>
...
</style>
}
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - SCP_Client</title>
<link rel="stylesheet" href="~/css/Solar/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/app.css" />
**#RenderSection("Styles", Required: false )**
</head>
<body>
<div class="container" id="header-container">
<div class="row">
...
</div>
</div>
<div class="container" id="body-container">
#RenderBody()
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
**#RenderSection("Scripts", required: false)**
</body>
</html>

JQuery data table not working in my Blazor and .NET core project

I am trying to use JQuery datatable in my blazor project. I am using the CDN files to load the framework. This is my _Host.cshtml file:
#page "/"
#namespace Blazor.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Blazor</title>
<base href="~/" />
<environment include="Development">
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
asp-fallback-href="css/bootstrap/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
crossorigin="anonymous"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
</environment>
<link href="css/site.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/jq-3.3.1/dt-1.10.18/datatables.min.css" />
</head>
<body>
<app>
#(await Html.RenderComponentAsync<App>
())
</App>
<script src="_framework/blazor.server.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/jq-3.3.1/dt-1.10.18/datatables.min.js"></script>
<script>
$(document).ready(function () {
$('#carTable').DataTable();
});
</script>
</body>
</html>
And in my CarData.razor file I connect the ID like this:
<table id="carTable" class="display" style="width:100%">
When I run the application it doesn't load the framework. I get no error in my console.
I have read about Javascript interop in this documentation:
https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interop?view=aspnetcore-3.0
Somehow it doesn't read my CDN files from the JQuery datatable.
Can someone point me in the right direction?
I have figured it out:
In my _Host.cshtml I have this code:
<script>
function DataTable() {
$(document).ready(function () {
$('#carTable').DataTable();
});
}
</script>
Then in my CarData.razor I call this method like this:
protected override async Task OnInitAsync()
{
await JSRuntime.InvokeAsync<object>("DataTable");
}
Don't forget to inject the library in your page:
#inject IJSRuntime JSRuntime
There might be some DataTable elements left over when you leave your page. You need to remove all elements with IDispose.
For a complete tutorial, have a look at this post:
How to add Data Tables to Blazor
Sine ASP.NET Core 5.0 you can directly access jQuery plugins like DataTables without having to define a wrapper-function globally:
#code {
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender) {
if (firstRender) {
var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
await jQuery.InvokeVoidAsync("DataTable");
}
}
}

Categories