模型验证在Razor Page .Net Core中不能正常工作。

问题描述 投票:0回答:1

Sup guys, im有这个麻烦一段时间,不知道该怎么办了。

我有一个重置密码的页面,这是一个剃刀页面。

@page
@model Project.API.Pages.ResetarSenhaModel
@{
    Layout = null;
    var sucesso = Request.Query["sucesso"].FirstOrDefault();
    var mensagem = Request.Query["mensagem"].FirstOrDefault();
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Reset Password</title>
</head>

<body>
@if (mensagem == null)
{ 
    <h1>Reset your password</h1>
    <form action="Auth/ResetPassword" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <input type="hidden" name="Token" value="@Request.Query["Token"]" />
        <input type="hidden" name="Email" value="@Request.Query["Email"]" />
        <table>
            <tr>
                <td>
                    Senha
                </td>
                <td>
                    <input type="password" name="NovaSenha" />
                    <span asp-validation-for="NovaSenha" class="text-danger"></span>
                </td>
            </tr>
            <tr>
                <td>
                    Confirmar Senha
                </td>
                <td>
                    <input type="password" name="ConfirmarNovaSenha" />
                    <span asp-validation-for="ConfirmarNovaSenha" class="text-danger"></span>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="Reset" />
                </td>
            </tr>
        </table>
    </form>
}
else
{
    if (sucesso.Equals("True"))
    {
        <h1>@mensagem</h1>
    }

    if (sucesso.Equals("False")) 
    {
        <h1>@mensagem</h1>
    }
}

</body>
</html>

在提交时调用这个动作。

[HttpPost]
        public async Task<IActionResult> ResetPassword([FromForm]ResetarSenhaVM resetarSenhaVM)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var resultado = await _autenticacaoService.ResetarSenha(resetarSenhaVM);

                    if (resultado.sucesso)
                        return RedirectToPage("/ResetarSenha", new { 
                            sucesso = resultado.sucesso,
                            mensagem = resultado.mensagem});

                    return RedirectToPage("/ResetarSenha", new { 
                            sucesso = resultado.sucesso,
                            mensagem = resultado.mensagem});
                }

                return RedirectToPage("/ResetarSenha");
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

然后,每当我提交的形式,我不能得到的验证属性错误消息 在span标签,相反,我得到了一个json。

{
    "errors": {
        "NovaSenha": [
            "The NovaSenha field is required.",
            "Password length is between 6 and 50."
        ]
    },
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "0HLJIO56EGJEV:00000001"
}

我缺少什么?任何建议都可以帮助,谢谢

我的startup.cs。

    public class Startup
    {
        public static IConfiguration Configuration { get; set; }
        public static IHostingEnvironment HostingEnvironment { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<PersisteContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddAutoMapper(typeof(MappingProfile));

            RepositoryScopeInjector.Add(services);
            ServiceScopeInjector.Add(services);

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton<ILogger>(LogManager.GetCurrentClassLogger());

            services.AddCors(options =>
            {
                options.AddPolicy("AllowMyOrigin",
                builder => builder.AllowAnyOrigin()
                                  .AllowAnyHeader()
                                  .AllowAnyMethod());
            });

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims
            services
                .AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

                })
                .AddJwtBearer(cfg =>
                {
                    cfg.RequireHttpsMetadata = false;
                    cfg.SaveToken = true;
                    cfg.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = Configuration["JwtIssuer"],
                        ValidAudience = Configuration["JwtIssuer"],
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
                        ClockSkew = TimeSpan.Zero
                    };
                    cfg.Events = new JwtBearerEvents
                    {
                        OnTokenValidated = context =>
                        {
                            // Add the access_token as a claim, as we may actually need it
                            var accessToken = context.SecurityToken as JwtSecurityToken;
                            if (accessToken != null)
                            {
                                ClaimsIdentity identity = context.Principal.Identity as ClaimsIdentity;
                                if (identity != null)
                                {
                                    identity.AddClaim(new Claim(ClaimTypes.Role, accessToken.Claims.Where(c => c.Type == ClaimTypes.Role).First().Value));
                                    identity.AddClaim(new Claim("id", accessToken.Claims.Where(c => c.Type == "id").First().Value));
                                    identity.AddClaim(new Claim("nome", accessToken.Claims.Where(c => c.Type == "nome").First().Value));
                                    identity.AddClaim(new Claim("email", accessToken.Claims.Where(c => c.Type == "email").First().Value));
                                }
                            }

                            return Task.CompletedTask;
                        }
                    };
                });

            services.AddApiVersioning(options =>
            {
                options.UseApiBehavior = false;
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ApiVersionReader = ApiVersionReader.Combine(
                    new HeaderApiVersionReader("x-api-version"));
            });

            services.AddVersionedApiExplorer(options =>
            {
                options.GroupNameFormat = "'v'VVV";
                options.SubstituteApiVersionInUrl = true;
            });

            if (!HostingEnvironment.IsProduction())
            {
                services.AddSwaggerGen();
                services.ConfigureOptions<ConfigureSwaggerOptions>();
            }

#if !DEBUG
            services.AddMvcCore().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddAuthorization()
            .AddJsonFormatters()
            .AddApiExplorer();
#else
            services.AddMvcCore(opts =>
            {
                opts.Filters.Add(new AllowAnonymousFilter());
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddJsonFormatters()
            .AddApiExplorer();
#endif
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
            {
                options.LoginPath = "/Home";
            });

            services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IApiVersionDescriptionProvider apiVersionDescriptionProvider)
        {
            //Usa appsetings.json de acordo com o ambiente de desenv. que está selecionado
            var builder = new ConfigurationBuilder()
            .SetBasePath(HostingEnvironment.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{HostingEnvironment.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
            Configuration = builder.Build();

            app.UseCors("AllowMyOrigin");

            var usCulture = new CultureInfo("en-US");
            var supportedCultures = new[] { usCulture };

            app.UseMiddleware(typeof(ErrorHandlingMiddleware));

            app.UseHttpContext();

            app.UseRequestLocalization(new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture(usCulture),
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            });

            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "")),
                RequestPath = "",
            });

            app.UseAuthentication();

            if (!HostingEnvironment.IsProduction())
            {
                app.UseSwagger();

                app.UseSwaggerUI(c =>
                {
                    foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
                    {
                        c.SwaggerEndpoint($"../swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                    }

                    c.RoutePrefix = "bmdoc";
                });
            }

            app.UseMvc();
        }
    }
}
.net model-view-controller razor .net-core razor-pages
1个回答
0
投票

所以在几个小时后,我得到了我想要的东西。我正在寻找一些关于剃须刀的文档,发现这个链接非常有用,回答了我的大部分问题。https:/docs.microsoft.comen-usaspnetcorerazor-pages?view=aspnetcore-3.1&tabs=visual-studio。

简单解释一下我的做法。

首先,我开始使用我的razor生成的类(在我的例子中是ResetPassword.cshtml.cs),结果是这样的。

public class ResetPasswordModel : PageModel
    {
        private readonly IAutenticacaoService _autenticacaoService;

        public ResetarSenhaModel(IAutenticacaoService autenticacaoService)
        {
            _autenticacaoService = autenticacaoService;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        public string Mensagem { get; private set; }
        public bool Sucesso { get; private set; }

        [BindProperty]
        public ResetarSenhaVM resetarSenhaVM { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            var resultado = await _autenticacaoService.ResetarSenha(resetarSenhaVM);

            this.Sucesso = resultado.sucesso;
            this.Mensagem = resultado.mensagem;

            return Page();
        }

    }
}

我使用[BindProperty]来绑定我所有需要验证的类属性到我的razor页面类中,我还导入了我的控制器,它的工作方式(至少)和我之前做的分离控制器一样。

最后在我的html中。

@page
@model Project.API.Pages.ResetPasswordModel
@{
    Layout = null;
}
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Reset Password</title>
</head>

<body>
@if (@Model.Mensagem == null && @Model.Sucesso == false)
{ 
    <h1>Reset your password</h1>
    <form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <input type="hidden" name="resetarSenhaVM.Token" value="@Request.Query["Token"]" />
        <input type="hidden" name="resetarSenhaVM.Email" value="@Request.Query["Email"]" />
        <table>
            <tr>
                <td>
                    Senha
                </td>
                <td>
                    <input 
                    type="password" 
                    name="resetarSenhaVM.NovaSenha"
                    />
                    <span asp-validation-for="resetarSenhaVM.NovaSenha" class="text-danger"></span>
                </td>
            </tr>
            <tr>
                <td>
                    Confirmar Senha
                </td>
                <td>
                    <input 
                    type="password" 
                    name="resetarSenhaVM.ConfirmarNovaSenha" />
                    <span asp-validation-for="resetarSenhaVM.ConfirmarNovaSenha" class="text-danger"></span>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="Reset" />
                </td>
            </tr>
        </table>
    </form>
}
else
{
    if (@Model.Sucesso == true)
    {
        <h1>@Model.Mensagem</h1>
    }

    if (@Model.Sucesso == false) 
    {
        <h1>@Model.Mensagem</h1>
    }
}

</body>
</html>

最重要的是:记得在你的html文件中使用TagHelper。@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

© www.soinside.com 2019 - 2024. All rights reserved.