I have a problem with this method, i want to return a PDF file and when the method it's over i want to delete de file from the directory.
public ActionResult DescargaPdfCompara(string id)
{
var rutaPdf = string.Empty;
var type = "application/pdf";
try
{
DateTime ahora = DateTime.Now;
var numeroAleatorio = new Random();
int numeroRandomico = numeroAleatorio.Next(100000000, 1000000000);
string Ruta = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Reportes\" + Convert.ToString(ahora.Year + ahora.Month + ahora.Day + ahora.Hour + ahora.Minute + ahora.Second + numeroRandomico) + ".pdf");
var result = SimuModel.ObtenerSabanaReporteComparativo(id);
var resumen = SimuModel.ObtenerPreExcel(result);
SimuModel.GenerarPdfCompa(result, resumen, Ruta);
rutaPdf = Ruta;
return File(rutaPdf, type);
}
catch (Exception e)
{
throw e;
}
finally
{
System.IO.File.Delete(rutaPdf);
}
}
In the finally i delete the file but i got an error because the method can't find the file, for some reason the method delete the file before return it.
PD: Sorry for my english, i'm from Chile.
Thanks fro your answers!
You can use System.IO.File.ReadAllBytes to read all the file contents to memory, then delete the file and return the contents with another overload of Controller.File method:
public ActionResult GetFile()
{
var fileName = Path.GetTempFileName();
System.IO.File.WriteAllText(fileName, "Hola, Chile!");
var bytes = System.IO.File.ReadAllBytes(fileName);
System.IO.File.Delete(fileName);
return File(bytes, "text/plain", "file.txt");
}
Change return type ContentResult
remove finally section.
public ContentResult DescargaPdfCompara(string id)
{
var rutaPdf = string.Empty;
var type = "application/pdf";
try
{
DateTime ahora = DateTime.Now;
var numeroAleatorio = new Random();
int numeroRandomico = numeroAleatorio.Next(100000000, 1000000000);
string Ruta = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Reportes\" + Convert.ToString(ahora.Year + ahora.Month + ahora.Day + ahora.Hour + ahora.Minute + ahora.Second + numeroRandomico) + ".pdf");
var result = SimuModel.ObtenerSabanaReporteComparativo(id);
var resumen = SimuModel.ObtenerPreExcel(result);
SimuModel.GenerarPdfCompa(result, resumen, Ruta);
rutaPdf = Ruta;
return Content(rutaPdf, type);
}
catch (Exception e)
{
throw e;
}
}
Related
I have the following code and it works fine when I loop through one by one using foreach, but when I change it to use Parallel.ForEach I'm getting errors. Trying to figure out how I can correct this. FYI the dParms list contain unique id's.
The error I'm getting is
Error writing to path..... ErrorMessage:Item has already been added.
Key in dictionary: 'IIS_WasUrlRewritten' Key being added:
'IIS_WasUrlRewritten',
private void GeneratePages(RequestStatus response, string localDir, List<Parameters> dParms, int total, DateTime generatedTime)
{
int current = 0;
Parallel.ForEach(dParms, curJob =>
{
try
{
DownloadPage(localDir, curJob, generatedTime);
}
catch (Exception ex)
{
response.Status = false;
response.Message = ex.Message;
}
finally
{
Interlocked.Increment(ref current);
if (current % 10 == 0)
//to do: Send Progress to UI
}
//});
}
private string DownloadPage(string localDir, Parameters p, DateTime generatedTime)
{
string strExtension = "html";
string url = string.Empty;
url = this.Url.Action("MyAction", "Home", new { area = "", #id = p.MyId, #generatedTime = generatedTime }, this.Request.Url.Scheme);
var document = new HtmlWeb().Load(url);
string strFileName = url.Substring(url.LastIndexOf("/") + 1);
strFileName = strFileName.Substring(0, strFileName.IndexOf("generatedTime") - 1);
string strDiskFileName = strFileName.Replace(".aspx?", "");
strDiskFileName = strDiskFileName.Replace("?", "");
strDiskFileName = strDiskFileName.Replace(".aspx", "");
strDiskFileName = strDiskFileName.Replace("&", "");
strDiskFileName = strDiskFileName.Replace("=", "");
strDiskFileName = strDiskFileName.Replace("%20", "");
strDiskFileName += "." + strExtension;
document.Save(localDir + strDiskFileName);
return url;
}
I'm trying to upload an excel file, and I want to append Guid with the file name.
I'm using C# MVC for this
public ActionResult ValidateUploadedFile()
{
DataExchangeDefinitionViewModel dataExchangeDefinitionVM = new DataExchangeDefinitionViewModel();
DataExchangeDefinition dataExchangeDefinitionObj = new DataExchangeDefinition();
// Get all files from Request object
HttpFileCollectionBase files = Request.Files;
HttpPostedFileBase file = files[0];
try
{
if (Request.Files.Count > 0)
{
string fname;
// Checking for Internet Explorer
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
Guid guidObj = Guid.NewGuid();
fname = file.FileName + guidObj.ToString();
}
fname = Path.Combine(Server.MapPath("~/images/Uploads/ImportExcel"), fname);
if (_dataExchangeBusiness.IsExcelFile(fname)==true)
{
file.SaveAs(fname);
return Json(new { Result = "true", Message = "" });
}
else
{
return Json(new { Result = "false", Message = "" });
}
}
}
catch (Exception ex)
{
throw ex;
}
// return Json(new { Result = "OK" ,Message="File validated succesfully"});
return null;
}
Actually, the file is uploaded properly. I want to append Guid with the file name. When I append with Guid with file name it appends after the file extension.
like this OtherExpense_01.01.2011_E20.xlsx7ac9dbdb-67bb-434c-8465-6a1f7e5bfc83
i'm expecting result like this OtherExpense_01.01.2011_E20_7ac9dbdb-67bb-434c-8465-6a1f7e5bfc83.xlsx
You can use Path.GetFileNameWithoutExtension() and Path.GetExtension() methods to concatenate filename with GUID (note that both of them requires System.IO namespace):
Guid guidObj = Guid.NewGuid();
string baseName = Path.GetFileNameWithoutExtension(file.FileName);
string extension = Path.GetExtension(file.FileName);
fname = baseName + guidObj.ToString() + extension;
I have phone numbers stored in the database, I want to retrieve all phone numbers using foreach loop and assign them to variable and send bulk sms, but problem is, I am getting only one number from database. Here is my code:
// GET: Members/SendBatch
public ActionResult SendBatch()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SendBatch(Membership member)
{
var db = new ChurchContext();
StreamReader objReader;
WebClient client = new WebClient();
string mess = member.Message;
string cell = member.Cell;
string pass = "xxxx";
string user = "xxxx";
string selectministries = member.SelectMinistries;
string pathtoministries = "";
pathtoministries = GetMinisry(selectministries);
if (pathtoministries == "Youth")
{
var youthtable = from e in db.Youths
select e;
var Entyouth = youthtable.ToList();
foreach (Youth y in Entyouth)
{
string youthcell = y.ContactMobile.ToString();
cell = youthcell;
}
}
string baseurl = "http://bulksms.2way.co.za/eapi/submission/send_sms/2/2.0?" +
"username=" + user + "&" +
"password=" + pass + "&" +
"message=" + mess + "&" +
"msisdn=" + cell;
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(baseurl);
try
{
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
objReader = new StreamReader(objStream);
objReader.Close();
}
catch (Exception ex)
{
ex.ToString();
}
return View("Index", member);
}
public static string GetMinisry(string ministry)
{
string membership = "";
switch (ministry)
{
case "Youth":
membership = "Youth";
break;
case "Children":
membership = "Children";
break;
case "Men":
membership = "Men";
break;
case "Women":
membership = "Women";
break;
case "Visitors":
membership = "Visitors";
break;
case "Members":
membership = "Members";
break;
}
return membership;
}
I would like to get all the phone numbers and assigned them to cell variable and then to sms api and send bulk sms.
Try this (dirty but will do the job):
string mess = member.Message;
string cell = member.Cell;
List<string> cellNumbers = new List<string>(); //LIST OF NUMBERs
string pass = "xxxx";
string user = "xxxx";
string selectministries = member.SelectMinistries;
string pathtoministries = "";
pathtoministries = GetMinisry(selectministries);
if (pathtoministries == "Youth")
{
var youthtable = from e in db.Youths
select e;
var Entyouth = youthtable.ToList();
foreach (Youth y in Entyouth)
{
string youthcell = y.ContactMobile.ToString();
cell = youthcell;
cellNumbers.add(cell);
}
}
foreach(string number in cellNumbers) // send all the sms
{
string baseurl = "http://bulksms.2way.co.za/eapi/submission/send_sms/2/2.0?" +
"username=" + user + "&" +
"password=" + pass + "&" +
"message=" + mess + "&" +
"msisdn=" + number;
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(baseurl);
try
{
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
objReader = new StreamReader(objStream);
objReader.Close();
}
catch (Exception ex)
{
ex.ToString();
}
}
You have a cycle where you override cell in each iteration and even though cell received all the values you need, all were overriden by the next one, except for the very last one. When the cycle is finished, you are sending the request using the very last value of cell. This is why you had the illusion that you have got a single value. Actually you have got all the values, but made the mistake of overriding them before using them. The solution is to send the request inside the cycle instead of after the cycle, like this:
// GET: Members/SendBatch
public ActionResult SendBatch()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SendBatch(Membership member)
{
var db = new ChurchContext();
StreamReader objReader;
WebClient client = new WebClient();
string mess = member.Message;
string cell = member.Cell;
string pass = "xxxx";
string user = "xxxx";
string selectministries = member.SelectMinistries;
string pathtoministries = "";
pathtoministries = GetMinisry(selectministries);
if (pathtoministries == "Youth")
{
var youthtable = from e in db.Youths
select e;
var Entyouth = youthtable.ToList();
foreach (Youth y in Entyouth)
{
string youthcell = y.ContactMobile.ToString();
cell = youthcell;
string baseurl = "http://bulksms.2way.co.za/eapi/submission/send_sms/2/2.0?" +
"username=" + user + "&" +
"password=" + pass + "&" +
"message=" + mess + "&" +
"msisdn=" + cell;
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(baseurl);
try
{
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
objReader = new StreamReader(objStream);
objReader.Close();
}
catch (Exception ex)
{
ex.ToString();
}
return View("Index", member);
}
}
}
public static string GetMinisry(string ministry)
{
string membership = "";
switch (ministry)
{
case "Youth":
membership = "Youth";
break;
case "Children":
membership = "Children";
break;
case "Men":
membership = "Men";
break;
case "Women":
membership = "Women";
break;
case "Visitors":
membership = "Visitors";
break;
case "Members":
membership = "Members";
break;
}
return membership;
}
Thanks guys, your answers solved my problem, hope future visitors to this page with similar problem will get help quickly.
I am uploading multiple images to my folder asynchronously using XMLHttpRequest. After the all images are completely loaded to folder I need to send an email which contains these images in the email body part as well as attachment. My question is how do I check if all the images are completely uploaded to my folder. I have tried the following:
$scope.UploadFile = function (inputFile) {
var j = inputFile.length;
var filenames = [];
for (var i = 0; i < inputFile.length; i++) {
$scope.UploadFileIndividual(inputFile[i].file,
inputFile[i].file.name,
inputFile[i].file.type,
inputFile[i].file.size,
i, inputFile.length);
filenames[i] = inputFile[i].file.name;
j--;
}
if (j == 0)
{
$http({
method: 'POST',
url: '/RFQ/SendEmail/',
data: { RFQValues: $scope.RFQData, fileNames: filenames}
}).success(function (response, status, headers, config) {
if (response == true) {
window.location.href = '/CheckOut/ThankYou';
}
}).error(function (response, status, headers, config) {
// alert('Your Selection Not Added to Cart');
});
}
} ;
$scope.UploadFileIndividual = function (fileToUpload, name, type, size, index, fileArrayLength) {
var reqObj = new XMLHttpRequest();
//open the object and set method of call(get/post), url to call, isasynchronous(true/False)
reqObj.open("POST", "/RFQ/UploadFiles", true);
//set Content-Type at request header.For file upload it's value must be multipart/form-data
reqObj.setRequestHeader("Content-Type", "multipart/form-data");
//Set Other header like file name,size and type
reqObj.setRequestHeader('X-File-Name', name);
reqObj.setRequestHeader('X-File-Type', type);
reqObj.setRequestHeader('X-File-Size', size);
// send the file
reqObj.send(fileToUpload);
};
This is my controller method to upload images:
public virtual string UploadFiles(object obj)
{
try
{
var length = Request.ContentLength;
var bytes = new byte[length];
Request.InputStream.Read(bytes, 0, length);
var fileName = Request.Headers["X-File-Name"];
var fileSize = Request.Headers["X-File-Size"];
var fileType = Request.Headers["X-File-Type"];
string path = #"~\images\Client Images";
string subPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString();
string finalPath = Server.MapPath(path + #"\" + subPath);
if (!Directory.Exists(finalPath))
Directory.CreateDirectory(finalPath);
var saveToFileLoc = finalPath + #"\" + fileName;
// save the file.
var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite);
fileStream.Write(bytes, 0, length);
fileStream.Close();
var usrid = Convert.ToInt32(System.Web.HttpContext.Current.Session["UserId"].ToString());
using (DataContext _db = new DataContext())
{
int RFQId = _db.RFQDetailss.OrderByDescending(x => x.RFQId).Where(x => x.UserId == usrid && EntityFunctions.TruncateTime(x.RFQ_CreatedDate) == EntityFunctions.TruncateTime(DateTime.Now)).Select(y => y.RFQId).FirstOrDefault();
RFQClientImage objClientImage = new RFQClientImage();
objClientImage.RFQId = RFQId;
objClientImage.ImagePath = #"images\Client Images\" + subPath + #"\" + fileName;
_db.RFQClientImages.Add(objClientImage);
_db.SaveChanges();
}
return string.Format("{0} bytes uploaded", bytes.Length);
}
catch
{
return "";
}
}
I have then checked on js side if all files are sent for uploading and then in controller also I am checking if currently uploaded files exists in the folder by following code:
public JsonResult SendEmail(RFQFormInfo RFQValues, string[] fileNames)
{
bool IsMailSent = false;
try
{
string directoryPath = #"~\images\Client Images\";
string subDirectoryPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString() + #"\";
//string[] fileEntries = Directory.GetFiles(Server.MapPath(directoryPath + subDirectoryPath));
string targetPath = Server.MapPath(directoryPath + subDirectoryPath);
IsMailSent = checkifImageUploaded(RFQValues, getFilesList(targetPath), fileNames);
return Json(IsMailSent, JsonRequestBehavior.AllowGet);
}
catch
{
return Json(IsMailSent, JsonRequestBehavior.AllowGet);
}
}
public bool checkifImageUploaded(RFQFormInfo RFQValues, IEnumerable<string> fileEntries, string[] fileNames)
{
bool IsMailSent = false;
try
{
int counter = 0;
string directoryPath = #"~\images\Client Images\";
string subDirectoryPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString() + #"\";
string targetPath = Server.MapPath(directoryPath + subDirectoryPath);
foreach (string filename in fileNames)
{
var currentFile = Server.MapPath(directoryPath + subDirectoryPath + filename);
foreach(var file in fileEntries)
{
if (file.Equals(currentFile))
{
counter++;
break;
}
}
if (counter == fileNames.Length)
break;
}
if (counter == fileNames.Length)
{
IsMailSent = SendRFQMail(RFQValues, fileNames);
return IsMailSent;
}
else
checkifImageUploaded(RFQValues, getFilesList(targetPath), fileNames);
return IsMailSent;
}
catch
{
return IsMailSent;
}
}
public IEnumerable<string> getFilesList(string targetDirectory)
{
var fileEntries = Directory.EnumerateFiles(targetDirectory);
return fileEntries;
}
but my checkIfImageUploaded() function throws stack overflow exception. I understand it is because my code is ending up into infinite loop or recursion but what I don't understand is at what point is my code ending into infinite recursion and how to solve it.
Please help me out. Thanks in advance.
I was using Make directory to create a folders and subfolder in my ftp (using filezilla) works fine,but when i try to do in my test server (IIS FTP) doesn't work ,throws 550,file not found or no access.so just a quick way to change the code to create subdirctory in my ftp server works fine but i know its a kinda shitty way to do like that.
Changed my code based on #Markus
var dir = new ConsoleApplication5.Program();
string path = "ftp://1.1.1.1/testsvr01/times/" + "testfile" + "/svr01fileName";
string[] pathsplit = path.ToString().Split('/');
string Firstpath = pathsplit[0] + "/" + pathsplit[1] + "/" + pathsplit[2] + "/" + pathsplit[3] + "/";
string SecondPath = Firstpath + "/" + pathsplit[4] + "/";
string ThirdPath = SecondPath + "/" + pathsplit[5] + "/";
string[] paths = { Firstpath, SecondPath, ThirdPath };
foreach (string pat in paths)
{
bool result= dir.EnsureDirectoryExists(pat);
if (result==true)
{
//do nothing
}
else
{ //create dir
dir.createdir(pat);
}
}
upload(path,filename);
}
private bool EnsureDirectoryExists(string pat)
{
try
{
//call the method the first path is exist ?
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(pat);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential("sh", "se");
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
return true;
}
}
catch (Exception ex)
{ return false; }
}
public void createdir(string pat)
{
try
{
FtpWebRequest createdir = (FtpWebRequest)FtpWebRequest.Create(new Uri(pat));
createdir.Method = WebRequestMethods.Ftp.MakeDirectory;
createdir.Credentials = new NetworkCredential("sh", "se");
createdir.UsePassive = true;
createdir.UseBinary = true;
createdir.KeepAlive = false;
FtpWebResponse response1 = (FtpWebResponse)createdir.GetResponse();
Stream ftpStream1 = response1.GetResponseStream();
ftpStream1.Close();
response1.Close();
}
catch (Exception ex)
{
}
}
Please if any of you guys find a better way,suggest me.
That's a lot of code for ensuring a directory exists. Is there a Directory.Exists() method (or a similar method you could leverage)? Then you could call an EnsureDirectoryExists() before uploading.
private bool EnsureDirectoryExists(string path)
{
// check if it exists
if (Directory.Exists(path))
return true;
string parentPath = GetParentPath(path);
if (parentPath == null)
return false;
bool result = EnsureDirectoryExists(parentPath);
if (result)
{
CreateDirectory(path);
return true;
}
return false;
}
Disclaimer: You might need to tweak the logic a bit and use the FTP functions, but I hope you get the point.