0

我有一个GridView里面一个UpdatePanel里面一个ModalPopup。当用户想要更改系统中的角色时,我使用它。他们从列表中选择一个新角色(UpdatePanel在进行选择时防止页面刷新)并按“确定”。Ok 按钮的OnClick事件触发并使用GridView'sSelectedIndexDataRow. DataRow用于收集更改的用户数据以创建新的 cookie (This is ) FormsAuthentication。旧的 cookie 被删除,GenericPrinciple被重置,新的 cookie 被添加。然后页面刷新(用 强制Response.Redirect())。

问题是当 Ok 按钮(未设置为 Popup 的OkControlID)在 之外时UpdatePanelSelectedIndex检索到的为 -1。当按钮在内部UpdatePanel或设置为异步触发器时,什么也不会发生。

这是弹出窗口的 .aspx 代码:

<ajaxToolkit:ModalPopupExtender ID="mpeRole" runat="server" 
    TargetControlID="btnRole" CancelControlID="btnCancel" 
    PopupControlID="pnlRole" BackgroundCssClass="modalBackground">
</ajaxToolkit:ModalPopupExtender>
<asp:Panel ID="pnlRole" runat="server" style="width: 350px" CssClass="popup">
    <div>
        <asp:UpdatePanel runat="server">
            <ContentTemplate>
                <asp:GridView ID="gvRole" runat="server" 
                    AutoGenerateColumns="false" Width="300px">
                    <Columns>
                        <asp:TemplateField HeaderText="Select a role">
                            <ItemTemplate>
                                <asp:LinkButton runat="server"
                                    Text="<%# Container.DataItem %>" 
                                    CommandName="Select" />
                            </ItemTemplate>
                            <HeaderStyle Font-Size="Medium" />
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
            </ContentTemplate>
        </asp:UpdatePanel>
        <br />
        <div>
            <asp:Button ID="btnOk" runat="server" Text="OK" Width="60px" 
                onclick="btnOk_Click" />
            &nbsp;
            <asp:Button ID="btnCancel" runat="server" Text="Cancel"
                Width="60px" />
        </div>
    </div>
</asp:Panel>

这是OnClickPage_Load事件的代码隐藏: GetRolesTableAdapter roleAdapter = new GetRolesTableAdapter();

protected void Page_Load(object sender, EventArgs e)
{
    DataTable dt;
    DataRow dr;

    /* nameAdapter */
    if (!Page.IsPostBack)
    {
        // Set lblName
        try
        {
            AppUser_NameTableAdapter nameAdapter = new AppUser_NameTableAdapter();
            dt = nameAdapter.GetData(uState.id);
            dr = dt.Rows[0];

            lblName.Text = dr.Field<string>("FirstName") + " " + dr.Field<string>("MiddleName") + " " + dr.Field<string>("LastName");
        }
        catch
        {
            Response.Write(uState.id.ToString());
        }
    }

    // Set lblDate
    lblDate.Text = DateTime.Now.ToLongDateString() + " | " + DateTime.Now.ToShortTimeString();

    /* roleAdapter */
    // Set lblRole and lvRole
    dt = roleAdapter.GetData(uState.id);
    string[] arr = new string[dt.Rows.Count];

    for (int i = 0; i < dt.Rows.Count; i++)
    {
        dr = dt.Rows[i];
        string[] tmp = new string[] { 
            dr.Field<string>("ProgModel"), 
            dr.Field<string>("Site"), 
            dr.Field<string>("Team"), 
            dr.Field<string>("Position"), 
            dr.Field<string>("Role") };
        arr[i] = string.Join(" - ", tmp.Where(s => !string.IsNullOrEmpty(s)).ToArray());
        if (uState.roleVal == dr.Field<byte>("RoleID") && uState.userPos == dr.Field<int?>("UserPosID"))
        {
            lblRole.Text = arr[i];
        }
    }

    gvRole.DataSource = arr;
    gvRole.DataBind();
    gvRole.SelectedIndex = -1;

    // Display btnRole if there is more than one role for the user
    if (dt.Rows.Count > 1)
        btnRole.Visible = Visible;
}
protected void btnOk_Click(object sender, EventArgs e)
{
    // Ensure a row was selected
    if (gvRole.SelectedIndex != -1)
    {
        try
        {
            // Get data for login
            DataTable dt = roleAdapter.GetData(uState.id);
            DataRow dr = dt.Rows[gvRole.SelectedIndex];

            UserState newState = new UserState();
            newState.id = uState.id;
            newState.role = dr.Field<string>("Role");
            newState.roleVal = dr.Field<byte>("RoleID");
            newState.position = dr.Field<int?>("PositionID");
            newState.programModel = dr.Field<int?>("ProgModelID");
            newState.site = dr.Field<int?>("SiteID");
            newState.team = dr.Field<int?>("TeamID");
            newState.userPos = dr.Field<int?>("UserPosID");

            // Get old ticket
            HttpCookie oldCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
            FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(oldCookie.Value);

            // Create a new ticket used for authentication
            var newTicket = new FormsAuthenticationTicket(
                1, // Ticket version
                oldTicket.Name.ToString(), // Username associated with ticket
                DateTime.Now, // DateTime issued
                DateTime.Now.AddMinutes(60), // DateTime for expiration
                true, // "true" for persistent user cookie
                newState.ToString(), // Userdata,
                FormsAuthentication.FormsCookiePath);

            // Encrypt the cookie using the machine key for secure transport
            string hash = FormsAuthentication.Encrypt(newTicket);
            HttpCookie cookie = new HttpCookie(
                FormsAuthentication.FormsCookieName, // Name of auth cookie
                hash); // Hashed ticket

            // Set the cookie's expiration time to the ticket's expiration time
            if (newTicket.IsPersistent) cookie.Expires = newTicket.Expiration;

            // Remove old cookie and principle
            HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

            // Add the cookie to the list for outgoing response
            Response.Cookies.Remove(oldCookie.Name);
            Response.Cookies.Add(cookie);

            // Refresh page
            Response.Redirect("~/foo.aspx", true);
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message.ToString().Trim());
            Response.Write(ex.StackTrace.ToString().Trim());
        }
    }
    else
    {
        Response.Write(gvRole.SelectedIndex.ToString());
    }
}

更新 1

我注意到如果btnOk添加为AsyncPostBackTriggerforUpdatePanel并且您在选择后点击确定,则在刷新页面之前您无法更改选择。我试过等待改变,但没有任何反应。

更新 2

我决定尝试别的东西。我删除了UpdatePaneland btnOk。我添加了一个SelectedIndexChanged事件处理程序gvRole并复制了btnOk没有检查的代码SelectedIndex > -1。这行得通。当我单击一个项目时,页面会刷新并且角色会立即更改。不过,我将这个问题悬而未决。我仍然想知道为什么这不起作用以及将来如何解决它。

4

0 回答 0