AddModelError未传递回Controller

时间:2012-12-10 20:21:49

标签: c# asp.net-mvc razor

我正在使用带有C#的asp.net Razor。我正在尝试验证输入的值是否为货币,但我似乎无法正确执行此操作。

这是我的PaymentModel:

  [Required]
  [DataType(DataType.Currency)]
  [DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
  [Display(Name = "Payment Amount:")]
  public decimal Amount { get; set; }

这是我的预付款视图:

@model SuburbanCustPortal.Models.PaymentModel.PrePayment

@{
    ViewBag.Title = "Make a payment!";
}

<script>
$(function(){
  $("#AccountId").change(function(){
    var val=$(this).val();
    $("#currentBalance").load("@Url.Action("GetMyValue","Payment")", { custid : val });
    document.forms[0].Amount.focus();
  });
});
</script>

<h2>Make a Payment</h2>

  @using (Html.BeginForm("SendPayment", "Payment", FormMethod.Post))
  {
    @Html.ValidationSummary(true, "Please correct the errors and try again.")
    <div>
      <fieldset>
        <legend>Please enter the amount of the payment below:</legend>

        <div class="editor-label">
          Please select an account.
        </div>

        @Html.DropDownListFor(x => x.AccountId, (IEnumerable<SelectListItem>)ViewBag.Accounts)

        <div class="editor-label">
          @Html.LabelFor(m => m.AccountBalance)
        </div>
        <div class="editor-field">
          <label class="sizedCustomerDataLeftLabel" id="currentBalance">@Html.DisplayFor(model => model.AccountBalance)&nbsp;</label>
        </div>      

        <div class="editor-label">
          @Html.LabelFor(m => m.Amount)
        </div>
        <div class="editor-field focus">
          @Html.TextBoxFor(m => m.Amount, new { @class = "makePaymentText" })
          @Html.ValidationMessageFor(m => m.Amount)
        </div>

        <p>
          <input id="btn" class="makePaymentInput" type="submit" value="Pay Now"  onclick="DisableSubmitButton()"/>  
        </p>
      </fieldset>
    </div>
  }

This is my Prepayment ActionResult:

    [Authorize]
    public ActionResult PrePayment(PaymentModel.PrePayment model)
    {
      var list = new List<SelectListItem>();
      var custs = _client.RequestCustomersForAccount(User.Identity.Name);
      foreach (var customerData in custs)
      {
        var acctno = customerData.Branch + customerData.AccountNumber;
        var acctnoname = string.Format(" {0} - {1} ", acctno, customerData.Name);
        // msg += string.Format("*** {0} - {1} ***{2}", customerData.AccountId, acctnoname, Environment.NewLine);
        list.Add(new SelectListItem() { Text = acctnoname, Value = customerData.AccountId });
      }

      if (custs.Length > 0)
      {
        model.AccountBalance = String.Format("{0:C}", Decimal.Parse(custs[0].TotalBalance));
      }

      ViewBag.Accounts = list;
      return View(model);
    }

视图的帖子调用SendPayment,这是我在视图开头的检查:

    if (model.Amount == 0)
    {    
      ModelState.AddModelError("Amount", "Invalid amount.");
      return RedirectToAction("PrePayment", model);
    }

我似乎无法从PreMayment获取我从AddModelError发送的错误。我改成了:

    if (model.Amount == 0)
    {    
      ModelState.AddModelError("Amount", "Invalid amount.");
      return View("PrePayment", model);
    }

但它从未调用控制器和屏幕错误,因为它没有预期的数据。

如何使用错误重定向回调用视图?

====其他信息====

这是我的预付款视图:

[Authorize]
public ActionResult PrePayment(PaymentModel.PrePayment model)
{
    var list = new List<SelectListItem>();
    var custs = _client.RequestCustomersForAccount(User.Identity.Name);
    foreach (var customerData in custs)
    {
      var acctno = customerData.Branch + customerData.AccountNumber;
      var acctnoname = string.Format(" {0} - {1} ", acctno, customerData.Name);
      // msg += string.Format("*** {0} - {1} ***{2}", customerData.AccountId, acctnoname, Environment.NewLine);
      list.Add(new SelectListItem() { Text = acctnoname, Value = customerData.AccountId });
    }

    if (custs.Length > 0)
    {
      var amt =String.Format("{0:C}", Decimal.Parse(custs[0].TotalBalance));
      model.AccountBalance = amt;
      decimal namt;
      if (decimal.TryParse(amt.Replace(",",string.Empty).Replace("$", string.Empty), out namt))
      {
        model.Amount = namt;
      }
    }
  ViewBag.Accounts = list;
  return View(model);
}

2 个答案:

答案 0 :(得分:2)

有几个问题需要解决。

1.  return View("PrePayment", model);  
This will not call the controller, as the function name suggests, it only passing your object to the specified "View"(.cshtml file)

2.     return RedirectToAction("PrePayment", model);  
You will not persist modelstate data, because you are doing a redirect.

建议的工作流程将解决您的问题。至少它解决了我的问题。

1. Get the form to post to "PrePayment" instead of SendPayment and you will create a new method with the following signature and have all you validation logic in the method
[Authorize]
[HttpPost]
public ActionResult PrePayment(PaymentModel.PrePayment model)

2. If everything goes well then redirect to the success/send payment page depending on your requirement

3. If somehow you need to pass model object onto the next action. Use TempData like following. This will temporarily persist the data till the next action. Then it get disposed:
TempData["payment"]=model;

答案 1 :(得分:0)

您可以在属性中添加数据注释,并使用ModelState.IsValid属性对其进行验证

[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
[Display(Name = "Payment Amount:")]
[Range(0.01, Double.MaxValue)]
public decimal Amount { get; set; }

POST方法中,检查验证是否通过,如果不是将模型发送回视图。

[HttpPost]
public ActionResult SendPayment(PrePayment model)
{
  if(ModelState.IsValid)
  {
     //do the fun stuff
  }
  return View(model);
}