Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.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# 在ASP.NET MVC中使用自定义模型绑定器验证整数字段_C#_Asp.net Mvc_Validation - Fatal编程技术网

C# 在ASP.NET MVC中使用自定义模型绑定器验证整数字段

C# 在ASP.NET MVC中使用自定义模型绑定器验证整数字段,c#,asp.net-mvc,validation,C#,Asp.net Mvc,Validation,我遇到了一个我认为很有趣的问题 采用一个输入表单,该表单有一个整数值的输入字段(在我的例子中是成本)。我不希望“100美元”或“20美元”被发送到数据库,因为它可能会抱怨。我想向模型中添加一个错误并将其发送回用户。似乎很简单;) 我使用自定义模型绑定器,因为我在域模型中使用了一些继承。我有多种类型的事件,每种类型都实现IEEvent——因此,我需要一个自定义模型绑定器 我遇到的问题是,当我尝试绑定成本字段时,从字符串到int的转换失败,我真的不确定如何最好地处理这个问题。 我的自定义模型活页夹

我遇到了一个我认为很有趣的问题

采用一个输入表单,该表单有一个整数值的输入字段(在我的例子中是成本)。我不希望“100美元”或“20美元”被发送到数据库,因为它可能会抱怨。我想向模型中添加一个错误并将其发送回用户。似乎很简单;)

我使用自定义模型绑定器,因为我在域模型中使用了一些继承。我有多种类型的事件,每种类型都实现IEEvent——因此,我需要一个自定义模型绑定器

我遇到的问题是,当我尝试绑定成本字段时,从字符串到int的转换失败,我真的不确定如何最好地处理这个问题。

我的自定义模型活页夹 公共类EventModelBinder:IModelBinder { #区域成员

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Trivial code ... binding other fields...

        _event.ProjectedCost = GetA<int>(bindingContext, "ProjectedCost").GetValueOrDefault(-1);

        return _event;
    }

    #endregion

    // From Scott Hanselman's blog :)
    private Nullable<T> GetA<T>(ModelBindingContext bindingContext, string key) where T : struct
    {
        if (String.IsNullOrEmpty(key)) return null;
        ValueProviderResult valueResult;
        Nullable<T> ret;
        //Try it with the prefix...
        bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName + "." + key, out valueResult);
        //Didn't work? Try without the prefix if needed...
        if (valueResult == null && bindingContext.FallbackToEmptyPrefix == true)
        {
            bindingContext.ValueProvider.TryGetValue(key, out valueResult);
        }
        if (valueResult == null)
        {
            return null;
        }

        try
        {
            ret = (Nullable<T>)valueResult.ConvertTo(typeof(T));
        }
        catch
        {
            return null;
        }

        return ret;
    }
公共对象绑定模型(ControllerContext ControllerContext,ModelBindingContext bindingContext) { //琐碎的代码…绑定其他字段。。。 _event.ProjectedCost=GetA(bindingContext,“ProjectedCost”).GetValueOrDefault(-1); 返回事件; } #端区 //来自Scott Hanselman的博客:) 私有可为null的GetA(ModelBindingContext,string key),其中T:struct { if(String.IsNullOrEmpty(key))返回null; ValueProviderResult valueResult; 可为空的ret; //用前缀试试看。。。 bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName+“+”+键,out valueResult); //不起作用?如果需要,请尝试不使用前缀。。。 if(valueResult==null&&bindingContext.FallbackToEmptyPrefix==true) { bindingContext.ValueProvider.TryGetValue(键,out valueResult); } 如果(valueResult==null) { 返回null; } 尝试 { ret=(可为null)valueResult.ConvertTo(typeof(T)); } 抓住 { 返回null; } 返回ret; } 这非常有效-如果枚举为null或未选中,我可以对其进行验证,并让用户知道这是必需的。对于成本字段,如果转换失败,我得到-1。但是,当我在服务器上验证数据并返回UI时,Model.Event.ProjectedCost字段为null

我的活动服务

// ...
protected bool ValidateEvent(IEvent eventToValidate)
    {            
        if (eventToValidate.ProjectedCost < 0)
            _validationDictionary.AddError("ProjectedCost", "Incorrect format");

        return _validationDictionary.IsValid;
    }

    public bool SaveEvent(IEvent _event)
    {
        if (!ValidateEvent(_event))
            return false;
        try
        {
            _repository.SaveEvent(_event);
            return true;
        }
        catch
        {
            return false;
        }
/。。。
受保护的bool ValidateEvent(IEvent eventToValidate)
{            
如果(eventToValidate.ProjectedCost<0)
_validationDictionary.AddError(“ProjectedCost”,“格式不正确”);
返回_validationDictionary.IsValid;
}
公共bool SaveEvent(IEvent\u事件)
{
如果(!ValidateEvent(_事件))
返回false;
尝试
{
_SaveEvent(_事件);
返回true;
}
抓住
{
返回false;
}
My Edit.aspx视图

编辑
领域

项目成本:

在我看来,Model.Event.ProjectedCost如果不进行验证则为null,这给了我一个问题(第54行是罪魁祸首):

异常详细信息:System.NullReferenceException:对象引用未设置为对象的实例。
源错误:
第52行:
第53行:项目成本:
第54行:
第55行:
第56行:

我想做的是将用户输入的值发送回用户,但我的自定义模型绑定器和/或验证逻辑似乎将某些内容设置为null


我意识到这可能不是最容易理解的问题,所以请让我知道我是否可以以任何方式进行澄清!

您可以使用javascript将文本框的输入限制为仅整数。

您可以使用javascript将文本框的输入限制为仅整数。

如果您调用AddModelError而不使用SetModelValue,则首先,有时您会得到一个全新的NullReferenceExceptions:


如果您在没有先调用SetModelValue的情况下调用AddModelError,您可能会得到一个全新的NullReferenceExceptions,有时:


+1非常正确-我不想完全依赖JS。但是,我希望在用户禁用JS的情况下有一个可靠的后援。是的,当然。我永远不会只进行前端验证,因为你永远不知道用户是如何设置的+1非常正确-我不想完全依赖JS。但是,我希望在用户禁用JS的情况下有一个可靠的后援是的,当然。我永远不会只进行前端验证,因为你永远不知道用户是如何设置的。你确定不能使用默认的模型绑定器吗?因为我怀疑绑定器没有做默认绑定器所做的事情,这就是为什么验证时没有返回你的值。我尝试过,但我的视图继承自IEvent-so默认模型绑定器试图创建IEvent的实例,这是不可能的,因为它是一个接口。你确定不能使用默认模型绑定器吗?因为我怀疑绑定器没有做默认模型绑定器所做的事情,这就是为什么验证时没有返回你的值的原因。我尝试了,但我的视图继承自IEvent-因此efault model binder试图创建IEEvent的实例,这是不可能的,因为它是一个接口。该博客帖子修复了该实例,但现在我得到的值是“-1”,而不是用户输入的值。嗯……该博客帖子修复了该实例,但现在我得到的值是“-1”,而不是用户输入的值。嗯。。
<h2>Edit</h2>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="ProjectedCost">ProjectedCost:</label>
            <%= Html.TextBox("ProjectedCost", Model.Event.ProjectedCost) %>
            <%= Html.ValidationMessage("ProjectedCost", "*") %>
        </p>

        <% Html.RenderPartial(String.Format("~/Views/Shared/{0}Form.ascx", Model.Event.Type), Model.Event, ViewData); %>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

<% } %>

<div>
    <%=Html.ActionLink("Back to List", "Index") %>
</div>
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 52:             <p>
Line 53:                 <label for="ProjectedCost">ProjectedCost:</label>
Line 54:                 <%= Html.TextBox("ProjectedCost", (Model.Event.ProjectedCost == null ? 0 : Model.Event.ProjectedCost)) %>
Line 55:                 <%= Html.ValidationMessage("ProjectedCost", "*") %>
Line 56:             </p>