Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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
C# 向模型中添加隐藏字段时,MVC范围属性失败_C#_Asp.net Mvc_Asp.net Mvc 3_Mvc Editor Templates_Editorfor - Fatal编程技术网

C# 向模型中添加隐藏字段时,MVC范围属性失败

C# 向模型中添加隐藏字段时,MVC范围属性失败,c#,asp.net-mvc,asp.net-mvc-3,mvc-editor-templates,editorfor,C#,Asp.net Mvc,Asp.net Mvc 3,Mvc Editor Templates,Editorfor,我有一个父模型,其中包含子模型用于预填充视图上字段的属性。 我想将属性移动到它所属的子模型中,但是当我这样做时,另一个属性的range属性失败。 当我有一个仅用于在EditorTemplate上隐藏的属性时,为什么range属性验证失败 模型看起来像 public class ParentModel { public SubModel subModel { get; set; } } public class SubModel { public uint? DefaultValu

我有一个父模型,其中包含子模型用于预填充视图上字段的属性。 我想将属性移动到它所属的子模型中,但是当我这样做时,另一个属性的range属性失败。 当我有一个仅用于在EditorTemplate上隐藏的属性时,为什么range属性验证失败

模型看起来像

public class ParentModel
{
    public SubModel subModel { get; set; }
}
public class SubModel
{
    public uint? DefaultValue { get; set; }

    [Required]
    [Range(1,100)]
    public uint RangedId { get; set;}

    public bool EnableRange { get; set; }
}
视图(EditorTemplate)如下所示

@model SubModel
@Html.HiddenFor(model => model.DefaultValue)
@Html.TextBoxFor(model => model.RangeId)
<script>
     $('#EnableRange').change(function() {
         if($('#EnableRange').val()){
             // remove the disabled attribute from the RangeId Field
         } else {
             // add the disabled attribute from the RangeId Field
         }
     }
</script>
使用子模型中的DefaultValue属性,即使在窗体上禁用RangeId,也会激发RangeId的Range属性。这将导致ModelState.IsValid为false。
当我将DefaultValue属性向上移动到ParentModel时,RangeId的Range属性不再激发(因为该字段是禁用的)。这将导致ModelState.IsValid为true,因为RangeId从未进行过验证计算。

您认为正在发生的任何事情都不会发生。服务器端Model.IsValid不关心任何问题,禁用客户端的控件也不会直接影响它(尽管它可能会受到间接影响,我们将在下面看到)。如果发布了嵌套表单字段,并且嵌套对象具有必需的属性,则始终会进行验证

更可能的是,这里真正的问题是,当您在子模型中有DefaultValue时,然后当您将模型提交给父模型时,模型绑定器会创建子模型的实例,因为它包含DefaultValue的值。将其移动到父对象并禁用RangeId时,没有要发布的值,因此不会创建子模型,因此不会进行验证

也就是说,我的猜测是,当您将DefaultValue移动到父级时,子模型在回发时为null,因此,由于没有要验证的实例,所以验证不会失败,特别是因为您没有持久化EnableRange值


所以你真的有几个问题。首先,在客户端禁用控件不会在服务器上禁用验证。其次,如果没有向服务器发布嵌套表单字段,则不会创建嵌套对象,也不会进行验证(因此,如果非常小心,验证可能会被禁用,作为一种副作用)。第三,如果您确实发布了一些嵌套表单字段,但没有发布其他字段,则将创建验证嵌套对象,并对由于禁用而未发布的字段进行验证。

如果发布视图呈现的html片段,可能会有所帮助。很难理解你想用js做什么。不清楚你在这里做什么。如果禁用控件,它不会回发,在这种情况下,
ModelState
将无效,因为
RangedId
的值为
0
听起来是使用该接口的一个很好的理由。同意。看起来逻辑相当复杂。服务器端逻辑可以在IValidatableObject中复制,也可以创建一些来整合逻辑。
public ActionResult Create(TViewModel model)
{
    try
    {
        if (ModelState.IsValid)
        {
            //Do Something Meaningful
        }
        //Redisplay the view
    }
}