【问题标题】:Remote validation model binding not working on a razor page in dotnet core 2.0远程验证模型绑定在 dotnet core 2.0 中的剃须刀页面上不起作用
【发布时间】:2018-07-17 11:49:44
【问题描述】:

我在剃须刀页面中有一个表单,其中包含一个具有远程验证的字段..

. . .
    <div class="form-group">
        <label class="control-label" asp-for="ReportViewModel.ExecSql"></label>
        <textarea class="form-control" asp-for="ReportViewModel.ExecSql" ></textarea>
        <span asp-validation-for="ReportViewModel.ExecSql" class="text-danger"></span>
    </div>
. . .

ReportViewModel中的字段定义为:

. . . 
[Remote(action: "VerifySql", controller: "ReportService", HttpMethod = "POST")]
public string ExecSql { get; set; }

调用下面的动作:

[AcceptVerbs("Post")]
public IActionResult VerifySql(string ExecSql)
{
   if (!Repository.VerifySql(ExecSql))
      return Json("Sql is not valid (Select statements only are allowed)");

    return Json(data: true);
}

剃须刀页面cs文件:

public class AddReportModel : PageModel
    {
        private readonly IIntegrityReportRepository _repository;
        private readonly IMapper _mapper;

        public AddReportModel(IIntegrityReportRepository repository, IMapper mapper)
        {
            _repository = repository;
            _mapper = mapper;
        }

        [TempData]
        public string ConfirmationMessage { get; set; }

        [BindProperty]
        public IntegrityReportViewModel ReportViewModel { get; set; }
. . .

这会调用操作,但 ExecSql 始终为空。这是因为当我查看请求时,表单正在发布.. ReportViewModel.ExecSql。我无法从我的 VerifySql 操作方法中获取。

我已尝试在 cshtml 字段中添加名称:

<textarea class="form-control" asp-for="ReportViewModel.ExecSql" name="ExecSql" ></textarea>

这会绑定字段并传递值,但是当它被传回时客户端验证不起作用。

我可以通过在 cs razor 页面文件中定义另一个字段来使其工作,例如

[Remote(action: "VerifySql", controller: "ReportService", HttpMethod = "POST")]
[BindProperty]
public string ExecSqlField { get; set; }

然后把cshtml改成:

<div class="form-group">
    <label class="control-label" asp-for="ExecSqlField"></label>
    <textarea class="form-control" asp-for="ExecSqlField"></textarea>
    <span asp-validation-for="ExecSqlField" class="text-danger"></span>
</div>

但是这感觉不对,然后我复制了需要在其他页面共享的视图模型。有没有办法通过某种方式让验证操作方法访问 ReportViewModel.ExecSql 来在我的操作方法中获取原始视图模型中的字段?

非常感谢您的帮助

【问题讨论】:

  • 我注意到了同样的事情,但我自己还没有找到令人满意的答案。
  • 应该补充一点,可以在远端的参数上使用[Bind(Prefix="ReportViewModel")]。但是由于 antiforgerytoken 也带有前缀,因此您无法通过注释验证 antiforgery(这意味着必须在 2.1 中主动禁用它)。无论哪种方式,它都不是一个好的选择。但是,既然您似乎没有在远程调用中包含防伪令牌,那么这可能就足够了吗?

标签: .net-core asp.net-core-2.0 razor-pages


【解决方案1】:

只是想补充一点,@Baseless 和 @Breno 确实有正确的答案。

我的财产是这样的:

        [Display(Name = "Access Code")]
        [Remote("CheckForGroup", "Users", "Admin", HttpMethod = "Post")]
        public string AccessCode { get; set; }

只有当我将它添加到我的控制器时它才有效:

    public IActionResult CheckForGroup([Bind(Prefix = "Input.AccessCode")] string accessCode)

谢谢你们!

【讨论】:

    【解决方案2】:

    在敲了很多头之后,我找到了一种解决方法。不是最优雅的,但它现在正在做这项工作。

    只需将 [Bind(Prefix = "ReportViewModel.ExecSql")] 添加到您的验证方法参数中。

    您可以使用“Model.Field”表单模式恢复更改并恢复。

    【讨论】:

      猜你喜欢
      • 2018-09-18
      • 2022-08-22
      • 2020-09-21
      • 2020-04-30
      • 2020-07-15
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多