Аргумент всегда нулевой при использовании RemoteAttribute - PullRequest
0 голосов
/ 04 ноября 2011

Я пытаюсь выполнить свою первую удаленную проверку в MVC, которую я не могу заставить работать, поскольку аргумент, который получает мое действие проверки, всегда равен нулю.

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

}

Моя проблема в том, что мой аргумент strDate в IsValidDate (строка strDate) всегда нулевой.Судя по всему, моя проверка работает нормально, и если я вынуждаю ее завершиться с ошибкой, она также возвращает правильное сообщение об ошибке в правильное поле.

Я не могу понять, почему strDate всегда имеет значение null.Это потому, что он находится в BookModel и поэтому называется «Book.ReleaseDate»?

1 Ответ

1 голос
/ 05 ноября 2011

Хорошо, вот хак, который работает для меня в этом случае.Сначала я должен признать, что я не знал, что аргумент в 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, я просматриваю все ключи QueryString, чтобы увидеть, есть ли аргумент, заканчивающийся желаемым именем поля, и затем заполняю свой аргумент этим значением.

Это привело меня к другому решению (которое ТОЛЬКОработает здесь, потому что я знаю, что у меня нет дополнительных полей, которые заканчиваются тем же именем поля (или я должен сказать - частично имя поля).Говоря, что я хочу посмотреть только на частично ключевое имя «date» (вместо «releaseate»), я могу заставить этот валидатор проверять все мои поля даты в представлении.Но, как уже упоминалось: это работает только потому, что я не хочу дополнительные поля в моей удаленной проверки.Если бы я захотел сравнить, например, «StartDate» с «ReleaseDate», у меня возникли бы проблемы: -)

Я также переместил свое ErrorMessage в свои DataAnnotations, чтобы у меня могли быть разные сообщения об ошибках в полях.

Это не приятно - но это работает!

...