c# on button click open pdf in new tab insted of downloading - pdf

I have a .aspx page and it has a button on click of which a radwindow opens .The radwindow has a new page with content including a button onclick of which a pdf is created and downloaded.I want the pdf to open in a new tab or window , so i made changes to my code -changed attachment to inline
Hashtable deviceInfo = new Hashtable();
deviceInfo.Add("FontEmbedding", "Subset");
deviceInfo.Add("DocumentTitle", String.Format("TrackitManager - {0}", reportToExport.DocumentName));
deviceInfo.Add("DocumentAuthor", "Trackit Systems Pty Ltd");
ReportProcessor reportProcessor = new ReportProcessor();
RenderingResult result = reportProcessor.RenderReport("PDF", reportToExport, deviceInfo);
if (String.IsNullOrEmpty(filename))
filename = result.DocumentName;
context.Response.Clear();
context.Response.ContentType = result.MimeType;
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Expires = -1;
context.Response.Buffer = true;
//context.Response.TransmitFile("~/Handlers/EnrollmentPDF.ashx");
context.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename=\"{0}.pdf\"", filename));
context.Response.BinaryWrite(result.DocumentBytes);
context.Response.End();
But this is opening the pdf inside the radwindow itself.I want it to open in a new window but outside the radwindow.

you have to give the correct header and mimeType to tell the browser to download the file
for that you just have to add this line to replace :
context.Response.ContentType = result.MimeType;
by this line :
Response.ContentType = "application/octectstream";

Related

Selenide can't download PDF

I had some trouble using Selenide's download function. This is my flow:
click on button
button opens new tab which shows pdf file and url is:
blob:https://hostname.apps.something.else/9365b3ab-f0ad-45e9-85d2-db7e2fb5fd2e
So basically the new tab is opened in Chrome PDF Viewer.
I tried to click on the hidden download button in the new tab but no luck.
My thinking got me to the idea of when I click that button, this new tab shouldn't open, the download should start. That would mean settings some Configuration preferences like I did below:
Configuration.browserCapabilities = new DesiredCapabilities();
Configuration.browserSize = "1920x1080";
Configuration.fileDownload = FileDownloadMode.FOLDER;
Configuration.downloadsFolder = "./src/pdfs";
Configuration.proxyHost = "30.40.34.82";
Configuration.proxyPort = 8080;
Configuration.proxyEnabled = true;
Configuration.fileDownload = FileDownloadMode.PROXY;
Configuration.browserCapabilities.setCapability("plugins.always_open_pdf_externally", true);
Configuration.browserCapabilities.setCapability("download.prompt_for_download", false);
Configuration.browserCapabilities.setCapability("pdfjs.disabled", true);
The problem is that, this still opens new tab, and I get no such element found
File file = applicationList.printButton.download(30000);
Why do you first set Configuration.fileDownload to FOLDER and then to PROXY? No need to set it twice.
I think you cannot download the file via PROXY because links of type blob: don't fetch file content from the server.
I think you can just remove all these lines:
Configuration.proxyHost = "30.40.34.82";
Configuration.proxyPort = 8080;
Configuration.proxyEnabled = true;
Configuration.fileDownload = FileDownloadMode.PROXY;
Configuration.browserCapabilities.setCapability("plugins.always_open_pdf_externally", true);
Configuration.browserCapabilities.setCapability("download.prompt_for_download", false);
Configuration.browserCapabilities.setCapability("pdfjs.disabled", true);
Selenide method FOLDER should download the file without all these tricky settings.
Try it
System.setProperty("chromeoptions.prefs", "plugins.always_open_pdf_externally=true")

Download PDF file opening as URL in different tab in selenium

Scenario:
I have an application, say A: When we log in to A, we have one link say B clicking on which will open a new browser.
In browser B we have one Link that will open a pdf. Once click on that the PDF is opening as URL in the 2nd tab where we had opened the page A.
Problem:
I have tried switching using iteration through window handle but it is not finding that. I have also tried adding below to find all the window handle where you have below locator.
if(driver.findElement(By.xpath("//*[#id="plugin"]")))
but as PDF URL has opened in a 2nd tab, I am not able to get the window handle. I think as per my code below, if I get Window handle then I will use robot class and save the PDF.
Note : I am using xframium framework so, had to define
WebDriver driver = getCustumWebDriver();
I can only use IE/Chrome and no other browsers
Any suggestions on how to solve?
Code:
public String getWindowUrl(String saveDir, SoftAssert softAssert, Element element)
{
boolean success = false;
String newWindowUrl = null;
try {
WebDriver driver = getCustumWebDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//current window handle
String beforWindowHandle = driver.getWindowHandle();
_wait(2000);
//Click on the element to which the pdf link is opened
_click(element);
waitForPageLoad();
_wait(30000);
Set<String> allWindowhandles = driver.getWindowHandles();
for(String handle1 : allWindowhandles)
{
if(!handle1.equals(beforWindowHandle))
{
driver.switchTo().window(handle1);
_wait(2000);
newWindowUrl = driver.getCurrentUrl();
docName = newWindowUrl.replaceAll("[^0-9]+", "");
docName = saveDir.concat(docName).concat(".pdf");
Robot rb = new Robot();
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_S);
_wait(3000);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_C);
rb.keyRelease(KeyEvent.VK_C);
rb.keyRelease(KeyEvent.VK_CONTROL);
_wait(1000);
rb.keyPress(KeyEvent.VK_HOME);
rb.keyRelease(KeyEvent.VK_HOME);
_wait(3000);
StringSelection stringSelection = new StringSelection(saveDir);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
rb.delay(3000);
// _wait(3000);
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
_wait(2000);
}
}
success = true;
driver.close();
}
Scenario 2 :
I can force the application to open a new browser window just for PDF but I am not able to get to that specific window where new PDF URL will open.
I will try the below and give my observation:
**for(String handle1 : allWindowhandles)
{
// change focus to new tab
driver.switchTo().window(handle1);
if(!(driver.findElement(By.id("Element that will be present on browser window 1 - A ")).isDisplayed()||
driver.findElement(By.id("Element that will be present on browser window 2 - B ")).isDisplayed()))
{
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_S);
_wait(3000);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_C);
rb.keyRelease(KeyEvent.VK_C);
rb.keyRelease(KeyEvent.VK_CONTROL);
_wait(1000);
rb.keyPress(KeyEvent.VK_HOME);
rb.keyRelease(KeyEvent.VK_HOME);
_wait(3000);
StringSelection stringSelection = new StringSelection(saveDir);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
rb.delay(3000);
// _wait(3000);
rb.keyPress(KeyEvent.VK_ENTER);
}**
As per my understanding,Developer of that application that you are referring has configured the pdf launching in new tab.so we cannot open it in same tab because it has already configured in application label.
Just call this method:
public void switchToNEWwindow(){
try{
ArrayList<String> newTab = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(newTab.get(1));
}
catch(Exception e){}
}

itextsharp stamper vs smartcopy, show pdf in browser without toolbar or navpanes

My application is grabbing pdf bytes from our db and sending the pdf to an iframe, using the itextsharp library. When the pdf is displayed in the iframe, the toolbar and navigation pane show, but we'd like to hide those. When I load a pdf document by simply typing in the pdf's url with #toolbar=0&navpanes=0, I see the result I'm looking for.
The application logic is using PdfStamper to add some buttons and other data to the pdf. When I write the pdf to the Response.Outputstream, the pdf shows up with the added buttons, and all is good except that I can't get rid of the toolbar and navpanes. I've tried adding "toolbar=0&navpanes=0" to the url in the response header, but to no avail.
I've written a test application which shows that using PdfSmartCopy instead of the stamper works perfectly - the pdf is shown in the browser which hides the toolbar and navpane by default.
The problem is that I still need to add some buttons to the pdf via the stamper. I've written a test app which adds the buttons via the stamper, then the smart copy grabs each page from the stamper and writes all this out to the Response.Output. The pdf shows in the browser with no toolbar or navpanes, but the buttons are not there.
Here is the code which uses both the stamper and the smart copy - your help is greatly appreciated:
private void SendStamperToCopy()
{
try
{
String filePath = #"C:\debug\PerfIndicWithDefaults.pdf";
byte[] pdfBytes = ReadFile(filePath);
Document document = new Document();
PdfSmartCopy copy = new PdfSmartCopy(document, Response.OutputStream);
document.Open();
MemoryStream memStream = new MemoryStream();
PdfReader reader = new PdfReader(pdfBytes);
PdfStamper pdfStamper = new PdfStamper(reader, memStream);
// add a button with the stamper
iTextSharp.text.Rectangle rectCancel = new iTextSharp.text.Rectangle(50, 50, 20, 20);
PushbuttonField btnCancel = new PushbuttonField(pdfStamper.Writer, rectCancel, "Cancel");
btnCancel.Text = "Cancel";
iTextSharp.text.pdf.PdfAnnotation fieldCancel = btnCancel.Field;
pdfStamper.AddAnnotation(fieldCancel, 1);
int numOfPgs = reader.NumberOfPages;
for (int n = 1; n <= numOfPgs; n++)
{
copy.AddPage(pdfStamper.GetImportedPage(reader, n));
}
String headerStr = "inline; filename=PerfIndicWithDefaults.pdf";
Response.AppendHeader("content-disposition", headerStr);
Response.ContentType = "application/pdf";
Response.OutputStream.Flush();
document.Close();
Response.OutputStream.Close();
}
catch (Exception ex)
{
Console.Write(ex);
Response.OutputStream.Flush();
Response.OutputStream.Close();
}
}
If I understand your question correctly, you want to use PdfStamper to add a button and you want to change the viewer preferences. This can be done like this:
PdfReader reader = new PdfReader(source);
System.IO.MemoryStream m = new System.IO.MemoryStream();
PdfStamper stamper = new PdfStamper(reader, m);
PdfStamper.ViewerPreferences = PdfWriter.HideToolbar | PdfWriter.PageModeUseNone;
stamper.Close();
reader.Close();
The HideToolbar will hide the toolbar, whereas PageModeUseNone means that you don't show any panels (such as the bookmarks panel, etc...).
It is not clear why you would need PdfSmartCopy in this context. Maybe I'm missing something. Also: there are some strange errors in your code: you never close the stamper instance, yet you import a page from the stamper into the copy instance. I've never seen any one try that. It's certainly not what I had in mind when I wrote iText. Your code is very confusing to me.

Replace attachment when uploading a new attachment

I have a simple form and body field. when user upload an attachment I want to remove any attachment already in the body field of the document. how can I do this in my save button.
I have tried to set the properites on the fileUpload control to always change the filename to tha same name but this does not replace the file, instead it adds a new file and add a new sequential number to it
<xp:fileUpload id="fileUpload1" value="#{userdoc.Body}" filename="profile" seUploadname="false"></xp:fileUpload>
I have also tried to loop all embedded attachments in body field before before save, and all attachments are then removed, but my new attachment is not added.
A little late, but in case anyone gets here just as I did through Google...
There's also another option: a NotesXSPDocument.getAttachmentList("rtitem") returns a list of attachments in the document. Each entry is of type DominoDocument.AttachmentValueHolder which has a getState() property that returns if a file was already in the document or just added. To remove the file that was already in the document you could add this SSJS code to a save button (assuming "files" is the name of the richtext item holding the files):
var attList = docFile.getAttachmentList("files");
for(var i=0; i<attList.size(); i++) {
var att = attList.get(i);
if (att.getState()==0) { //STATE_INDOCUMENT: this is the 'old' file: remove it
docFile.removeAttachment("files", att.getName() );
} else if (att.getState()==1) { //STATE_ADDED: this is the new file
//leave it
}
}
This can be done by removing all attachments first (use the removeAllAttachments function from NotesXSPDocument object) and then attach the uploaded file manually to the richtext item.
This SSJS code has to be added to beforeRenderResponse-event of your XPage / Custom Control:
var con = facesContext.getExternalContext();
var request:com.sun.faces.context.MyHttpServletRequestWrapper = con.getRequest();
var map:java.util.Map = request.getParameterMap();
var fileDataName = getClientId('fileUpload1') ;
var fileData:com.ibm.xsp.http.UploadedFile = map.get( fileDataName );
if( fileData == null ){
return;
}
var tempFile:java.io.File = fileData.getServerFile();
var correctedFile = new java.io.File( tempFile.getParentFile().getAbsolutePath() +
java.io.File.separator + fileData.getClientFileName() );
var success = tempFile.renameTo(correctedFile);
try{
document1.removeAllAttachments("Body");
}catch(e){}
var rtFiles:NotesRichTextItem = null;
if(!(document1.getDocument().hasItem("Body"))){
rtFiles = document1.getDocument().createRichTextItem("Body")
}else{
rtFiles = document1.getDocument().getFirstItem("Body");
}
rtFiles.embedObject(lotus.domino.local.EmbeddedObject.EMBED_ATTACHMENT, "",
correctedFile.getAbsolutePath(), null);
correctedFile.renameTo(tempFile);
document1.save();
The richtext item where the files are stored is "Body", the name of the datasource is "document1". The Fileupload control is "fileUpload1".
There are two limitations:
You cannot use this with a save button, you have to use a normal button / link which makes a full refresh (see what Serdar Basegmez wrote above)
You have to refresh the page after a upload once again, otherwise you will not see the uploaded file in a file download conrol (maybe a partial refresh to this control may work).
EDIT:
Sorry, my fault: You can use this code above in a submit button that saves the document. Then you don't have to refresh the page manually!

How to start SharePoint 2010 workflow from Infopath 2010 code behind?

I have an Infopath 2010 template with 2 buttons: submit and cancel. When the submit button is clicked I the form is saved to a document library in SharePoint 2010 and the corresponding workflow is clicked off. The user can then open the form and cancel the request by clicking on cancel. I would like to start a different workflow when cancel is clicked. Any ideas as to how that could be done?
Thanks
I have not found a method to kick off a workflow specifically from an Infopath form. I did however find a workaround; here's how I set it up:
Added a column to my list/library that will be set to true when the cancel button is selected.
In my infopath form, add my "cancel" button.
Open the control properties for the button, and select the "Rules" action. Close out of the properties dialog.
I added a fomatting rule for the cancel button so it will only display if the first workflow has started. I also disabled all other editing controls as I only wanted the cancel option to be available.
On the Control Tools contextual tab, in the Button group, click Manage Rules.
Add a new Action rule, it should run two actions: first set the value of the column we created in the first step to true; second submit data using the main data connection.
The workflow you want to run when it is cancelled should be set to run on change. As a first step, evaluate the column created above, and if true, continue the worflow. Make sure you set the value back to false so the workflow doesn't run unintentionally.
Hope that helps.
That is not a bad workaround Nostromo but we actually ended up using the out of the box SharePoint web services to start the workflow from InfoPath code behind. Here is the method we developed to do that.
public static void StartWorkflow(string siteUrl, string docUrl,string workflowName, List<string> approvers,string description)
{
var workflow = new Workflow();
workflow.Url = siteUrl+ "/_vti_bin/workflow.asmx";
workflow.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlNode assocNode = workflow.GetTemplatesForItem(docUrl);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
nsmgr.AddNamespace("wf", "http://schemas.microsoft.com/sharepoint/soap/workflow/");
XmlDocument doc = new XmlDocument();
Guid templateID = new Guid();
bool workflowFound = false;
XPathNodeIterator rows = assocNode.CreateNavigator().Select("//wf:WorkflowTemplate", nsmgr);
while (rows.MoveNext())
{
if (rows.Current.GetAttribute("Name", "").ToLower() == workflowName.ToLower())
{
doc.LoadXml(rows.Current.SelectSingleNode("wf:AssociationData/wf:string", nsmgr).Value);
XPathNavigator idNode = rows.Current.SelectSingleNode("wf:WorkflowTemplateIdSet", nsmgr);
templateID = new Guid(idNode.GetAttribute("TemplateId", ""));
workflowFound = true;
break;
}
}
if(!workflowFound)
throw new Exception("System couldn't location the workflow with name: " +workflowName);
XmlElement xmlRoot = doc.DocumentElement;
nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
nsmgr.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD");
xmlRoot.SelectSingleNode("/my:myFields/my:Description", nsmgr).InnerText = description;
XmlNode reviewersNode = xmlRoot.SelectSingleNode("/my:myFields/my:Reviewers", nsmgr);
reviewersNode.InnerXml = "";
foreach (var user in approvers)
{
XmlNode personNode = reviewersNode.AppendChild(doc.CreateElement("my:Person"));
XmlNode accountIdNode = personNode.AppendChild(doc.CreateElement("my:AccountId"));
accountIdNode.InnerText = user;
XmlNode accountTypeNode = accountIdNode.AppendChild(doc.CreateElement("my:AccountType"));
accountTypeNode.InnerText = "User";
}
XmlNode workflowNode = workflow.StartWorkflow(docUrl, templateID, doc.DocumentElement);
}