私はGridView
内側に内側UpdatePanel
を持っていModalPopup
ます。ユーザーがシステム内の役割を変更したい場合にこれを使用しています。彼らはリストから新しいロールを選択し (これUpdatePanel
により、選択が行われたときにページが更新されなくなります)、[OK] を押します。Ok ボタンのイベントOnClick
が発生し、 を使用してと一致させます。は、変更されたユーザー データを収集して新しい Cookie を作成するために使用されます (これは です)。古い Cookie が削除され、リセットされ、新しい Cookie が追加されます。その後、ページが更新されます ( で強制)。GridView
SelectedIndex
DataRow
DataRow
FormsAuthentication
GenericPrinciple
Response.Redirect()
問題は、OK ボタン (ポップアップの として設定されていない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
andPage_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
、UpdatePanel
選択後に [OK] をクリックすると、ページを更新するまで選択を変更できないことに気付きました。変更を待ってみましたが、何も起こりません。
更新 2
私は何か他のものを試すことにしました。と を削除しましUpdatePanel
たbtnOk
。SelectedIndexChanged
のイベント ハンドラを追加し、のコード sans checkgvRole
をコピーしました。これはうまくいきました。アイテムをクリックすると、ページが更新され、ロールが即座に変更されます。ただし、この質問は開いたままにします。これがうまくいかなかった理由と、今後どのように解決できるかを知りたいです。btnOk
SelectedIndex > -1