我在GridView
内的UpdatePanel
内有一个ModalPopup
。当用户想要更改系统中的角色时,我正在使用它。他们从列表中选择一个新角色(UpdatePanel
阻止页面在进行选择时刷新)并按“确定”。 Ok按钮的OnClick
事件触发并使用GridView
的{{1}}与SelectedIndex
匹配。 DataRow
用于收集已更改的用户数据以创建新Cookie(这是DataRow
)。删除旧Cookie,重置FormsAuthentication
,然后添加新Cookie。然后页面刷新(强制使用GenericPrinciple
)。
问题是当Ok按钮(未设置为Popup的Response.Redirect()
)超出OkControlID
时,检索到的UpdatePanel
为-1。当按钮位于SelectedIndex
内或设置为异步触发时,没有任何反应。
以下是弹出窗口的.aspx代码:
UpdatePanel
这是<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
事件的代码隐藏:
GetRolesTableAdapter roleAdapter = new GetRolesTableAdapter();
Page_Load
我注意到,如果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());
}
}
添加为btnOk
作为AsyncPostBackTrigger
,并且您在选择后点击了确定,则在刷新页面之前无法更改选择。我试过等待改变但没有任何反应。
我决定尝试别的东西。我删除了UpdatePanel
和UpdatePanel
。我为btnOk
添加了SelectedIndexChanged
事件处理程序,并复制了gvRole
的代码btnOk
检查。这很有效。单击某个项目时,页面将刷新,角色会立即更改。不过,我打开这个问题了。我仍然想知道为什么这不起作用以及我将来如何解决它。