entity-framework - 如何从局部 View 实现元素的验证规则

标签 entity-framework partial-views asp.net-core-3.1 validationattribute

我们正在开发一个 .net core 3.1 MVC 应用程序(实际使用 MVVMC)。

我们已经实现了自定义验证属性。并希望在服务器和客户端上检查它们。

该 View 是标准 View ,但是用户可以将多个部分 View 添加到标准 View (通过按钮)。

在部分 View 中,我们无法在输入字段中使用“asp-for”标签助手,因为可以多次添加相同的项目,并且我们需要能够在 ViewModel 中创建一个列表从选定的其他部分 View 中。这就是我们尝试自己构建标签的原因。

一旦通过 ajax 请求部分 View ,我们将再次调用验证器。服务器验证有效,客户端验证仅适用于主视图上的输入,不适用于部分 View 上的输入。但是,刷新后或服务器在验证错误后将用户发送回来时,客户端验证开始工作(因为站点已完全刷新,并且 jquery 验证会考虑部分 View 的输入字段)。

请找到下面的代码:

验证属性的实现

public class AllowedExtensionsAttribute: ValidationAttribute, IClientModelValidator
{
    private readonly List<string> _extensions = new List<string>();

    public AllowedExtensionsAttribute(string extensions)
    {
        _extensions.Add(extensions);
    }

    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        if (value is IFormFile file)
        {
            var extension = Path.GetExtension(file.FileName);

            if (!_extensions.Contains(extension.ToLower()))
            {
                return new ValidationResult(ErrorMessage);
            }
        }

        return ValidationResult.Success;
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        context.Attributes.Add("data-val", "true");
        context.Attributes.Add("data-val-extension", ErrorMessage);
    }
 

}

主视图模型

[AllowedExtensions(".pdf", ErrorMessage = "This data type is not allowed!")]
public IFormFile PdfDocumentOne { get; set; }

部分 View 模型

[AllowedExtensions(".pdf", ErrorMessage = "This data type is not allowed!")]
public IFormFile PdfDocumentTwo { get; set; }

主视图

<form method="post" asp-controller="Home" asp-action="MainView" enctype="multipart/form-data">
    <div class="form-group top-buffer">
        <div class="row">
            <div class="col-2">
                <label asp-for="PdfDocumentOne" class="control-label"></label>
            </div>
            <div class="col-3">
                <input asp-for="PdfDocumentOne" class="form-control-file" accept="application/pdf" />
                <span asp-validation-for="PdfDocumentOne" class="text-danger"></span>
            </div>
        </div>
    </div>
    
    
    <div id="container">
        <div id="containerFull" class="form-group">
            <div class="row">
                <div class="col-2">
                    <label class="control-label">...</label>
                </div>
                <div class="col-10">
                    <div id="containerPartialView">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-2">
                </div>
                <div class="col-3">
                    <button id="AddPartialView" type="button" class="form-control">...</button>
                </div>
            </div>
        </div>
    </div>

    ...
    
     <div class="form-group top-buffer">
         <div class="row">
             <div class="col-2">
                 <input type="submit" value="Submit" class="form-control" id="checkBtn" />
             </div>
         </div>
     </div>
</form>

部分 View

<input id="Lists[@Model.ViewId].ViewId" name="Lists[@Model.ViewId].ViewId" class="partialViewModel" type="hidden" value="@Model.ViewId" />

<div id="Lists[@Model.ViewId].MainContainer" class="partialView">
    <div class="form-group">
        <div> 
            <div class="col-2">
                <label asp-for="PdfDocumentTwo" class="control-label"></label>
            </div>
            <div class="col-3">
                <input name="Lists[@Model.ViewId].PdfDocumentTwo" id="Lists[@Model.ViewId].PdfDocumentTwo " type="file" class="form-control-file" accept="application/pdf" 
                               data-val="true" data-val-extension="This data type is not allowed!"/>
                <span class="text-danger field-validation-valid" data-valmsg-for="Lists[@Model.ViewId].PdfDocumentTwo" data-valmsg-replace="true"></span>
            </div>
        </div>  
    </div>          
    ...
</div>

Javascript

function AddPartialView() {
    var i = $(".partialView").length;
    $.ajax({
        url: '/Home/AddPartialView?index=' + i,
        success: function (data) {
            $('#containerPartialView').append(data);
            $().rules('remove','extension');
            jQuery.validator.unobtrusive.adapters.addBool("extension");
        },
        error: function (a, b, c) {
            console.log(a, b, c);
        }
    });
}

$('#AddPartialView').click(function () {
    AddPartialView();
});

jQuery.validator.addMethod("extension",
    function (value, element, param) {

        var extension = value.split('.').pop().toLowerCase();

        if ($.inArray(extension, ['pdf']) == -1) {
            return false;
        }
        return true;
    });

jQuery.validator.unobtrusive.adapters.addBool("extension");

家庭 Controller

[HttpPost]
public IActionResult MainView(MainViewModel vm)
{
    if (vm == null)
    {
        return RedirectToAction("Index");
    }

    DatabaseHelper.GetMainViewModel(vm);
        
    if (!ModelState.IsValid)
    {
        @ViewData["StatusMessageNegative"] = "The entered data is not valid. Please scroll down to correct your data.";
         return View(vm);
     }
    
     return RedirectToAction("UploadDocument", new { Id = vm.Id});
 }


 [HttpGet]
 public ActionResult AddPartialView(int index)
 {
     PartialViewModel pvm = DatabaseHelper.GetPartialViewModel(index);
     return PartialView("Partial", pvm);
 }

在互联网上搜索后,我们发现了以下参数(data-ajax="true")。但是,我们不知道将其放置在哪里或如何正确使用它。

最佳答案

您是否尝试过在加载部分 View 后重新应用验证?

$.ajax({
    url: '/Home/AddPartialView?index=' + i,
    success: function (data) {
        $('#containerPartialView').append(data);
        $().rules('remove','extension');
        jQuery.validator.unobtrusive.adapters.addBool("extension");
    },
    error: function (a, b, c) {
        console.log(a, b, c);
    }
}).then(function () {
$("form").each(function () { $.data($(this)[0], 'validator', false); });
$.validator.unobtrusive.parse("form");

});

关于entity-framework - 如何从局部 View 实现元素的验证规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62265851/

相关文章:

c# - 将可为空的 int 映射到可为空的 int + automapper

c# - Entity Framework 中 IMigrationMetadata 接口(interface)的用途和语义

c# - 我应该使用 @html.renderpartial 还是 @html.renderaction

ruby-on-rails - Angular + rails : ngInclude directive not working

asp.net-mvc - ASP.net MVC - 呈现一个包含不同类型的列表,每种类型都有不同的 View

c# - 无法先投代码

c# - 远程过程调用 (RPC) 协议(protocol)流不正确

c# - Microsoft.AspNetCore.Routing.Matching.AmbigouslyMatchException : The request matched multiple endpoints

c# - 修改 WordprocessingDocument 不会保存更改

c# - 强制 Encoding.UTF8.GetString 抛出 ArgumentException