__DoPostback отправляет обратно значения отключенных элементов управления при частичной обратной передаче - PullRequest
6 голосов
/ 17 сентября 2009

У меня есть форма, которая ради изоляции проблемы содержит около десятка простых HTML-флажков (не WebControls), все из которых отключены . Они внутри UpdatePanel.

У меня есть ссылка, которая звонит

__doPostBack('a-control','my-custom-argument');

В зависимости от первого аргумента, который я предоставляю, страница может заполнять postback или частично.

Когда я делаю полный postback, ни одно из значений флажков не отправляется в сообщении (потому что они отключены). Это нормальное и, следовательно, желаемое поведение.

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

Это раздражает, и я хотел бы, чтобы он вел себя последовательно. Можно ли в любом случае сказать, что обработчик .NET javascript будет работать так, как работает весь остальной мир, и не postback значения отключенных элементов HTML-формы?

Ответы [ 3 ]

3 голосов
/ 17 сентября 2009

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

Вот моя полная тестовая страница:

<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" EnableViewState="false" EnableEventValidation="false" Trace="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Test disabled checkboxes</title>
    <script>
    initState = false;
    function disableCheckboxes(disabled) {
        document.getElementById('foo').disabled = disabled;
    }
    </script>
</head>
<body>
<form id="form1" runat="server">
    <asp:ScriptManager runat="server" />

    <asp:UpdatePanel runat="server">
        <ContentTemplate>
            <input runat="server" type="checkbox" id="foo" name="foo" checked="checked" /> Foo
            <asp:Button ID="Inside" runat="server" Text="Submit Inside UpdatePanel" />
        </ContentTemplate>
    </asp:UpdatePanel>

    <asp:Button ID="Outside" runat="server" Text="Submit Outside UpdatePanel" />
    <br />
    <button type="button" onclick="disableCheckboxes(initState=!initState)">Toggle checkboxes</button>
</form>
</body>
</html>

Шаги для воспроизведения:

  1. Откройте Fiddler и тестовую страницу.
  2. Нажмите «Отправить вне UpdatePanel» (запускает нормальную обратную передачу). Обратите внимание, что в Fiddler значение "foo=on" передается в теле сообщения POST.
  3. Нажмите «Переключить флажки», чтобы отключить флажок.
  4. Снова нажмите «Отправить снаружи UpdatePanel». Обратите внимание, что параметр "foo" опущен в теле POST. Это ожидается.
  5. Нажмите «Отправить внутри UpdatePanel» (запускает частичную обратную передачу). Обратите внимание, что значение "foo=on" присутствует в теле POST, даже если оно должно быть опущено

Ошибка, по-видимому, в MicrosoftAjaxWebForms.js и MicrosoftMvcAjax.js.debug аналогах каждого):

if ((type === 'text') ||
    (type === 'password') ||
    (type === 'hidden') ||
    (((type === 'checkbox') || (type === 'radio')) && element.checked)) {
        formBody.append(encodeURIComponent(name));
        formBody.append('=');
        formBody.append(encodeURIComponent(element.value));
        formBody.append('&');
}

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

2 голосов
/ 17 сентября 2009

Я могу предложить два варианта:

1) Вы можете удалить атрибут name отключенных элементов управления с помощью JavaScript непосредственно перед выполнением обратной передачи.

2) Переопределить Sys.WebForms.PageRequestManager.getInstance()._onFormSubmit исправленной версией кода. Просто скопируйте реализацию из MicrosoftAjaxWebForms.debug.js, добавьте обработку для атрибута disabled и присоедините исправленную функцию к существующему объекту PageRequestManager:

Sys.WebForms.PageRequestManager.getInstance () ._ onFormSubmit = function ...

Затем зарегистрируйте этот блок JS в качестве сценария запуска. Важно получить правильный порядок визуализации блоков скриптов. Я делаю аналогичную вещь в моем подклассе ScriptManager:

protected override void OnResolveScriptReference(ScriptReferenceEventArgs e) {
    base.OnResolveScriptReference(e);

    if (e.Script.Name.StartsWith("MicrosoftAjax"))
        Page.ClientScript.RegisterStartupScript(GetType(), "My patch", MyPatchJs, true);
}

Работает как шарм!

2 голосов
/ 17 сентября 2009

В .Net тег формы имеет атрибут submitdisabledcontrols, который по умолчанию равен false. Вы можете по крайней мере заставить вещи вести себя последовательно, если вы установите его в значение true.

...