Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 自定义服务器端模型验证标记帮助程序不通过ViewComponent中的unobtrusiveJS显示_Jquery_Asp.net Mvc_Asp.net Core_Asp.net Core Tag Helpers_Asp.net Core Viewcomponent - Fatal编程技术网

Jquery 自定义服务器端模型验证标记帮助程序不通过ViewComponent中的unobtrusiveJS显示

Jquery 自定义服务器端模型验证标记帮助程序不通过ViewComponent中的unobtrusiveJS显示,jquery,asp.net-mvc,asp.net-core,asp.net-core-tag-helpers,asp.net-core-viewcomponent,Jquery,Asp.net Mvc,Asp.net Core,Asp.net Core Tag Helpers,Asp.net Core Viewcomponent,我为位于ViewComponent内部的一组复选框创建了一个自定义验证属性。在我将其移动到ViewComponent之前,不引人注目的验证消息在asp验证中非常有效,但是现在消息没有出现在那里 同时,我正在收集服务器端验证错误并将其传递回视图,这正如预期的那样工作:因此,我通过自定义属性获取错误消息,它只是没有在视图中显示该消息 这是代码(我正在尽可能简化它,如果您需要更多信息,请告诉我。如果我遗漏了一些内容,我很抱歉。): 控制器: public IActionResult Enrollmen

我为位于ViewComponent内部的一组复选框创建了一个自定义验证属性。在我将其移动到ViewComponent之前,不引人注目的验证消息在asp验证中非常有效,但是现在消息没有出现在那里

同时,我正在收集服务器端验证错误并将其传递回视图,这正如预期的那样工作:因此,我通过自定义属性获取错误消息,它只是没有在视图中显示该消息

这是代码(我正在尽可能简化它,如果您需要更多信息,请告诉我。如果我遗漏了一些内容,我很抱歉。):

控制器:

public IActionResult Enrollment(EnrollmentViewModel enrollmentVM)
        {
            return View("~/Enrollment.cshtml", enrollmentVM);
        }


public EnrollmentViewModel SetModelListItems(EnrollmentViewModel enrollmentVM)
        {
            if (enrollmentVM.Preferences == null)
            {
                var preferencesList = preferences.GetAll().ToList();
                enrollmentVM.Preferences = preferences.Select(x => new SelectListItem
                {
                    Text = x.PreferencesName,
                    Value = x.PreferenceseId.ToString()
                }).ToList();
    return enrollmentVM;
    }

public class EnrollmentController : Controller
{
    public IActionResult Enrollment(EnrollmentViewModel enrollmentVM)
    {
        return View("Enrollment", enrollmentVM);
    }

    [HttpPost]
    public IActionResult Enroll(EnrollmentViewModel enrollmentVM)
    {
        if (!ModelState.IsValid)
        {
            return View("Enrollment", enrollmentVM);
        }
        else
        {
            //SaveForm
            return View("Enrollment", enrollmentVM);
        }
    }
}
带属性的视图模型:

public class EnrollmentViewModel
    {
    
        [ListItemSelected(ErrorMessage = "Please select at least one Preference option.")]
        public List<SelectListItem> Preferences { get; set; }
    }
    
public class ListItemSelectedAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                if ((value as List<SelectListItem>).Count(x => x.Selected) == 0)
                    return new ValidationResult(ErrorMessage);
            }

            return ValidationResult.Success;
        }
    }

公共类注册视图模型
{
[ListItemSelected(ErrorMessage=“请至少选择一个首选项选项。”)]
公共列表首选项{get;set;}
}
公共类ListItemSelectedAttribute:ValidationAttribute
{
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
if(值!=null)
{
if((值作为列表).Count(x=>x.Selected)==0)
返回新的ValidationResult(ErrorMessage);
}
返回ValidationResult.Success;
}
}
我觉得这是很多代码,但希望大部分代码都能解释我的问题。。。我把它削减了很多。jquery、验证和不引人注目的脚本位于_Layout.cshtml中。非常感谢你

编辑


我在ViewComponent和主视图文件中放置了一个断点,在这两个文件中,在Locals选项卡中,ViewContext显示ModelState无效,ValidationMessageElement=“span”!我想那不是它应该是的??我发现一篇帖子建议添加ViewContext.FormContext=new FormContext();在顶部,但有或没有FormContext项是相同的。

我测试了您的代码,但提交按钮没有启动。另外,在Html.begin中设置时,我没有看到
Enroll
操作

@using (Html.BeginForm("Enroll", "Enrollment", FormMethod.Post, new { enctype = "multipart/form-data", id = "EnrollForm" }))
我根据您的代码制作了一个示例,它似乎如您所期望的那样工作

主视图(Enrollment.cshtml)

项目结构:

结果:


当然,您是否尝试过在ViewComponent的视图文件中放置断点以检查其
模型状态
?其中应该有验证错误,否则标记帮助程序无法对进行asp验证。顺便说一句,我有点怀疑这个
asp for=“@Model.Preferences[I].Selected”
是否会呈现
Selected
的相应名称。您是否可以检查您的网页(使用浏览器的inspector工具)以查看为您的输入生成的实际名称?
的asp验证看起来很正确。@KingKing我不知道该怎么做(谢谢)。我这样做了,ModelState无效,ValidationMessageElement=“span”!我想那不是它应该是的??我在谷歌搜索了一下,发现一篇帖子建议添加
ViewContext.FormContext=newformcontext()
位于顶部,但有或没有它,FormContext项在Locals选项卡中都是相同的。您可以检查
ModelState
深入到每个
ModelStateEntry
的错误列表,这里的ModelState是一个
IReadOnlyDictionary
。您好!我修正了问题中的错误。我认为最主要的区别在于,因为我在虚拟机中使用了一个自定义属性,所以它只是服务器端验证,而且验证消息不会返回,尽管ModelState是。(我用更多信息更新了我的问题)。非常感谢你!
public IActionResult EnrollClient(EnrollmentViewModel viewModel)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    viewModel = SetModelListItems(viewModel);
                    viewModel.HasErrors = true;
                    viewModel.SubmitErrors = ModelState.Values
                        .SelectMany(state => state.Errors)
                        .Select(error => error.ErrorMessage);
                    return View("~/Enrollment.cshtml", viewModel);
                }
                SaveForm();
            }

//....
        }
public class EnrollmentViewModel
    {
    
        [ListItemSelected(ErrorMessage = "Please select at least one Preference option.")]
        public List<SelectListItem> Preferences { get; set; }
    }
    
public class ListItemSelectedAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                if ((value as List<SelectListItem>).Count(x => x.Selected) == 0)
                    return new ValidationResult(ErrorMessage);
            }

            return ValidationResult.Success;
        }
    }

@using (Html.BeginForm("Enroll", "Enrollment", FormMethod.Post, new { enctype = "multipart/form-data", id = "EnrollForm" }))
@model EnrollmentViewModel

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Enrollment</h1>

<div>
    @await Component.InvokeAsync("EnrollClient", new { enrollmentVM = @Model })
</div>
@model EnrollmentViewModel
@{ 
    var x = Model;
}

@using (Html.BeginForm("Enroll", "Enrollment", FormMethod.Post, new { enctype = "multipart/form-data", id = "EnrollForm" }))
{
<fieldset>
    <legend>Preferences (select all that apply)</legend>
    @for (var i = 0; i < Model.Preferences.Count(); i++)
    {
        <div>
            <input type="checkbox" asp-for="@Model.Preferences[i].Selected">
            <label>@Model.Preferences[i].Text</label>
            <input type="hidden" asp-for="@Model.Preferences[i].Value" />
            <input type="hidden" asp-for="@Model.Preferences[i].Text" />
        </div>
    }
    <button type="submit" id="EnrollForm" form="EnrollForm">
        <span>Save</span>
    </button>
    <span asp-validation-for="Preferences" class="text-danger"></span>
</fieldset>
}
public class EnrollClientViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(EnrollmentViewModel enrollmentVM)
    {
        enrollmentVM = SetModelListItems(enrollmentVM);
        return new ViewViewComponentResult()
        {
            ViewData = new ViewDataDictionary<EnrollmentViewModel>(ViewData, enrollmentVM)
        };

    }

    public EnrollmentViewModel SetModelListItems(EnrollmentViewModel enrollmentVM)
    {
        enrollmentVM.Preferences = new List<SelectListItem>
        {
            new SelectListItem{ Text = "A", Value = "1"},
            new SelectListItem{ Text = "B", Value = "2"},
            new SelectListItem{ Text = "C", Value = "3"},
        };
        return enrollmentVM;
    }
}
public class EnrollmentController : Controller
{
    public IActionResult Enrollment(EnrollmentViewModel enrollmentVM)
    {
        return View("Enrollment", enrollmentVM);
    }

    [HttpPost]
    public IActionResult Enroll(EnrollmentViewModel enrollmentVM)
    {
        if (!ModelState.IsValid)
        {
            return View("Enrollment", enrollmentVM);
        }
        else
        {
            //SaveForm
            return View("Enrollment", enrollmentVM);
        }
    }
}