Automate WebBrowser.ShowSaveAsDialog() or alternative method - c#

Basically I wan't to save an image loaded in a webBrowser control. The only way I can get this to work at the moment is by showing the save as dialog.
is there a way to pass in a path and make it save itself? (hide the dialog I ask to show!)
is there another way to save the image? I can't seem to get documentstream to work. I have also tried webclient.filedownload(...) but get an error 302 ( "(302) Found Redirect.")
DownloadFileAsync gives no error but an empty jpeg file?
files are always jpegs, but not always at same location.

You should go with HttpWebRequest.
It has the capability to follow a 302 automatically.
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
//increase this number if there are more then one redirects.
myHttpWebRequest.MaximumAutomaticRedirections = 1;
myHttpWebRequest.AllowAutoRedirect = true;
var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
var buff = new byte[myHttpWebResponse.ContentLength];
// here you specify the path to the file. The path in this example is : image.jpg
// if you want to store it in the application root use:
// AppDomain.CurrentDomain.BaseDirectory + "\\image.jpg"
using (var sw = new BinaryWriter(File.Open("c:\\image.jpg", FileMode.OpenOrCreate)))
{
using (var br = new BinaryReader (myHttpWebResponse.GetResponseStream ()))
{
br.Read(buff, 0, (int)myHttpWebResponse.ContentLength);
sw.Write(buff);
}
}

Related

Image.ImageUrl = ... nothing is displayed

On my development system (Win 10 Pro, VS 2015), I am testing a web forms app in VS 2015; it uses a master page. An image control in an asp content page shows nothing when I try to display a photo from a file just written after a resize, whereas it displays the original photo just fine. Here is the code-behind fragment with the problem detailed in the comments:
// During testing, sRelLoc contains "~/i/SlideShow/1th.jpg" (original photo)
string sRelLocMod = sRelLoc.Replace("~/", "").Replace("/", "\\");
// During testing, Global.sgHomeDir contains "K:\\DataAndDocs\\12_Projects\\TinyNP\\TinyNP\\"
string sImgUrl = Global.sgHomeDir + sRelLocMod;
// sImgUrl now contains
System.Drawing.Image Photo = null;
// Read original photo from file
using (FileStream fs = new FileStream(sImgUrl, FileMode.Open, FileAccess.Read))
{
Photo= System.Drawing.Image.FromStream(fs);
}
// ResizeImage from https://www.codeproject.com/articles/191424/resizing-an-image-on-the-fly-using-net
System.Drawing.Image PhotoResized = ResizeImage(Photo, new Size(400, 400), true);
sImgUrl = Global.sgHomeDir + "i\\tempImg.jpg";
using (FileStream fs = new FileStream(sImgUrl, FileMode.Open, FileAccess.Write))
{
PhotoResized.Save(fs,System.Drawing.Imaging.ImageFormat.Jpeg);
}
// NOTE THAT: The image has been saved correctly in its resized form inside the expected directory
sImgUrl = sImgUrl.Replace("\\", "/");
//sImgUrl now contains "K:/DataAndDocs/12_Projects/TinyNP/TinyNP/i/tempImg.jpg"
// Image1 is an Image control on an asp.net web page.
// PROBLEM: The following statement displays nothing where Image1 is
// placed (not even a red-x or anything) , ...
Image1.ImageUrl = sImgUrl;
// ... but displays the unresized original just fine when the following statement is used instead:
// Image1.ImageUrl = sRelLoc;
Same behavior whether or not running in debug mode.
Perhaps there is a better approach than writing the resized photo to temporary file tempImg.jpg and then reading from it?
Update after jignesh's and Sami's responses:
I am using MapPath in Default.aspx.cs (see new comments below).
Now using System.Uri to convert path to Url which starts with "file:///". Leads to nothing being displayed. Replacing "file:" with "http:" leads to a broken image symbol being displayed. Updated code is:
// During testing, sRelLoc contains "~/i/SlideShow/1.jpg" (original photo)
string sRelLocMod = sRelLoc.Replace("~/", "").Replace("/", "\\");
// During testing, Global.sgHomeDir contains "K:\\DataAndDocs\\12_Projects\\TinyNP\\TinyNP"
// which was obtained in Default.aspx.cs Page Load Event by
// Global.sgHomeDir = HttpContext.Current.Server.MapPath(null);
string sImgPath = Global.sgHomeDir + "\\" + sRelLocMod;
// sImgPath now contains "K:\\DataAndDocs\\12_Projects\\TinyNP\\TinyNP\\i\\SlideShow\\1.jpg"
System.Drawing.Image Photo = null;
// Read original photo from file
using (FileStream fs = new FileStream(sImgPath, FileMode.Open, FileAccess.Read))
{ Photo= System.Drawing.Image.FromStream(fs); }
// ResizeImage from https://www.codeproject.com/articles/191424/resizing-an-image-on-the-fly-using-net
System.Drawing.Image PhotoResized = ResizeImage(Photo, new Size(400, 400), true);
sImgPath = Global.sgHomeDir + "\\i\\tempImg.jpg";
// sImgPath now contains "K:\\DataAndDocs\\12_Projects\\TinyNP\\TinyNP\\i\\tempImg.jpg"
using (FileStream fs = new FileStream(sImgPath, FileMode.OpenOrCreate, FileAccess.Write))
{ PhotoResized.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg); }
// I have verified that the image has been saved correctly in its resized form inside the expected directory
System.Uri ImgUrl = new System.Uri(sImgPath, UriKind.Absolute);
// Image1 is an Image control on an asp.net web page.
string sImgUrl = ImgUrl.ToString();
//sImgUrl now contains "file:///K:/DataAndDocs/12_Projects/TinyNP/TinyNP/i/tempImg.jpg"
Image1.ImageUrl = sImgUrl;
// The above statement DOES NOT work (displays nothing at all)
// However:
//Image1.ImageUrl = "~/i/tempImg.jpg"; // ** DOES ** work ok
// If I replace "file:" with "http:", a broken image symbol is displayed.
But what does work is using a tilde "~" even though it does not look like a Url. Is it ok to use the tilde? Will it get me into any trouble, like when deploying to a hosting server?
Use the ImageUrl property to specify the URL of an image to display in the Image control.You can use a relative or an absolute URL. A relative URL relates the location of the image to the location of the Web page without specifying a complete path on the server. The path is relative to the location of the Web page. This makes it easier to move the entire site to another directory on the server without updating the code. An absolute URL provides the complete path, so moving the site to another directory requires that you update the code.
By absolute url, they mean the entire IIS path to the URL (Not your disk directory path). (i.e. http://yourVirtualDirectory/ExternalImages/logo.jpg).
So here in above code sImgUrl="K:/DataAndDocs/12_Projects/TinyNP/TinyNP/i/tempImg.jpg" it should be like http://yourVirtualDirectory/tempImg.jpg

Add downloaded images to resource folder

I have downloaded an image with the following code:
bool pageExists = false;
// Check if webpage exists
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://image.tmdb.org/t/p/w780" + imagePath);
request.Method = WebRequestMethods.Http.Head;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
pageExists = response.StatusCode == HttpStatusCode.OK;
}
// Download image
if (pageExists)
{
string localFilename = #"C:\Users\Giri\Desktop\giri" + id + ".jpg";
using (WebClient client = new WebClient())
{
client.DownloadFile("http://image.tmdb.org/t/p/w780" + imagePath, localFilename);
}
}
For now, I have just been saving this image on my Desktop.
My question is how do I go about storing this image in my WPF application programmatically within a resources folder or a folder I have generated myself? The images should persist in that the next time the application is run, the added images should remain.
Is there an accepted place I should be storing my images?
Thanks for your help.
Please use AppDomain.CurrentDomain.BaseDirectory. Which will give you the directory of your executable. Even in deployed code this should give you the right value. But other values like Environment.CurrentDirectory can give different value based on from where you are calling it etc.
See this question Best way to get application folder path

Saving File on Desktop by c#

I am using a web service that returns me some data. I am writing that data in a text file. my problem is that I am having a file already specified in the c# code, where I want to open a dialog box which ask user to save file in his desired location. Here I am posting code which I have used. Please help me in modifying my code. Actually after searching from internet, all are having different views and there is lot of changes in code required where as I do not want to change my code in extent. I am able to write the content in test file but how can I ask user to enter his desire location on computer?
StreamWriter file = new StreamWriter("D:\\test.txt");
HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(yahooURL);
// Get the response from the Internet resource.
HttpWebResponse webresp = (HttpWebResponse)webreq.GetResponse();
// Read the body of the response from the server.
StreamReader strm =
new StreamReader(webresp.GetResponseStream(), Encoding.ASCII);
string content = "";
for (int i = 0; i < symbols.Length; i++)
{
// Loop through each line from the stream,
// building the return XML Document string
if (symbols[i].Trim() == "")
continue;
content = strm.ReadLine().Replace("\"", "");
string[] contents = content.ToString().Split(',');
foreach (string dataToWrite in contents)
{
file.WriteLine(dataToWrite);
}
}
file.Close();
Try this
using (WebClient Client = new WebClient ())
{
Client.DownloadFile("http://www.abc.com/file/song/a.mpeg", "a.mpeg");
}

How to Download File

I have been following these links all listed below, i found the best way to write this SMALL create Excel and Download function. ( Using EPPlus for Excel )
Download file of any type in Asp.Net MVC using FileResult? + How to convert an Stream into a byte[] in C#?
Using a FileStreamResult with a MemoryStream in ASP.NET MVC 3
Writing A Custom File Download Action Result For ASP.NET MVC
It runs through the code perfectly without error every time I run this but does not "Kick out" the file to be downloaded ( in a save as dialogue or w/e ).
public ActionResult ShowReport()
{
using (var stream = new MemoryStream())
{
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample1");
ws.Cells["A1"].Value = "Sample 1";
ws.Cells["A1"].Style.Font.Bold = true;
var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
shape.SetPosition(50, 200);
shape.SetSize(200, 100);
shape.Text = "Sample 1 text text text";
var fileDownloadName = "sample.xlsx";
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";//System.Net.Mime.MediaTypeNames.Application.Octet
var fileStream = new MemoryStream();
pck.SaveAs(fileStream);
fileStream.Position = 0;
var fsr = new FileStreamResult(fileStream, contentType);
fsr.FileDownloadName = fileDownloadName;
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
}
}
What am I doing wrong / missing? - Must i write that Dialogue myself?
PN: I have also attempted this way
byte[] fileBytes = ReadToEnd(fileStream);
string fileName = "example";
return File(fileBytes, contentType, fileName);
ofcourse i had to figure out how to convert Stream to Byte but it also did not show anything.
Image of Chrome's Network Development Tool
Sorry about the small image ( if you can't see it scroll in with ctl+MouseWheel ) if your in a supporting browswer.
(In response to the comment thread above.)
From the image posted it looks like the actual file request (the last one in the list) is coming from JavaScript code instead of from a normal document-level request. Given this, it's highly likely that the server-side code is working correctly and returning the correct response.
However, since it's an AJAX request, the browser doesn't actually know what to do with the response. There are some potential solutions here. Ideally, you'll want to make this a normal request and remove AJAX from the picture if possible. If that's not an option, you can still initiate a document-level request from JavaScript. Something as simple as this:
window.location = '#Url.Action("Method", "Controller")';
This would be initiated from JavaScript code as it currently is, but would be for the whole browser instead of an AJAX request. That should do the trick.
Using the memory stream you have you can simple pass that to the Response object once you have saved the Excel Package
Code:
Response.AddHeader("content-disposition", "attachment;filename=FILENAME.xlsx")
Response.Charset = String.Empty
Response.ContentType = "application/ms-excel"
Response.BinaryWrite(stream.ToArray())
Response.End()

Selenium c# - how do i test that an image src file exists (verifying if the image shows on the page)

im new to Selenium and c# so I've hit a dead end. I need to know how to check weather an images src file exists or not. When I mean exists, is it showing on the page (not the red x box you get when no image is present).
I have tried file.exists(#c://imagename); and System.File.Exists.
I don't know if this is correct or not.
Any help would be great!! My heads fried with this
Thanks
Assuming that the path to the image is relative in the src attribute you would need to work out the URL then run a test similar to the one outlined in this answer:
Test to see if an image exists in C#
If you really need to check if the image exists and has been deployed (I would question if this is a qorthwhile test to be honest) you could use something like the code below:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://full-path-to-your-image.png");
request.Method = "HEAD";
bool exists;
try
{
request.GetResponse();
exists = true;
}
catch
{
exists = false;
}
It basically checks the URL (of the image in your case), to see if the images exists.
If you need a hand with it turn round and ask ;)
My solutions was to check length of the file.
you can modify this solution to your need:
/// <summary>
/// Gets the file lenght from location.
/// </summary>
/// <param name="location">The location where file location sould be located.</param>
/// <returns>Lenght of the content</returns>
public int GetFileLenghtFromUrlLocation(string location)
{
int len = 0;
int timeoutInSeconds = 5;
// paranoid check for null value
if (string.IsNullOrEmpty(location)) return 0;
// Create a web request to the URL
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(location);
myRequest.Timeout = timeoutInSeconds * 1000;
myRequest.AddRange(1024);
try
{
// Get the web response
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
// Make sure the response is valid
if (HttpStatusCode.OK == myResponse.StatusCode)
{
// Open the response stream
using (Stream myResponseStream = myResponse.GetResponseStream())
{
if (myResponseStream == null) return 0;
using (StreamReader rdr = new StreamReader(myResponseStream))
{
len = rdr.ReadToEnd().Length;
}
}
}
}
catch (Exception err)
{
throw new Exception("Error saving file from URL:" + err.Message, err);
}
return len;
}
You can't do it, at least not solely with Selenium. Depending on which browser you're testing with, you might be able to look into the on-disk browser cache and find the file, but not all browsers cache everything to disk, and figuring out the filename may be very difficult.
Without Selenium, of course, you can use curl, wget, et al. to download the image file, or you could possibly screen-shot the browser and search for the "red X box" yourself. But neither is really a nice answer.

Categories

Resources