DetailsView Item events (updated deleted) with same handler - asp.net

I'm using a details view in my asp.net web application.
When it fires its updated and inserted events I'd like to handle them the same way. Because the event args they have are two separate classes with no common inheritance I have to have two separate methods with basically the same code.
Is there any way around this?
eg.
protected void DetailsViewItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
if (e == null)
return;
if (e.Exception != null)
{
e.ExceptionHandled = HandleException(e.Exception);
e.KeepInInsertMode = e.ExceptionHandled;
}
}
protected void DetailsViewItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
{
if (e == null)
return;
if (e.Exception != null)
{
e.ExceptionHandled = HandleException(e.Exception);
e.KeepInEditMode = e.ExceptionHandled;
}
}
I'd like to extract
if (e == null)
return;
if (e.Exception != null)
{
e.ExceptionHandled = HandleException(e.Exception);
e.KeepInEditMode = e.ExceptionHandled;
}
into some kind of common method if possible.

I agree it is disappointing that these classes inherit directly from EventArgs. It seems logical that they would inherit from the same sublass of EventArgs given not just their common properties, but the fact that most times you use a DetailsView for inserting you also use it for updating.
That being said, what you want to do can be accomplished with a bit of dynamic C#. It's pretty cool, and maybe even a little elegant, albeit a little more overhead.
Try this: (requires C# 4.0)
protected void DetailsView1_Inserted(Object sender, DetailsViewInsertedEventArgs e)
{
ProcessDetailsViewEventArgs(e);
}
protected void DetailsView1_Updated(Object sender, DetailsViewUpdatedEventArgs e)
{
ProcessDetailsViewEventArgs(e);
}
private void ProcessDetailsViewEventArgs(dynamic e)
{
if (e == null)
return;
if (e.Exception != null)
{
e.ExceptionHandled = HandleException(e.Exception);
e.KeepInEditMode = e.ExceptionHandled;
}
}

Use the OnItemCommand, & give your Edit & Delete buttons CommandNames. This event will handle both scenarios for you.

Related

ViewState equal null asp.net

I have the next code.
protected void Page_PreRender(object sender, EventArgs e)
{
bool isDelayWarning = proxy.MerchantPaySystemSetting_IsHoldPaymentsAllow(clientID, PaySystem.Type));
ViewState.Add("IsDelayWarning", isDelayWarning);
}
protected void btnSend_Click(object sender, EventArgs e)
{
if ((bool)ViewState["IsDelayWarning"] && !cbxDelayConfirm.Checked)
{
this.CustomErrorMessage = Yandex_Term_Error;
return;
}
}
In btnSend_Click method ViewState["IsDelayWarning"] = null.
How can I resolve this trouble?
Thanks! :)
I'm not sure about the logic you're going for, but a button push happens during post-back, before the page is rendered. Put breakpoints in your two methods to see their relative order.
Pay attention to the yellow marked items, control event processing is one of them and it happens strictly before PreRender.
You can always check for null reference by doing something like this
if (something != null)
code ------
or another way if you will sometimes have null is to use. For example if user address is null
if (thisuser.Address == null)
{
thisuser.Address = new Address();
}
thisuser.Address = user.Address.City;

Data used by several usercontrols

I have a page with several different usercontrols.
All of them run the following code:
var member = System.Web.Security.Membership.GetUser();
MemberProfile mp = MemberProfile.GetUserProfile(member.UserName);
string affilID = mp.GetPropertyValue("aID").ToString();
I would like to get this value once and save it for use with all the controls.
I'm not sure where in the life cycle I need to do this to insure it is accessible to all the controls when they are being rendered.
Any suggestions?
Thank you!
Why not do it in the Page_Load event with Session? Maybe something like this (C#):
MembershipUser member;
MemberProfile mp;
string affilID;
protected void Page_Load(object sender, EventArgs e)
{
if (Session["member"] != null)
{
member = (MembershipUser)Session["member"];
}
else
{
member = System.Web.Security.Membership.GetUser();
}
if (Session["mp"] != null)
{
mp = (MemberProfile)Session["mp"];
}
else
{
mp = MemberProfile.GetUserProfile(member.UserName);
}
if (Session["affilID"] != null)
{
affilID = (string)Session["affilID"];
}
else
{
affilID = mp.GetPropertyValue("aID").ToString();
}
}
If it's all on the same page, as long as it's outside of a subroutine you should be able to use it within any subroutine. Or am I missing something?

SiteMapResolve does not fire

I am getting trouble that SiteMapResolve fires on some pages and doesn't on other.
This is my code.
protected void Page_Load(object sender, EventArgs e)
{
SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ChangeMapPath);
}
private SiteMapNode ChangeMapPath(Object sender, SiteMapResolveEventArgs e)
{
if (SiteMap.CurrentNode != null)
{
// Clone the current node and all of its relevant parents.
SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
SiteMapNode tempNode = currentNode;
if (clientId != 0 && tempNode.Title.Equals("Client Notes"))
{
tempNode.Url = tempNode.Url + EncryptQueryString("ParentId=" + clientId.ToString());
}
if (clientId != 0 && tempNode.ParentNode != null && (tempNode.ParentNode.Title.Equals("Client Contacts")))
{
tempNode.ParentNode.Url = tempNode.ParentNode.Url + EncryptQueryString("ParentId=" + clientId.ToString());
}
else if (tempNode.ParentNode != null)
tempNode.ParentNode.Url = tempNode.ParentNode.Url;
return currentNode;
}
return null;
}
Thanks.
Try replace your code
SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ChangeMapPath);
to
foreach (SiteMapProvider mapProvider in SiteMap.Providers)
{
mapProvider.SiteMapResolve += ChangeMapPath;
}
I know this is an old question, but just in case anyone else is still dealing with this issue, the following solution works for me.
It appears that there is an issue with SiteMapResolveEventHandler not ever being removed, so the first event handler that is added, will be the one that gets called after that point.
https://blogs.msdn.microsoft.com/asiatech/2012/11/29/asp-net-case-study-sitemapresolveeventhandler-memory-leakage/
So, you can do exactly as the original poster has done, but you also need to add the following to each page that adds the SiteMapResolveEventHandler.
protected void Page_UnLoad(object sender, EventArgs e)
{
SiteMap.Provider.SiteMapResolve -= new SiteMapResolveEventHandler(this.ChangeMapPath);
}
It should call the appropriate handler on each page if you have forced the removal on previous pages.
Alternatively, instead of using the Page_Unload, you could place the
SiteMap.Provider.SiteMapResolve -= new SiteMapResolveEventHandler(this.ChangeMapPath);
line of code at the beginning of the ChangeMapPath method.
What worked for me better and easier to understand / maintain:
Create an interface with a handler method:
public interface ISiteMapResolver
{
SiteMapNode SiteMapResolve(object sender, SiteMapResolveEventArgs e);
}
subscribe to each event in the Application_Start method in global.asax
foreach (SiteMapProvider siteMapProvider in SiteMap.Providers)
siteMapProvider.SiteMapResolve += Provider_SiteMapResolve;
}
Then implement this method
SiteMapNode Provider_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
{
var handler = e.Context.CurrentHandler as ISiteMapResolver;
return handler != null ? handler.SiteMapResolve(sender, e) : null;
}
This way you can implement ISiteMapResolverin each page you are interested to modify the node, e.g.
public SiteMapNode SiteMapResolve(object sender, SiteMapResolveEventArgs e)
{
if (SiteMap.CurrentNode == null) return null;
var node = SiteMap.CurrentNode.Clone(true);
node.Url += "?productId=" + ProductId; // Access page property, no problem. Page_Load event already fired.
note.Title = "Product " + Product;
// Modify node.ParentNode here if needed.
return node;
}

Set session variable in Application_BeginRequest

I'm using ASP.NET MVC and I need to set a session variable at Application_BeginRequest. The problem is that at this point the object HttpContext.Current.Session is always null.
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
//this code is never executed, current session is always null
HttpContext.Current.Session.Add("__MySessionVariable", new object());
}
}
Try AcquireRequestState in Global.asax. Session is available in this event which fires for each request:
void Application_AcquireRequestState(object sender, EventArgs e)
{
// Session is Available here
HttpContext context = HttpContext.Current;
context.Session["foo"] = "foo";
}
Valamas - Suggested Edit:
Used this with MVC 3 successfully and avoids session error.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context != null && context.Session != null)
{
context.Session["foo"] = "foo";
}
}
Maybe you could change the paradigm... Perhaps you can use another property of the HttpContext class, more specifically HttpContext.Current.Items as shown below:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
HttpContext.Current.Items["__MySessionVariable"] = new object();
}
It won't store it on the session, but it will be stored on the Items dictionary of the HttpContext class and will be available for the duration of that specific request. Since you're setting it at every request, it would really make more sense to store it into a "per session" dictionary which, incidentally, is exactly what the Items is all about. :-)
Sorry to try to infer your requirements instead of answering your question directly, but I've faced this same problem before and noticed that what I needed was not the Session at all, but the Items property instead.
You can use the session items in Application_BeginRequest this way:
protected void Application_BeginRequest(object sender, EventArgs e)
{
//Note everything hardcoded, for simplicity!
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get("LanguagePref");
if (cookie == null)
return;
string language = cookie["LanguagePref"];
if (language.Length<2)
return;
language = language.Substring(0, 2).ToLower();
HttpContext.Current.Items["__SessionLang"] = language;
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(language);
}
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context != null && context.Session != null)
{
context.Session["Lang"] = HttpContext.Current.Items["__SessionLang"];
}
}

Textbox value null when trying to access it

namespace Dynamic_Controls.Dropdowndynamic
{
public partial class DropdowndynamicUserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (ControlCount != 0)
{
Recreatecontrols();
}
}
private void Recreatecontrols()
{
// createtextboxes(ControlCount);
createtextboxes(2);
}
protected void createtextboxes(int ControlCount)
{
DynPanel.Visible = true;
for (int i = 0; i <= ControlCount; i++)
{
TextBox tb = new TextBox();
tb.Width = 150;
tb.Height = 18;
tb.TextMode = TextBoxMode.SingleLine;
tb.ID = "TextBoxID" + this.DynPanel.Controls.Count;
tb.Text = "EnterTitle" + this.DynPanel.Controls.Count;
tb.Load+=new EventHandler(tb_Load);
tb.Visible = true;
tb.EnableViewState = true;
DynPanel.Controls.Add(tb);
DynPanel.Controls.Add(new LiteralControl("<br/>"));
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Int32 newControlCount = Int32.Parse(DropDownList1.SelectedValue);
//createtextboxes(newControlCount);
//ControlCount+=newControlCount;
createtextboxes(2);
}
protected void Button1_Click(object sender, EventArgs e)
{
readtextboxes();
}
public void readtextboxes()
{
string x = string.Empty;
for (int a = 0; a < DynPanel.Controls.Count; a++)
{
foreach (Control ctrl in DynPanel.Controls)
{
if (ctrl is TextBox)
{
x = ((TextBox)ctrl).Text;
}
x+=x+("\n");
}
Result.Text = x;
}
}
private Int32 ControlCount
{
get
{
if (ViewState["ControlCount"] == null)
{
ViewState["ControlCount"] = 0;
}
return (Int32)ViewState["ControlCount"];
}
set
{
// ViewState["ControlCount"] = value;
ViewState["ControlCount"] = 2;
}
}
private void tb_Load(object sender, EventArgs e)
{
LblInfo.Text = ((TextBox)sender).ID + "entered";
}
}
}
Are you adding these controls dynamically in Page_Load (by, I'm assuming, calling your AddRequiredControl() method)? If so, is it wrapped in a conditional which checks for IsPostBack? The likely culprit is that you're destructively re-populating the page with controls before you get to the button click handler, so all the controls would be present but empty (as in an initial load of the page).
Also, just a note, if you're storing each control in _txt in your loop, why not refer to that variable instead of re-casting on each line. The code in your loop seems to be doing a lot of work for little return.
You need to recreate any dynamically created controls on or before Page_Load or they won't contain postback data.
I'm not entirely clear what happens on DropdownList changed - are you trying to preserve anything that has been entered already based on the textboxes previously generated?
In any event (no pun intended) you need to recreate exactly the same textboxes in or before Page_Load that were there present on the postback, or there won't be data.
A typical way to do this is save something in ViewState that your code can use to figure out what to recreate - e.g. the previous value of the DropDownList. Override LoadViewState and call the creation code there in order to capture the needed value, create the textboxes, then in the DropDownList change event, remove any controls that may have been created in LoadViewState (after of course dealing with their data) and recreate them based on the new value.
edit - i can't figure out how your code works now, you have AddRequiredControl with parameters but you call it with none. Let's assume you have a function AddRequiredControls that creates all textboxes for a given DropDownList1 value, and has this signature:
void AddRequiredControls(int index)
Let's also assume you have a PlaceHolder called ControlsPlaceholder that will contain the textboxes. Here's some pseudocode:
override void LoadViewState(..) {
base.LoadViewState(..);
if (ViewState["oldDropDownIndex"]!=null) {
AddRequiredControls((int)ViewState["oldDropDownIndex"]);
}
}
override OnLoad(EventArgs e)
{
// process data from textboxes
}
void DropDownList1_SelectedIndexChanged(..) {
ControlsPlaceholder.Controls.Clear();
AddRequiredControls(DropDownList1.SelectedIndex);
ViewState["oldDropDownIndex"]=DropDownList1.SelectedIndex;
}

Resources