使用RemoteAttribute时,参数始终为null

时间:2011-11-04 18:09:50

标签: model-view-controller data-annotations

我正在尝试在MVC中进行第一次远程验证,因为我的验证操作收到的参数始终为null,所以我无法工作。

public class Book
{
  [Remote("IsValidDate", "Validation")]
  public DateTime ReleaseDate { get; set; }
}

然后我在Book类之外需要一些其他的值,因此我还创建了一个BookModel:

public class BookModel
{
  public Book Book;
  public string SomeOtherValueNotInterestingInThisExample;
  public BookModel(Book book)
  {
    Book = book;
    // other stuff
  }
}

然后我的编辑页面包含:

...
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
.... and later
<div class="editor-label">
    @Html.LabelFor(model => model.Book.ReleaseDate)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Book.ReleaseDate)
    @Html.ValidationMessageFor(model => model.Book.ReleaseDate)
</div>

我的ValidationController看起来像这样:

public class ValidationController : Controller
{
    public JsonResult IsValidDate(string strDate)
    {
        bool isValid = DateHelper.IsValid(strDate);
        if (isValid)
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json("(remote - not valid)", JsonRequestBehavior.AllowGet);
        }
    }

}

我的问题是,我在IsValidDate(字符串strDate)中的strDate参数始终为null。从我的验证工作正常,如果我强制它失败,它也会将正确的错误消息返回到正确的字段。

我无法弄清楚为什么strDate总是为空。是因为它在BookModel中,因而被称为“Book.ReleaseDate”?

1 个答案:

答案 0 :(得分:1)

好的,在这种情况下,这是一个适用于我的黑客攻击。首先,我必须承认我不知道IsValidDate中的参数必须与我想要验证的字段相同。我现在知道了。

以下是更改后的代码:

public class ValidationController : Controller
{
    public JsonResult IsValidDate(string date)
    {
        if (date == null)
            date = GetQueryStringValue("date");

        bool isValid = DateHelper.IsValid(date);
        if (isValid)
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(false, JsonRequestBehavior.AllowGet);
        }
    }

    private string GetQueryStringValue(string key)
    {
        return (from qStr in Request.QueryString.AllKeys
                where qStr.ToLower().EndsWith(key.ToLower())
                select Request.QueryString.Get(qStr)).FirstOrDefault();
    }
}

请注意,我已经创建了一个单独的GetQueryStringValue,因此其他验证器可以使用相同的方法。

My Book课程现在看起来像这样(这里只提到有问题的字段):

public class Book
{
  [Remote("IsValidDate", "Validation", ErrorMessage = "Release date is not valid")]
  public DateTime ReleaseDate { get; set; }


  [Remote("IsValidDate", "Validation", ErrorMessage = "Start date is not valid")]
  public DateTime StartDate { get; set; }
}

对解决方案的评论:基本上我开始检查IsValidDate中的参数是否为null。如果它为null,我将遍历所有QueryString键,看看是否有一个以我想要的字段名结尾的参数,然后用该值填充我的参数。

这导致了我的另一个解决方案(它只能在这里工作,因为我知道我没有其他字段以相同的字段名称结尾 - 或者我应该说 - 部分字段名称)。通过说我只想查看部分关键名称“date”(而不是“releaseate”),我可以让这个验证器检查View中的所有日期字段。但正如所提到的:它只能起作用,因为我不想在远程验证中添加其他字段。如果我想比较,例如带有“ReleaseDate”的“StartDate”我会遇到问题: - )

我还将我的ErrorMessage移动到了DataAnnotations,因此我可以在字段上使用不同的错误消息。

这不好 - 但它有效!