how to store and retrieve multiple values inside single session variable - c#

i am using dropzone to upload multiple files to the server. files will be uploaded to server while file names will be stored in table.
i am trying to add file names in session.
the problem here is that it doesn't add multiple file names inside single session
here is my code :
string imageSessList = context.Session["imageNames"].ToString(); //if i put this line at the begining, then the debugger doesn't even moves to foreach block
foreach (string s in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[s];
string fileName = file.FileName;
string fileExtension = file.ContentType;
string strUploadFileExtension = fileName.Substring(fileName.LastIndexOf(".") + 1);
string strAllowedFileTypes = "***jpg***jpeg***png***gif***bmp***"; //allowed file types
string destFileName = "";
List<string> lstImageNames = new List<string>();
// else upload file
if (!string.IsNullOrEmpty(fileName))
{
if (strAllowedFileTypes.IndexOf("***" + strUploadFileExtension + "***") != -1) //check extension
{
if (context.Request.Files[0].ContentLength < 5 * 1024 * 1024) //check filesize
{
// generate file name
destFileName = Guid.NewGuid().ToString() + "." + strUploadFileExtension;
string destFilePath = HttpContext.Current.Server.MapPath("/resourceContent/") + destFileName;
//Save image names to session
lstImageNames.Add(destFileName);
context.Session["imageNames"] = lstImageNames;
file.SaveAs(destFilePath);
strMessage = "Success " + destFileName;
}
else
{
strMessage = "File Size can't be more than 5 MB.";
}
}
else
{
strMessage = "File type not supported!";
}
}
} // foreach
context.Response.Write(strMessage);
}
here i am able to add only single filename to session, not multiple.
how to store and maintain multiple file names in single session :
context.Session["imageNames"]

you need to get current list from session
List<string> lstImageNames= (List<string>)Session["imageNames"];
if(lstImageNames==null)
lstImageNames = new List<string>(); // create new list in the first time
now add new item to it.
lstImageNames.Add(destFileName);
set back to session
context.Session["imageNames"] = lstImageNames;

Related

Every time writes new file in c#

I am working on a c# console application. I am saving some data into a text file. Every time the programs are run it saves the data into that file without overwriting into it. Now I want to save the data into a new file every time I send a request/runs the new program.
var result = XmlDecode(soapResult);
XDocument doc = XDocument.Parse(result);
XmlReader read = doc.CreateReader();
DataSet ds = new DataSet();
ds.ReadXml(read);
read.Close();
if (ds.Tables.Count > 0 && ds.Tables["Reply"] != null && ds.Tables["Reply"].Rows.Count > 0)
{
string refNo = string.Empty;
string uniqueKey = string.Empty;
string meterNo = string.Empty;
List<string> ls = new List<string>();
if (ds.Tables["Reply"].Rows[0][0].ToString().ToUpper() == "OK")
{
if (ds.Tables["Names"] != null && ds.Tables["Names"].Rows.Count > 0)
{
uniqueKey = ds.Tables["Names"].Rows[0]["name"].ToString();
}
if (ds.Tables["NameType"] != null && ds.Tables["NameType"].Rows.Count > 0)
{
refNo = ds.Tables["NameType"].Rows[0]["name"].ToString();
}
if (ds.Tables["Meter"] != null && ds.Tables["Meter"].Rows.Count > 0)
{
if (ds.Tables["Meter"].Columns.Contains("mRID"))
{
meterNo = ds.Tables["Meter"].Rows[0]["mRID"].ToString();
processedRec++;
}
}
}
log = uniqueKey + " | " + refNo + " | " + meterNo + " | " + Environment.NewLine;
ls.Add(log);
}
File.AppendAllText(filePath, log);
How can I create a new file every time?
Any help would be highly appreciated.
Make a unique filePath. Something like this:
var filePath =$"{folderPath}\txtFile_{Guid.NewGuid()}";
This will make the file to be always unique. The guid can be replaced with something more meaningful like Unix Timestamp as well.
Create a custom file name every time and make use of File.WriteAllText (which will Creates a new file, write the contents to the file, and then closes the file. If the target file already exists, it is overwritten.) instead for File.AppendAllText
In your case the filePath should be dynamic which can be construct like this:
string basePath = ""; // this should be path to your directory in which you wanted to create the output files
string extension = ".xml";
string fileName = String.Format("{0}{1}{2}","MyFile",DateTime.Now.ToString("ddMMyy_hhmmss"),extension );
string filePath = Path.Combine(basePath,fileName);
In the above snippet the DateTime.Now.ToString("ddMMyy_hhmmss") will be the current time(at the time of execution of the code) which will be differ in each execution so the file name will differ in each run. And at some later points you can search/group files based on these common pattern.
One more thing:
In your code you have used a variable List<string> ls which is populated with all logs, and you are writing the the contents of log to the file, which contains only the last record. So the statement for writing the content should be:
File.WriteAllText(filePath, String.Join("\n",log));
or even simply
File.WriteAllLines(filePath, log);
simply make your filePath unique, for example by using Ticks
var filePath = $"app-log-{DateTime.Now.Ticks:X}.log";

Moving files using SSIS and Script Component

I need to write a code in script component in SSIS that will move files to corresponding folders. Files that I'm getting are usually named, for example "Dem323_04265.45.23.4", "Dem65_459.452.56", "Ec2345_456.156.7894" and I need to move them to a corresponding folders. The name of my folders are "Oklahoma City (323)", "New York(65)".. I need to move those files to matching folders, so for example "Dem323_04265.45.23.4" would go to folder "Oklahoma City (323)". I need to modify my code so the number that is located between first two or three letter and underline matches number located in parenthesis. I've been working on this for several days already and I'm new with ssis and c#, so any help would be appreciated. This is the code I have so far:
public void Main()
{
string filename;
// string datepart;
bool FolderExistFlg;
filename = Dts.Variables["User::FileName"].Value.ToString();
// datepart = (filename.Substring(filename.Length - 12)).Substring(0, 8);
var folderNumber = Regex.Match(
filename,
//Dts.Variables["OutputMainFolder"].Value.ToString(),
#"\(([^)]*)\)").Groups[1].Value;
FolderExistFlg = Directory.Exists(Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + folderNumber);
if (!FolderExistFlg)
{
Directory.CreateDirectory(Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + folderNumber);
}
File.Move(Dts.Variables["SourceFolder"].Value.ToString() + "\\" + filename + "\\" + folderNumber,
Dts.Variables["OutputMainFolder"].Value.ToString() + "\\" + filename);
Dts.TaskResult = (int)ScriptResults.Success;
}
#region ScriptResults declaration
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
Here you go, the below snippet would move the files as per the match criteria. You need to take care of the source input as per your configuration.
string filePath = #"C:\Packages\StackOverflow";
//string fileName = string.Empty;
//get list of files
string[] filePaths = Directory.GetFiles(filePath);
//get list of folders
string[] dirPaths = Directory.GetDirectories(filePath);
//loop through the files and move them
foreach(string fileNames in filePaths)
{
string[] pathArr = fileNames.Split('\\');
string fileName = pathArr.Last().ToString();
int index = fileName.IndexOf('_');
string fileNamePart = fileName.Substring(0, index);
//get the first numeric part of the filename to perform the match
var fileNameNumPart = Regex.Replace(fileNamePart, "[^0-9]", "");
//find related directory
var dirMatch = dirPaths.FirstOrDefault(stringToCheck => stringToCheck.Contains(fileNameNumPart.ToString()));
if (dirMatch != null)
{
// move would fail if file already exists in destination
if (!File.Exists(dirMatch + '\\' + fileName))
{
File.Move(fileNames, dirMatch + '\\' + fileName);
}
}
}

FileUpload if exist concat (counter) to the name [duplicate]

This question already has answers here:
FileUpload - if file name exist concat a number between parentheses at the end of name
(3 answers)
Closed 5 years ago.
I have a fileupload control, What I want to achieve is to concat a nuber to it, in order it to be unique.
All the posts that I found are talking about adding a GUID or DateTime
What i want to achieve is if the file exist in folder then the file name will be filename + (counter)
Example:
The folder contain a file name- file.png
1) When I upload the same file name again, the existing one wont get delete and the new one will be called file(1).png.
2) When I upload the same file name again, (file.png)
now the new file will be called file(2)
I have this code which handle the 1'st case but not the second:
public static string GetUniqueName(string fileName)
{
string dir = Globals.Directories.GetCustomCategoryThumbnailDir();
string fileExtension = Path.GetExtension(fileName);
string fileNameWE = Path.GetFileNameWithoutExtension(fileName);
string[] files = Directory.GetFiles(dir, "*" + fileExtension)
.Select(Path.GetFileName)
.ToArray();
string uniqueName = fileNameWE;
int nextNum = 0;
bool fileExist = false;
string pattern = #"(.*)\(([\d]+)\)";
foreach (var file in files)
{
var tempFileName = Path.GetFileNameWithoutExtension(file);
var match = Regex.Match(tempFileName, pattern);
if (tempFileName.Equals(fileNameWE))
{
// file exist in folder
fileExist = true;
}
if (tempFileName.StartsWith(fileNameWE) && match.Success)
{
// there is a file name that start with "fileToUpload" name, we want to to take the number
nextNum = Convert.ToInt32(match.Groups[2].Value);
nextNum++;
}
}
if (nextNum == 0 && !fileExist)
{
// filename dont exist
return fileNameWE + fileExtension;
}
if (nextNum == 0 && fileExist)
{
// the file name exist without (1)
fileNameWE = $"{fileNameWE}(1)";
return fileNameWE + fileExtension;
}
else
{
var haveParentessis = Regex.Match(fileNameWE, pattern);
if (haveParentessis.Success)
{
// we need to reset the nextNum
nextNum = 1;
}
// return the new unique name with suffix
fileNameWE = string.Format("{0}({1})", fileNameWE, nextNum);
return fileNameWE + fileExtension;
}
}
How can I achieve that?
Yeah, that's cause your while loop as pointed below is local to the function and thus the counter variable which is also a local variable won't be maintained it's current value. So in essence every request you get a new page instance and thus your counter will get re-initialized to 0
while (File.Exists(Path.Combine(dir, fileNameWE + fileExtension)))
{
fileNameWE = fileNameWE + "(" + counter.ToString() + ")";
counter++;
}
To get this done, you should store the counter variable in Session and retrieve it back. Don't forget it's an web application and thus the state won't be maintained unless you do it explicitly
if (File.Exists(Path.Combine(dir, fileNameWE + fileExtension)))
{
counter = (Session["counter"] != null) ? ((int)Session["counter"])++ : default(int);
fileNameWE = fileNameWE + "(" + counter.ToString() + ")";
Session["counter"] = counter;
}
I got this to work by using regular expressions, below. No persistent counter is required. I think the concat problem is because there's nothing done to deal with the existing (1) suffix. I coded this potential solution and hope it helps! NB: only lightly tested in debugger, and I am a novice
{
string fileName = #"C:\Uploads\Testfile.bin";
string fileExtension = Path.GetExtension(fileName);
string fileNameWE = Path.GetFileNameWithoutExtension(fileName);
string pattern = #"(.*)\(([\d]+)\)$";
var match = Regex.Match(fileNameWE, pattern);
if (match.Success)
{
int nextNum = Convert.ToInt32(match.Groups[2].Value);
nextNum++;
fileNameWE = $"{match.Groups[1].Value}({nextNum})";
}
else
{
fileNameWE = $"{fileNameWE}(1)";
}
}

How to copy file from one library to another library using CSOM?

I need to copy a particular file from one library to another library.
At first, need to check if file is existing in that library.
If Existing, then need to overwrite file content and new sharepoint version should be updated for that document.
I need to do this using c# CSOM and sharepoint version is 2013.
Thanks in advance :)
public static void CopyDocuments(string srcUrl, string destUrl, string srcLibrary, string destLibrary, Login _login)
{
// set up the src client
SP.ClientContext srcContext = new SP.ClientContext(srcUrl);
srcContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
srcContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// set up the destination context (in your case there is no needs to create a new context, because it would be the same library!!!!)
SP.ClientContext destContext = new SP.ClientContext(destUrl);
destContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
destContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// get the list and items
SP.Web srcWeb = srcContext.Web;
SP.List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
SP.ListItemCollection col = srcList.GetItems(new SP.CamlQuery());
srcContext.Load(col);
srcContext.ExecuteQuery();
// get the new list
SP.Web destWeb = destContext.Web;
destContext.Load(destWeb);
destContext.ExecuteQuery();
foreach (var doc in col)
{
try
{
if (doc.FileSystemObjectType == SP.FileSystemObjectType.File)
{
// get the file
SP.File f = doc.File;
srcContext.Load(f);
srcContext.ExecuteQuery();
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
if (doc.FileSystemObjectType == SP.FileSystemObjectType.Folder)
{
// load the folder
srcContext.Load(doc);
srcContext.ExecuteQuery();
// get the folder data, get the file collection in the folder
SP.Folder folder = srcWeb.GetFolderByServerRelativeUrl(doc.FieldValues["FileRef"].ToString());
SP.FileCollection fileCol = folder.Files;
// load everyting so we can access it
srcContext.Load(folder);
srcContext.Load(fileCol);
srcContext.ExecuteQuery();
foreach (SP.File f in fileCol)
{
// load the file
srcContext.Load(f);
srcContext.ExecuteQuery();
string[] parts = null;
string id = null;
if (srcLibrary == "My Files")
{
// these are doc sets
parts = f.ServerRelativeUrl.Split('/');
id = parts[parts.Length - 2];
}
else
{
id = folder.Name;
}
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + id + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
}
}
catch (Exception ex)
{
Log("File Error = " + ex.ToString());
}
}
}
Source: https://sharepoint.stackexchange.com/questions/114033/how-do-i-move-files-from-one-document-library-to-another-using-jsom
I strongly advise against using the approach suggested by Nikerym. You don't want to download the bytes only to upload them unmodified. It's slow and error-prone. Instead, use the built-in method provided by the CSOM API.
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt162553(v=office.15)?redirectedfrom=MSDN
var srcPath = "https://YOUR.sharepoint.com/sites/xxx/SitePages/Page.aspx";
var destPath = $"https://YOUR.sharepoint.com/sites/xxx/SitePages/CopiedPage.aspx";
MoveCopyUtil.CopyFileByPath(ctx, ResourcePath.FromDecodedUrl(srcPath), ResourcePath.FromDecodedUrl(destPath), false, new MoveCopyOptions());
ctx.ExecuteQuery();
You can configure the override behavior by adjusting the 4th and 5th arguments of the function signature.
[...]
bool overwrite,
MoveCopyOptions options
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt844930(v=office.15)

c# service renaming files!

I have a windows service , that takes files with metadata(FIDEF) and corresponding video file and , translates the XML(FIDEF) using XSLT .
I get the file directory listing for FIDEF's and if a video file of the same name exists it translates it. That works ok , but it is on a timer to search every minute. I am trying to handle situations where the same file name enters the input directory but is already in the output directory. I just have it changing the output name to (copy) thus if another file enters i should get (copy)(copy).mov but the service won't start with filenames of the same directory already in the output , it works once and then does not seem to pick up any new files.
Any Help would be great as I have tried a few things with no good results. I believe its the renaming methods, but I've put most of the code up in case its a clean up issue or something else.
(forgive some of the names just trying different things).
private void getFileList()
{
//Get FILE LIST FROM Directory
try
{
// Process Each String/File In Directory
string result;
//string filename;
filepaths = null;
filepaths = Directory.GetFiles(path, Filetype);
foreach (string s in filepaths)
{
for (int i = 0; i < filepaths.Length; i++)
{
//Result Returns Video Name
result = Path.GetFileNameWithoutExtension(filepaths[i]);
FileInfo f = new FileInfo(filepaths[i]);
PreformTranslation(f, outputPath + result , result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error " + e);
}
}
private void MoveVideoFiles(String Input, String Output)
{
File.Move(Input, Output);
}
private string GetUniqueName(string name)
{
//Original Filename
String ValidName = name;
//remove FIDEF from filename
String Justname1 = Path.GetFileNameWithoutExtension(name);
//get .mov extension
String Extension2 = Path.GetExtension(Justname1);
//get filename with NO extensions
String Justname = Path.GetFileNameWithoutExtension(Justname1);
//get .Fidef
String Extension = Path.GetExtension(name);
int cnt = 0;
//string[] FileName = Justname.Split('(');
//string Name = FileName[0];
while (File.Exists(ValidName)==true)
{
ValidName = outputPath + Justname + "(Copy)" + Extension2 + Extension;
cnt++;
}
return ValidName;
}
private string getMovFile(string name)
{
String ValidName = name;
String Ext = Path.GetExtension(name);
String JustName = Path.GetFileNameWithoutExtension(name);
while(File.Exists(ValidName))
{
ValidName = outputPath + JustName + "(Copy)" + Ext;
}
return ValidName;
}
//Preforms the translation requires XSL & FIDEF name.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
string FidefName = OutputFileName + ".FIDEF";
String CopyName;
String copyVidName = outputPath + result;
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
try
{
myXslTransform.Load(XSLname);
}
catch
{
EventLog.WriteEntry("Error in loading XSL");
}
try
{ //only process FIDEF's with corresponding Video file
if (AllFidef == "no")
{
//Check if video exists if yes,
if (File.Exists(path + result))
{
//Check for FIDEF File Already Existing in the Output Directory.
if (File.Exists(FidefName))
{
//Get unique name
CopyName = GetUniqueName(FidefName);
copyVidName= getMovFile(copyVidName);
//Translate and create new FIDEF.
//double checking the file is here
if (File.Exists(outputPath + result))
{
myXslTransform.Transform(FileName.ToString(), CopyName);
File.Delete(FileName.ToString());
MoveVideoFiles(path + result, copyVidName);
}
////Move Video file with Corresponding Name.
}
else
{ //If no duplicate file exsists in Directory just move.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
MoveVideoFiles(path + result, outputPath + result);
}
}
}
else
{
//Must have FIDEF extension
//Processes All FIDEFS and moves any video files if found.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error Transforming " + "FILENAME = " + FileName.ToString()
+ " OUTPUT_FILENAME = " + OutputFileName + "\r\n" +"\r\n"+ e);
}
}
There is a lot wrong with your code. getFileList has the unneeded inner for loop for starters. Get rid of it. Your foreach loop has s, which can replace filepaths[i] from your for loop. Also, don't do outputPath + result to make file paths. Use Path.Combine(outputPath, result) instead, since Path.Combine handles directory characters for you. Also, you need to come up with a better name for getFileList, since that is not what the method does at all. Do not make your method names liars.
I would simply get rid of MoveVideoFiles. The compiler just might too.
GetUniqueName only works if your file name is of the form name.mov.fidef, which I'm assuming it is. You really need better variable names though, otherwise it will be a maintenance nightware later on. I would get rid of the == true in the while loop condition, but that is optional. The assignment inside the while is why your files get overwritten. You always generate the same name (something(Copy).mov.fidef), and as far as I can see, if the file exists, I think you blow the stack looping forever. You need to fix that loop to generate a new name (and don't forget Path.Combine). Maybe something like this (note this is untested):
int copyCount = 0;
while (File.Exists(ValidName))
{
const string CopyName = "(Copy)";
string copyString = copyCount == 0 ? CopyName : (CopyName + "(" + copyCount + ")");
string tempName = Justname + copyString + Extension2 + Extension;
ValidName = Path.Combine(outputPath, tempName);
copyCount++;
}
This generates something(Copy).mov.fidef for the first copy, something(Copy)(2).mov.fidef for the second, and so on. Maybe not what you want, but you can make adjustments.
At this point you have a lot to do. getMovFile looks as though it could use work in the same manner as GetUniqueName. You'll figure it out. Good luck.

Categories