验证模型中的属性是否高于另一个属性

时间:2013-03-11 19:50:58

标签: c# asp.net-mvc html5

我有这个模型,它包含以下两个属性:

public int m_ID
public int m_NbrInStock
public int m_QtyToShow

这是我实际渲染我的观点:

<script src="/Scripts/jquery-1.7.1.min.js"
        type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $("#selectAll").click(function ()
        {
            var chkValue = $(this).is(":checked");
            $(".divChckBox").prop("checked", chkValue);
        });
    });
</script>
<p>
    @using (Html.BeginForm("SendItems", "Inventory"))
    {
        <p>
            Select / UnSelet All Items @Html.CheckBox("selectAll", true) 
        </p>
        <table>
            <tr>
                <th>Obj Name</th>
                <th>Number In Stock</th>
                (...)
                <th>Quantity</th>
            </tr>
            @for (int i = 0; i < Model.Count(); i++)
            {
                <tr>
                    <td>@Html.DisplayFor(x => x[i].m_Card.m_CardName)</td>
                    <td>@Html.DisplayFor(x => x[i].m_NbInStock)</td>
                    (...)
                    <td>
                        <input type="checkbox" name="itemSending" class="divChckBox" checked="true" value="@Model[i].m_ID"/>
                    </td>

                    <td>@Html.TextBoxFor(x => x[i].m_QtyToShow</td>
                </tr>
            }

        </table>
        <div class="float-right">
            <input type="submit" value="Send"/>
        </div>
    }
</p>

我在这里遇到很多问题:

  1. 首先,我需要保留QtyToShow,因为它稍后将用于数据管理,但由于HTTPPost,数据无法在模型中存活;
  2. 我还需要验证QtyToShow永远不会高于m_NbrInStock,否则会显示错误消息。
  3. 这不是一项简单的任务,因为我在MVC开发方面没有太多经验,所以我不知道如何做到这一点。你能帮我吗?谢谢。

2 个答案:

答案 0 :(得分:3)

两种方法:

  • 在控制器中手动验证数据
  • 编写自定义验证程序

第一个是最简单的,第二个是更好的做法。

为了让您开始工作,让您的应用程序正常运行,您可以实施第一种方式,然后在您更熟悉mvc时重新进行重构。

所以在viewModel中添加一个属性

public string QuantityValidationMsg {get; set}

然后在您的视图中显示消息

<td>@Html.TextBoxFor(x => x[i].m_QtyToShow
 <span>@Html.DisplayFor(x => x[i].m_QuantityValidationMsg)</span></td>

然后在您的帖子操作中(需要接受List<yourViewModel> a List<int>,btw)

viewModel.QuantityValidationMsg = null;
if (viewModel.QtyToShow > viewModel.NbrInStock)
{
  viewModel.QuantityValidationMsg = "Error Message!";
}

对于第二种方法,您将创建一个实现ValidationAttribute的新类 并按照以下方式定义:

public class ValidateQuantity : ValidateAttribute
{
  private const string MESSAGE = "Error Message";
  public ValidateQuantity (int qtyInput, int qtyConfirm)
      : base( MESSAGE )
  {
     Input = qtyInput;
     Confirm = qtyConfirm;
  }

  public int Input {get; private set;}
  public int Confirm {get; private set;}

  public override bool IsValid (object value)
  {
    var properties = TypeDescriptor.GetProperties(value);
    var input = properties.Find(Input, false).GetValue(value); 
    var confirm = properties.Find(Confirm, false).GetValue(value); 
    if( input > confirm)
    {
      return false;
    }
    return true;
  }
}

然后使用新属性

装饰model属性
public int m_ID
public int m_NbrInStock

[ValidateQuantity]
public int m_QtyToShow

在视图中添加验证消息

@Html.ValidationMessageFor(m => m.m_QtyToShow)

答案 1 :(得分:1)

这种事情在Mkay中非常容易表达,这是我为这样的临时规则编写的自定义属性。它可以作为nuget包使用。安装完成后,您需要做的就是注释您的模型属性,如下所示:

[Mkay(">= m_NbrInStock")]
public int m_QtyToShow

如果您有兴趣,可以在我的博客上阅读更多关于Mkay的工作原理:https://einarwh.wordpress.com/2013/02/15/mkay-one-validation-attribute-to-rule-them-al/