我有一个GridView
里面一个UpdatePanel
里面一个ModalPopup
。当用户想要更改系统中的角色时,我使用它。他们从列表中选择一个新角色(UpdatePanel
在进行选择时防止页面刷新)并按“确定”。Ok 按钮的OnClick
事件触发并使用GridView
'sSelectedIndex
与DataRow
. DataRow
用于收集更改的用户数据以创建新的 cookie (This is ) FormsAuthentication
。旧的 cookie 被删除,GenericPrinciple
被重置,新的 cookie 被添加。然后页面刷新(用 强制Response.Redirect()
)。
问题是当 Ok 按钮(未设置为 Popup 的OkControlID
)在 之外时UpdatePanel
,SelectedIndex
检索到的为 -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" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel"
Width="60px" />
</div>
</div>
</asp:Panel>
这是OnClick
和Page_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
添加为AsyncPostBackTrigger
forUpdatePanel
并且您在选择后点击确定,则在刷新页面之前您无法更改选择。我试过等待改变,但没有任何反应。
更新 2
我决定尝试别的东西。我删除了UpdatePanel
and btnOk
。我添加了一个SelectedIndexChanged
事件处理程序gvRole
并复制了btnOk
没有检查的代码SelectedIndex > -1
。这行得通。当我单击一个项目时,页面会刷新并且角色会立即更改。不过,我将这个问题悬而未决。我仍然想知道为什么这不起作用以及将来如何解决它。