0

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

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 或在这种情况下显示错误消息。

这不是一个简单的任务,因为我在 MVC 开发方面没有太多经验,所以我不知道我该怎么做。你能帮我吗?谢谢你。

4

2 回答 2

3

有两种方法可以做到这一点:

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

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

To get you off the ground and get your app working, you can implement the first way, and then come back and refactor when you're more comfortable with mvc.

So add a property to your viewModel

public string QuantityValidationMsg {get; set}

Then in your view display the message

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

Then in your post action (which needs to accept a List<yourViewModel>, not a List<int>, btw)

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

For the second approach, you would create a new class that implements ValidationAttribute and define something along the lines of:

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;
  }
}

Then decorate the model property with the new attribute

public int m_ID
public int m_NbrInStock

[ValidateQuantity]
public int m_QtyToShow

And add the validation message in the view

@Html.ValidationMessageFor(m => m.m_QtyToShow)
于 2013-03-11T20:02:49.327 回答
1

This kind of thing is terribly easy to express in Mkay, a custom attribute I wrote for ad hoc rules like this. It's available as a nuget package. After installing, all you need to do is annotate your model property like this:

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

If you're interested, you can read more about how Mkay works at my blog: https://einarwh.wordpress.com/2013/02/15/mkay-one-validation-attribute-to-rule-them-al/

于 2013-03-11T21:00:18.120 回答