Razor 组件上的 EditForm 未触发 OnValidSubmit
EditForm on Razor component not firing OnValidSubmit
我有一个简单的剃须刀组件,它接受用户的评论然后保存评论。呈现它的页面当前位于页面 >> Expeditions >> Index.cshtml。当我在浏览器中导航到 /Expeditions 时,一切都正确加载并且 OnValidSubmit 工作。当我导航到 /Expeditions/Index 时,页面会正确呈现,但永远不会触发 OnValidSubmit。
我猜当我在 URL 中省略 Index 时会发生某种魔法。我想知道我在这里做错了什么,因为如果我将组件放在索引页面以外的任何页面中,提交按钮不会触发 OnValidSubmit。
这是代码...
Index.cshtml
@page
@model Project1.com.Pages.Expeditions.IndexModel
@{
ViewData["Title"] = "Home page";
}
@(await Html.RenderComponentAsync<ComposeCommentComponent>(RenderMode.ServerPrerendered, new { PostId = 1 }))
<script src="_framework/blazor.server.js"></script>
ComposeCommentComponent.razor
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@using Project1.com.Models
@using Project1.com.Services
@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject CommentService CommentService
<EditForm Model="@Comment" OnValidSubmit="OnValidSubmit">
<div class="form-group">
<InputTextArea id="Comment" @bind-Value="@Comment.Comment" class="form-control" rows="5" cols="65" placeholder="Leave a Comment!"></InputTextArea>
</div>
<button class="btn btn-primary float-right">Submit</button>
</EditForm>
@functions{
public ClaimsPrincipal User { get; set; }
protected override async void OnInitialized()
{
await base.OnInitializedAsync();
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
User = authState.User;
}
}
@code {
[Parameter]
public int PostId { get; set; }
CommentModel Comment = new CommentModel();
private async void OnValidSubmit()
{
// Update Database with New Comment
CommentService.CreateComment(new CommentModel() { Username = User.Identity.Name, Comment=Comment.Comment, PostId=PostId});
// Clear Comment
Comment.Comment = "";
// Notify Parent Component to Update Data.
await OnNewComment.InvokeAsync(Comment.Id);
}
[Parameter]
public EventCallback<int> OnNewComment { get; set; }
}
Startup.cs
using Project1.com.Data;
using Project1.com.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Project1.com
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddTransient<ExpeditionService>();
services.AddTransient<CommentService>();
}
// 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.UseDatabaseErrorPage();
}
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.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages().RequireAuthorization();
endpoints.MapBlazorHub();
});
}
}
}
如果您检查不起作用的页面,您会发现有一个或多个 blazor.server.js
404 错误。大概是这样的:
您的问题是您没有为您的应用程序指定 base href
。
/Expeditions
有效,因为 Blazor 认为您在根目录中,但是
/Expeditions/Index
没有,因为它现在试图从 /Expeditions
子目录访问资源。
Blazor 使用 <base href="~/" />
定义获取资源的位置。
@page
@using Whosebug.Web.Components
@model WhosebugAnswers.Pages.MeModel
@{
ViewData["Title"] = "Home page";
}
<!DOCTYPE html>
<html lang="en">
<head>
<base href="~/" />
</head>
<body>
@(await Html.RenderComponentAsync<ComposeCommentComponent>(RenderMode.ServerPrerendered, new { PostId = 1 }))
<script src="_framework/blazor.server.js"></script>
</body>
</html>
注意:@enet 在他的回答中的要点仍然适用于清理您的代码。
我有一个简单的剃须刀组件,它接受用户的评论然后保存评论。呈现它的页面当前位于页面 >> Expeditions >> Index.cshtml。当我在浏览器中导航到 /Expeditions 时,一切都正确加载并且 OnValidSubmit 工作。当我导航到 /Expeditions/Index 时,页面会正确呈现,但永远不会触发 OnValidSubmit。
我猜当我在 URL 中省略 Index 时会发生某种魔法。我想知道我在这里做错了什么,因为如果我将组件放在索引页面以外的任何页面中,提交按钮不会触发 OnValidSubmit。
这是代码... Index.cshtml
@page
@model Project1.com.Pages.Expeditions.IndexModel
@{
ViewData["Title"] = "Home page";
}
@(await Html.RenderComponentAsync<ComposeCommentComponent>(RenderMode.ServerPrerendered, new { PostId = 1 }))
<script src="_framework/blazor.server.js"></script>
ComposeCommentComponent.razor
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@using Project1.com.Models
@using Project1.com.Services
@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject CommentService CommentService
<EditForm Model="@Comment" OnValidSubmit="OnValidSubmit">
<div class="form-group">
<InputTextArea id="Comment" @bind-Value="@Comment.Comment" class="form-control" rows="5" cols="65" placeholder="Leave a Comment!"></InputTextArea>
</div>
<button class="btn btn-primary float-right">Submit</button>
</EditForm>
@functions{
public ClaimsPrincipal User { get; set; }
protected override async void OnInitialized()
{
await base.OnInitializedAsync();
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
User = authState.User;
}
}
@code {
[Parameter]
public int PostId { get; set; }
CommentModel Comment = new CommentModel();
private async void OnValidSubmit()
{
// Update Database with New Comment
CommentService.CreateComment(new CommentModel() { Username = User.Identity.Name, Comment=Comment.Comment, PostId=PostId});
// Clear Comment
Comment.Comment = "";
// Notify Parent Component to Update Data.
await OnNewComment.InvokeAsync(Comment.Id);
}
[Parameter]
public EventCallback<int> OnNewComment { get; set; }
}
Startup.cs
using Project1.com.Data;
using Project1.com.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Project1.com
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddTransient<ExpeditionService>();
services.AddTransient<CommentService>();
}
// 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.UseDatabaseErrorPage();
}
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.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages().RequireAuthorization();
endpoints.MapBlazorHub();
});
}
}
}
如果您检查不起作用的页面,您会发现有一个或多个 blazor.server.js
404 错误。大概是这样的:
您的问题是您没有为您的应用程序指定 base href
。
/Expeditions
有效,因为 Blazor 认为您在根目录中,但是/Expeditions/Index
没有,因为它现在试图从/Expeditions
子目录访问资源。
Blazor 使用 <base href="~/" />
定义获取资源的位置。
@page
@using Whosebug.Web.Components
@model WhosebugAnswers.Pages.MeModel
@{
ViewData["Title"] = "Home page";
}
<!DOCTYPE html>
<html lang="en">
<head>
<base href="~/" />
</head>
<body>
@(await Html.RenderComponentAsync<ComposeCommentComponent>(RenderMode.ServerPrerendered, new { PostId = 1 }))
<script src="_framework/blazor.server.js"></script>
</body>
</html>
注意:@enet 在他的回答中的要点仍然适用于清理您的代码。