【问题标题】:ASP.NET dropdownlist is empty in server button_click, the ddl is populated client sideASP.NET 下拉列表在服务器 button_click 中为空,ddl 填充客户端
【发布时间】:2015-03-31 10:06:44
【问题描述】:

我有一个表格可以更改一些地址信息。将一些generic ZIP code 放入文本框中时,会触发客户端事件以填充具有兼容城市的下拉列表。

填充是正确的,问题是无论我选择哪个值,因为当我点击按钮保存数据时,服务器函数button_click中的下拉列表有SelectedItem to null,有aso list Items count to 0..

我放了另一个下拉列表只是为了测试,里面有一些随机城市,如果我通过同一个 jquery 函数在它上面设置一个值,我可以在服务器函数中正确地看到它,所以问题似乎出在另一个是客户端填充的事实..

我见过这个:Asp.Net: Restoring client-side SelectedItem of DropDownList on server-side 和设置隐藏字段值的解决方法,但我想知道是否有更正确的方法来做到这一点..

<table>
    <tr>
        <td>
            <label>Address</label><br />
            <asp:TextBox ID="txtAddress" CssClass="testo" runat="server"></asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <label>Province</label><br />
            <asp:TextBox ID="txtProvince" runat="server" />
        </td>
        <td>
            <label>City</label><br />
            <asp:DropDownList ID="ddlCity" runat="server" />
        </td>
        <td>
            <label>ZIP</label><br />
            <asp:TextBox ID="txtZIP" />
        </td>
    </tr>
    <tr>
        <td>
            <!-- Just for test set ddl by jQuery -->
            <asp:DropDownList ID="ddlTest" runat="server" />
        </td>
    </tr>
    <tr>
        <td>
            <asp:ImageButton ID="btnSave" runat="server"
                OnClick="btnSave_Click" />
        </td>
    </tr>
</table>

$(function () {

    $(document).on('keyup', 'input[id*="txtZIP"]', function () { 
        var input = $(this);
        if (input[0].selectionStart == 5) {
            $.ajax({ 
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "CleanAddress.aspx/txtZIP_TextChanged",
                data: "{ZIP:'" + input.val() + "'}",
                dataType: "json",
                success: function (response) {
                    var cities = $.parseJSON(JSON.stringify(response.d)); 
                    if (comuni.length > 0) {
                        $("[id*=txtProvince]").val(cities[0].ID_PROVINCE);
                        $("[id*='ddlCity']").empty();
                        $.each(cities, function (key, value) {
                            $("[id*='ddlCity']").append($("<option />
").val(value.ID_CITY).text(value.CITY));
                        });
                        $("[id*='ddlCity']").removeAttr('disabled');
                        $("[id*='ddlTest']").val(9); // Just for test
                        $("[id*='ddlComuneDom']").val(cities[0].ID_CITY);
                        //alert($("[id*='ddlTest']").val());
                        //alert($("[id*='ddlCity']").val());
                        }
                    }
                },
                error: function (result) {
                    alert("Errore! " + result.status + " - " + result.statusText);
                }
            });
        }
    });

[WebMethod]
    public static List<Comuni> txtZIP_TextChanged(string ZIP)
    {
        try
        {
            List<Cities> cities = new List<Cities>();
            if ((ZIP.Trim() != "") && (ZIP.Length == 5))
            {
                dcListCitiesDataContext dc = new dcListCitiesDataContext();

                if (dc.Cities.Where(c => c.ZIP.Equals(ZIP)).Count() > 0)
                {
                    string province = dc.Cities.Where(c => c.ZIP.Equals(ZIP)).First().ID_PROVINCE.ToUpper();
                    if (province != null)
                    {
                        cities = dc.Cities.Where(c => c.ZIP.Equals(ZIP)).ToList();
                        return cities;
                    }

                }
            }
            return cities;
        }
        catch (Exception ex)
        {
            Utility.WriteLog("CleanAddress - txtZIP_TextChanged " + " - " + ex.Message, TipoLog.Error);
            throw;
        }
    }

    protected void btnSave_Click(object sender, ImageClickEventArgs e)
{
    // Here I've always ddlCity empty
    string cities= "";
    if (ddlCity.SelectedItem != null)
        cities= ddlCity.SelectedItem.ToString();
    else
        cities= ddlTest.SelectedItem.ToString();
    (...)
}

【问题讨论】:

  • 要获取当前选定的文本,你应该这样做$('#dropDownId :selected').text();
  • 我想要服务器端的值,而客户端的选择器 #idValue 无效,而是 '' 或 $("[id*='dropDownId']" )。

标签: javascript c# jquery asp.net


【解决方案1】:

在 asp webforms 中,您永远不应该在客户端添加服务器端控件。由于应用了像视图状态这样的抽象,它不能很好地工作并且可能会导致非常有趣的问题。

如果您需要以“网络表单”方式填充列表,您通常会将 dropdownv 放在更新面板中,并通过部分回发来加载它。然后你可以添加到项目中,或者在服务器端进行数据绑定来填充它。

如果您不喜欢此选项,请将其设为标准选择,并且不要尝试使用服务器端控件。当您提交表单时,您应该仍然能够获得提交的值,并且它会更干净。

【讨论】:

  • 整个页面都在一个更新面板中,您的第一个选项是它到目前为止的工作方式,但下拉菜单已重新加载,更改 ZIP 文本框或更改省文本框,反之亦然,所以即使部分所有回发导致“沉重”界面,也是因为我正在开发的 Web 应用程序显示一个带有轮子的框,可以转动每个回发,这就是我转向 jQuery 的原因。标准选择是个好主意,但我在页面中有其他部分的代码引用了该下拉列表,所以我想我要提到提到的 HiddenField 解决方法,似乎更快..
  • 我可以告诉你,如果视图状态打开,你最终会遇到异常。这真是个坏主意。使更新面板更小,以最大限度地减少每个部分回发中的传输量。它们越大,响应大小就越大。如果是整页,则不会是部分更新。
  • 我的错..我错了,我的意思不是整个页面而是整个用户控件,其中包含地址字段..
【解决方案2】:

如我所见:

Asp.Net: Restoring client-side SelectedItem of DropDownList on server-side

<asp:HiddenField ID="hdnCity" runat="server" />

ZIP 文本更改和 ddl 更改:

$("[id*='hdnCity']").val($("[id*='ddlCity'] option:selected").text());

和服务器端:

city = hdnCity.Value;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    相关资源
    最近更新 更多