Кнопка формы удаленной проверки MVC 3 не включена в данные POST - PullRequest
6 голосов
/ 17 июня 2011

У меня есть приложение ASP.NET MVC3 и с удаленной проверкой на одном из моих классов моделей.Я обнаружил, что, если я открою представление «Правка» для этой модели и вызывается процедура удаленной проверки НЕ (из-за отсутствия редактирования поля с удаленной проверкой на нем) перед отправкой формы, кнопка щелкала, чтобы ЗАПИСАТЬФорма НЕ включена в данные запроса, отправленные методу Action.

Если процедура удаленной проверки IS вызвана до отправки формы - кнопка нажата для отправки формы IS , включенной в POST.

Мне нужно знать, какая кнопка была нажата, когда действие вызывается на сервере, чтобы я мог определить, нажал ли пользователь UPDATE или CANCEL.

Если я удалю удаленную проверку из модели, форма каждый раз будет корректно отправляться.

Почему кнопка, которая использовалась для отправки формы, была исключена из публикации формы, если удаленная проверка не была вызвана до отправки формы.

спасибо Михаил

ЗдесьВот пример кода:

@model Channel
<script src="@Url.Content("~/Scripts/jquery-1.6.1.min.js")" type="text/javascript"></script>
<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>

@using (Html.BeginForm()) {
<fieldset>
    <legend>Edit Channel</legend>

    @Html.HiddenFor(model => model.ChannelGUID)


    <div class="editor-label">Name</div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>

    <div class="editor-label">Description</div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
    </div>

    <div class="editor-label">Channel Code</div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Code)
        @Html.ValidationMessageFor(model => model.Code)
    </div>

    <p>
        <button type="submit" name="updateCommand" value="Update">Update</button>
        <button type="submit" class="cancel">Cancel</button>
    </p>
</fieldset>
}

здесь есть действие

[HttpPost]
public ActionResult Edit(string updateCommand, Channel channel)
{
    if (updateCommand != null)
    {
     //update clicked
    }
    else
    {
     //cancel clicked
    }

здесь есть атрибут remote для свойства модели Code

[Remote("IsChannelCodeUnique", "Channel", AdditionalFields = "ChannelGUID", ErrorMessage = "code must be unique")]

Ответы [ 3 ]

4 голосов
/ 29 июля 2013

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

В то время как другие ответы предоставляют обходные путиЯ немного углубился в это и отвечу на фактический вопрос, который вы задали: "Почему кнопка, которая использовалась для отправки формы, была исключена из публикации формы, когда удаленная проверка не вызывается до отправки формы".

Я знал, что Javascript Submit не включает значение кнопки Submit .Поэтому я попытался разместить с отключенным JavaScriptПроверка не сработала, но ценность моей отправки была опубликована.Я предположил, что jquery.validate.js подключается и отправляет программную отправку.Это действительно так.Вот что происходит, используя jquery.validate.js 1.9.0, без сжатия:

  1. Когда страница загружена, в строке 942 средства проверки расширяются с помощью метода remote ,и в строке 735 с прототипом stopRequest .
  2. Проверка происходит, когда поле ввода теряет фокус в первый раз, когда вы вводите его после этого или когда отправляете форму.
  3. После проверки вызывается метод stopRequest .
  4. Когда щелкают по входу подтверждения, отправка каким-то образом подавляетсяв строке 56 есть оператор event.preventDefault();, но он вызывается только в режиме отладки.В любом случае, метод stopRequest будет вызываться при нажатии на отправку и после выполнения удаленной проверки.
  5. Когда форма действительна, вызывается строка 742: $(this.currentForm).submit();, чтопрограммная отправка и не будет публиковать значение отправки.Вот почему я не могу определить, какая кнопка отправки была нажата.

Внимательно изучив способ расширения проверки, я нашел в строке 59 определение обработчика, который, кажется, предназначен для преодоления некоторыхпохожая проблема: он добавляет скрытый ввод с точным названием и значением кнопки отправки, которую обрабатывает.Однако в моем случае ни validator.settings.submitHandler, ни validator.submitButton не определены, поэтому этот код никогда не вызывается.

Было бы неплохо, если бы в этом случае также было добавлено это скрытое поле, поскольку MVC не будетне важно знать, какой тип ввода отправил значение, и действие post на контроллере могло бы просто использовать это значение.

Добавление Мой обходной путь для этой проблемы - добавление обработчика к функциям щелчкаотправляет:

$('input[type="submit"]').click(function () {
    var hidden = $("<input type='hidden'/>").attr("name", this.name).val(this.value).appendTo($(this).closest("form"));
});

Скрытое поле создано, поэтому мне не нужно полагаться на скрытое поле с указанием правильного имени.Вы можете либо предоставить отправителям одинаковые имена и проверить их значение, либо дать им разные имена и проверить наличие параметра post.Конечно, вам также нужно будет использовать имя поля формы, которое еще не используется.

0 голосов
/ 12 августа 2011

Мы создали собственный ActionMethodSelectorAttribute, так что нет необходимости писать if else или переключать операторы, чтобы решить, какая кнопка была нажата.Вот пользовательский класс:

public class AcceptParameterAttribute : ActionMethodSelectorAttribute
{
    public string Name { get; set; }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        var req = controllerContext.RequestContext.HttpContext.Request;

        return req.Form[this.Name] != null;
    }
}

Этот атрибут выбирает метод, который будет выполнен, основываясь на имени кнопки, на которой была нажата кнопка.И вот использование:

[HttpPost]
[ActionName(ActionNameEditUser)]
[AcceptParameter(Name = "save")]
public ActionResult Save()
{
    // put your code here
}

[HttpPost]
[ActionName(ActionNameEditUser)]
[AcceptParameter(Name = "cancel")]
public ActionResult Cancel()
{
    // put your code here
}

Все, что осталось, чтобы назвать кнопки соответственно, и мы сделали:

<button name="save">Save</button>
<button name="cancel">Cancel</button> 
0 голосов
/ 22 июня 2011

Я обратился к замене кнопки отмены на ссылку (используя ссылку действия) и использованию пользовательского интерфейса jQuery, чтобы стилизовать ссылку и кнопку отправки в форме, чтобы они выглядели одинаково.Это позволяет избежать проблем, с которыми я столкнулся, когда нажатая кнопка не была включена в данные POST.Теперь, когда вызывается действие, мне не нужно определять нажатую кнопку, чтобы увидеть, нажал ли пользователь кнопку «Отмена».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...