Open link in a new window in ajax panel on server side - asp.net

I have asked this question before, but got no answer that worked.
This is a buttonclick event that should initiate the download:
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
SendFileDownload(file);
}
One of the solutions that was offered was opening a link in a new window and have the window on page load initiate the download there with this piece of code:
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
// SendFileDownload(file); dont call it here , call it in the other window
string url = "PopupFileDownload.aspx?file="+file;
string s = "window.open('" + url + "', 'popup_window', 'width=300,height=100,left=100,top=100,resizable=yes');";
ClientScript.RegisterStartupScript(this.GetType(), "script", s, true);
}
This did not work. I tried doing something similar since I am using the Telerik Ajax Panel
ajaxPanel.ResponseScripts.Add("window.open('DownLoadPopup.aspx?file='" + file + "'', 'popup_window', 'width=300,height=100,left=100,top=100,resizable=yes');");
But this also did not work. the command was executed with no effect.
How can I send a file to the user without sacrificing the Ajax panel?

If your button's inside an ASP.NET Ajax UpdatePanel you could turn off the ajax for just the download button
ScriptManager.RegisterPostBackControl(btnDownload);

If you're using Telerik Ajax controls, you can use the following code to pop up a RadWindow.
Make sure you've got a RadScriptManager and a RadAjaxManager on your page before your RadAjaxPanel...
Then add a RadWindowManager inside your RadAjaxPanel like this...
<telerik:RadWindowManager runat="server" ID="rwm" Modal="true" Skin="Default" AutoSize="true" />
Then in your code, you can do this...
protected void btnDownload_Command1(object sender, CommandEventArgs e)
{
GridDataItem item = gvClients.Items[Convert.ToInt32(e.CommandArgument)];
GetUserData usr = new GetUserData(item["id"].Text, Security.level.Agent, servermap);
string file = usr.RetrieveContractPath();
rwm.Windows.Clear();
var rWin = new RadWindow();
rWin.ID = "Name of my window";
rWin.NavigateUrl = string.Format("~/DownLoadPopup.aspx?file={0}", file);
rWin.Width = Unit.Pixel(1000);
rWin.Height = Unit.Pixel(600);
rWin.VisibleOnPageLoad = true;
rwm.Windows.Add(rWin);
}
Adjust the path to your DownLoadPopup.aspx and the properties of the RadWindow as necessary.

Related

ASP.NET UserControl get property in inline code

I have a user control, in the page load of the control I am doing this :
if (ViewState["Lib"] != null)
{
cfg.Lib = (string)ViewState["Lib"];
}
This Lib property can be modified with a textbox like this :
protected void Lib_e_Changed(object sender, EventArgs e)
{
cfg.Lib = Lib_e.Text;
ViewState["Lib"] = Lib_e.Text;
}
I have written the following javascript in my ascx file :
alert('<%= cfg.Lib %>');
It will always return the default value even if I have changed the text in my textbox. My textbox is in an update panel and I have set AutoPostBack to true. Is there something I am missing to update my value ?
It is happening because aspx page render
alert('<%= cfg.Lib %>');
before any assign you are performing on
cfg.Lib
to make it workable what you can do is .. register the script from server side like
protected void Lib_e_Changed(object sender, EventArgs e)
{
cfg.Lib = Lib_e.Text;
ViewState["Lib"] = Lib_e.Text;
ScriptManager.RegisterStartupScript(updatePanelId, updatePanelId.GetType(), "AnyKey", "alert('" + cfg.Lib + "')", true);
//ScriptManager.RegisterStartupScript(this, this.GetType(), "AnyKey", "alert('" + cfg.Lib + "')", true);
//Page.ClientScript.RegisterStartupScript(this.GetType(),"AnyKey","alert('"+cfg.Lib +"')",true);
}

asp.net textbox not updated from another task

I have a GridView and on its SelectedIndexChanged the code is fired:
protected void grdEntry_SelectedIndexChanged(object sender, EventArgs e)
{
lblAssignId.Text = grdEntry.SelectedRow.Cells[1].Text == " "
? ""
: grdEntry.SelectedRow.Cells[1].Text;
Ob.BranchId = Globals.BranchID;
Ob.AssignId = lblAssignId.Text;
DataSet dsMain = GetAssignDetails(Ob);
if (dsMain.Tables[0].Rows.Count != 0)
{
// some other code
Task.Factory.StartNew(() => FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId));
}
}
and the code for filling membership id is
private void FillMemberShipAndBarCode(string customerCode, string branchId)
{
var sqlCommand = new SqlCommand
{
CommandText = "sp_customermaster",
CommandType = CommandType.StoredProcedure
};
sqlCommand.Parameters.AddWithValue("#CustomerCode", customerCode);
sqlCommand.Parameters.AddWithValue("#BranchId", branchId);
sqlCommand.Parameters.AddWithValue("#Flag", 18);
var data = PrjClass.GetData(sqlCommand);
txtMemberShip.Text = data.Tables[0].Rows[0]["MembershipId"].ToString();
txtBarCode.Text = data.Tables[0].Rows[0]["Barcode"].ToString();
}
It's working fine, but is is not updating any of the textboxes. Also, I checked in watch window, the values are returned as expected (M-1213 and 634-98-4 ) and the code does reaches the point txtMemberShip.Text = data.Tables[0].Rows[0]["MembershipId"].ToString();
but the txtMemberShip just remains empty??? Can anyone tell me why is not updating the textboxes?
UPDATE
As per comments, here is the page load
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindDropDown();
BindGrid();
SetDefaultsInTextBoxes();
}
}
And I don't have any code that waits on this task.
Don't do this:
Task.Factory.StartNew(() => FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId));
What are you trying to achieve by doing so?
What is probably happening is your method FillMemberShipAndBarCode is probably running after ASP.NET has already sent the page back to the browser. Thus, essentially, no visible effect on the rendered HTML.
ASP.NET isn't a good place to do multi-threaded stuff.
Try just replacing the above with this:
FillMemberShipAndBarCode(dsMain.Tables[0].Rows[0]["CustomerCode"].ToString(), Ob.BranchId);

AjaxControlToolkit AsyncFileUpload - how to modify a label text value in UploadedComplete event

I am trying to set a label text value after a file is uploaded to the server using a AsyncFileUpload component in AjaxControlToolkit. But it seams it is ineffective, although the file uploader is green after the upload, and the upload works.
protected void AsyncFileUpload1_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
string filename = System.IO.Path.GetFileName(AsyncFileUpload1.FileName);
AsyncFileUpload1.SaveAs(Server.MapPath("Uploads/") + filename);
sourceLabel.Text="saved to "+filename; //this has no effect. I assume this is because the event is Async, but how can I set the value of sourceLabel?
}
The AsyncFileUpload control uses hidden frame for file submitting so all updates of controls will be lost. Check this link and draw attention how the uploadResult label's text changed from AsyncFileUpload1_UploadedComplete method: Ajax Control Toolkit source code
It works for me: https://stackoverflow.com/a/12472235/2247978
.....................................................................................................
Add HiddenField control onto a form:
<asp:HiddenField runat="server" ID="UploadedPathHiddenField" />
Rewrite UploadComplete method as below:
protected void UploadComplete(object sender, AsyncFileUploadEventArgs e)
{
var fileName = GeneratePrefixFileName() + System.IO.Path.GetFileName(e.FileName);
var relativePath = "~/Image/" + fileName;
var filePath = Server.MapPath(relativePath);
AsyncFileUpload1.SaveAs(filePath);
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "filePath", "top.$get(\"" + UploadedPathHiddenField.ClientID + "\").value = '" + ResolveClientUrl(relativePath) + "';", true);
}
After that you can get path of saved image in showConfirmation method by :
var src = $get("<%= UploadedPathHiddenField.ClientID %>").value;
.....................................................................................................
protected void BtnUpload_Click(object sender, EventArgs e)
{
UploadMessage.Text = UploadedPathHiddenField.Value;
}

Fire server event from client

I am having trouble with the Asp.net page life cycle. I am trying to create a custom menu using HtmlTextWriter with an asp.net LinkButton to fire a server event. I can not get the server event to fire and I get the 'object reference not set to instance of object' when I click my linkbutton. Here is some code.
protected string CreateModuleMenu()
{
var modules = ModuleManager.GetModulesByDeveloperId(Developer.DeveloperID);
StringWriter sw = new StringWriter();
ClientScriptManager cs = Page.ClientScript;
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
foreach (var module in modules)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.RenderBeginTag(HtmlTextWriterTag.Dl);
writer.RenderBeginTag(HtmlTextWriterTag.Dt);
writer.Write(module.Name);
var files = ModuleManager.GetModuleFilesByModuleId(module.ModuleID);
foreach (var file in files)
{
writer.RenderBeginTag(HtmlTextWriterTag.Dd);
LinkButton lb = new LinkButton();
lb.ID = "mc" + file.ModuleFileID;
lb.Attributes.Add("onclick", cs.GetPostBackEventReference(lb, "LoadControl_Clk"));
lb.Text = file.Name;
Page.RegisterRequiresRaiseEvent(lb);
lb.RenderControl(writer);
writer.RenderEndTag();
}
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
}
return sw.ToString();
Here is my click event:
protected void LoadControl_Clk(object sender, EventArgs e)
{
Response.Write("Hello World");
}
Finally here is what I have in the Page_Load event. Note: I tried moving this around to PreRender, PreInt, etc.
protected void Page_Load(object sender, EventArgs e)
{
LiteralControl lit = new LiteralControl();
lit.Text = CreateModuleMenu();
phModuleMenu.Controls.Add(lit);
if (DefaultModuleFile == null)
Response.Write("Error.");
else
{
Control ctrl = LoadControl(DefaultModuleFile.Src);
phAdminModules.Controls.Add(ctrl);
}
}
Lost. Thanks.
Perhaps you need to only load the control in Page_Load on the first time the page is called, that is, if !IsPostBack.
If you load the control on every page load, you will lose the event being fired.

Dynamically Loaded ListButton's and PostBack Event

I am trying to get a dynamically loaded LinkButton to fire a postback event, which I then handle.
I have across Command, CommandName and CommandArgument - which looked real useful.. So I started messing with that, but currently cannot get to work as desired.
The links are rendered within a table that is created on the fly, here is the code to generate them:
// The links are stored in Session since I was told that the objects need to remain intact across requests.
LinkButton GetEditCardLink(string card)
{
if (!IsPostBack)
{
TW("Creating Link for Card '" + card + "' and Placing in Session.", true);
LinkButton link = CreateEditLink(card);
Business.Session.Set<LinkButton>("LinkedCards_EditLink_" + card, link);
}
return Business.Session.Get<LinkButton>("LinkedCards_EditLink_" + card);
}
// Here the link itself is created, note the ID and Command details are set.
LinkButton CreateEditLink(string forCard)
{
TW("Setting Up Link for Card: " + forCard, true);
LinkButton rtn = new LinkButton();
rtn.ID = "Edit_" + forCard;
rtn.Text = Resources.Header("EditDetails");
rtn.CommandName = "Edit";
rtn.CommandArgument = forCard;
rtn.Command += new CommandEventHandler(RedirectToEdit);
rtn.Attributes["style"] = "display: block; text-align:center;";
return rtn;
}
// ... And the delegate I want called on PostBack..
void RedirectToEdit(object sender, CommandEventArgs e)
{
TW("RedirectToEdit Called:\r\nName: " + e.CommandName + "\r\nArgument: " + e.CommandArgument);
}
Trace confirms that the LinkButtons are being loaded correctly, and are only being creating once, so in theory they should be fine, but when I click the link, a PostBack is performed, but the RedirectToEdit method is not called?
All help gratefully received! :)
NOTE
Oh, I thought I should mention TW is just a utility method for Trace.Write/Warn :)
When you create a control that needs event handling you have to do it early enough in the processing that the event handler gets hooked up. Override OnInit for the page where you are creating the table and move the table creation code there. As #ScarletGarden suggests, you also need to add the control whether it's a PostBack or not. I believe that doing it in Page_Load is too late for the event to be detected if you add the control there.
Reference
Here is my trial, and it worked :
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
//{
placeHolderAtPage.Controls.Add(CreateEditLink("forCard1"));
//}
}
LinkButton CreateEditLink(string forCard)
{
LinkButton rtn = new LinkButton();
rtn.ID = "Edit_" + forCard;
rtn.Text = "EditDetails";
rtn.CommandName = "Edit";
rtn.CommandArgument = forCard;
rtn.Command += new CommandEventHandler(RedirectToEdit);
rtn.Attributes["style"] = "display: block; text-align:center;";
return rtn;
}
void RedirectToEdit(object sender, CommandEventArgs e)
{
Response.Write("RedirectToEdit Called:\r\nName: " + e.CommandName + "\r\nArgument: " + e.CommandArgument);
}
If you decomment the IsPostBack line, RedirectToEdit will be useless.
Only binding codes can be under IsPostBack control.

Resources