JSON string values are getting saved without quotes - c#

I have two programs. The first program creates some JSON using Json.Net and then launches the second program, passing the JSON to it. The second program saves the JSON to a file using the SaveFileDialog from WinForms. The problem is the string values in the JSON are not saving properly.
For example, it saves
{
projectName : MY_PROJECT_NAME
}
When it should be
{
"projectName" : "MY_PROJECT_NAME"
}
Later when I'm trying to deserialize the JSON and convert to an object, I'm getting an error, but only with string values.
Here is the code that saves the file:
[STAThread]
static void Main(string[] args)
{
string seriaizedData = args[0];
Stream streamData;
SaveFileDialog savefiledialog = new SaveFileDialog();
savefiledialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Bamboo Wall";
savefiledialog.Filter = "bamboo files (*.bamboo)|*.bamboo|All files (*.*)|*.*";
savefiledialog.FilterIndex = 1;
savefiledialog.RestoreDirectory = true;
if (savefiledialog.ShowDialog() == DialogResult.OK)
{
if ((streamData = savefiledialog.OpenFile()) != null)
{
byte[] buffer = Encoding.ASCII.GetBytes(seriaizedData);
streamData.Write(buffer, 0, buffer.Length);
streamData.Close();
}
}
}
Here is the code that creates the JSON:
FloorModel grdData = GridData.gridData.gridDataClassList[GetActiveTabIndex()];
//How I get the object does not matter so much
string jsonObj = JsonConvert.SerializeObject(grdData);
print (jsonObj);
Process myProcess = new Process();
myProcess.StartInfo.FileName = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "Narnia.exe";
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProcess.StartInfo.Arguments = jsonObj;
myProcess.Start();
What am I doing wrong?

The problem is that you are passing JSON on the command line from one program to the other. Quote characters and spaces have special meaning to the command line parser, so you will need escape your JSON string judiciously if you want it to survive the command line parsing process intact. Another potential issue is the command line has a length limit, depending on what platform you are running on. So if the JSON you are trying to pass is large, it may be truncated even if you manage to escape it correctly. In short, I don't recommend this approach.
Instead, I would make your first program write the JSON to a temporary file, then pass the path of the temp file to the second program via the command line. That program can then copy the file to the correct location as specified by the user.
So, something like this:
Sending Program
FloorModel grdData = GridData.gridData.gridDataClassList[GetActiveTabIndex()];
string json = JsonConvert.SerializeObject(grdData);
string tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, json);
Process myProcess = new Process();
myProcess.StartInfo.FileName = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "Narnia.exe";
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProcess.StartInfo.Arguments = '"' + tempFile + '"';
myProcess.Start();
Receiving Program
string jsonTempFile = args[0];
try
{
SaveFileDialog savefiledialog = new SaveFileDialog();
savefiledialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Bamboo Wall";
savefiledialog.Filter = "bamboo files (*.bamboo)|*.bamboo|All files (*.*)|*.*";
savefiledialog.FilterIndex = 1;
savefiledialog.RestoreDirectory = true;
if (savefiledialog.ShowDialog() == DialogResult.OK)
{
File.Copy(jsonTempFile, savefiledialog.FileName, overwrite: true);
}
}
finally
{
File.Delete(jsonTempFile);
}

Related

When i try to delete report from the folder this error comes

The process cannot access the file because it is being used by another process
private void DeleteReport()
{
int invid = Convert.ToInt32(Session["InvId"]);
string FileName = invid + "_Report" + ".pdf";
string path1 = Server.MapPath("~/Report/" + FileName);
if (File.Exists(path1))
{
File.Delete(path1);
}
}
The error tells you, that the file is used and can't be deleted. So nothing wrong. As you did not formulate a
real question, lets try to help you in following way.
I guess that only your program is using the report, so good possible, you block the report
somewhere else.
E.g., the following code
string path = "C:\\Temp\\test.txt";
FileStream file = File.Open(path, FileMode.OpenOrCreate);
if (File.Exists(path))
File.Delete(path);
raises the same error. It does not necessarily mean that the process is another process.
What you can do is for example, for testing purpose, install SysInternal
http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx and add following code around your
File.Delete statement. Then you will see, what process uses the file:
try
{
File.Delete(path);
}
catch (Exception)
{
using (Process tool = new Process())
{
tool.StartInfo.FileName = #"C:\Program Files (x86)\SysinternalsSuite\handle.exe"; //Your path
tool.StartInfo.Arguments = path + " /accepteula";
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
string matchPattern = #"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach (Match match in Regex.Matches(outputTool, matchPattern))
{
Process p = Process.GetProcessById(int.Parse(match.Value));
MessageBox.Show(p.ProcessName); // OR LOG IT
}
}
throw;
}
Credit for handle.exe call to https://stackoverflow.com/a/1263609/2707156

How to give custom made locations for downloading the file

I just wanted to know how can i give a custom made default location for grabbing the files.
I have uploaded a file to the local database and i have binded the file to the gird also. When i press download its showing an error called "the file is not found in location"
If i copy the particular uploaded files to the specified location i can download it easily.
So i just need to know how can i give a default location so that i can upload and downlaod the file from the same exact location.
snapshot of error: https://imageshack.com/i/ewTrmAI2j
Edited the same below code with custom made folder path. But i dont know why the file is always being asked from bin/debug/ folder. WHy its happening like this. IS there any way i can make changes to this folder.. other than bin/debug/ folder
Codes:
private void DownloadAttachment(DataGridViewCell dgvCell)
{
string fileName = Convert.ToString(dgvCell.Value);
//Return if the cell is empty
if (fileName == string.Empty)
return;
FileInfo fileInfo = new FileInfo(fileName);
string fileExtension = fileInfo.Extension;
byte[] byteData = File.ReadAllBytes(fileInfo.FullName); - - - - <<<<< ERROR HERE
//show save as dialog
using (SaveFileDialog saveFileDialog1 = new SaveFileDialog())
{
//Set Save dialog properties
saveFileDialog1.Filter = "Files (*" + fileExtension + ")|*" + fileExtension;
saveFileDialog1.Title = "Save File as";
saveFileDialog1.CheckPathExists = true;
saveFileDialog1.FileName = fileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string s = cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value.ToString();
File.WriteAllBytes(saveFileDialog1.FileName, byteData);
byteData = System.Text.Encoding.ASCII.GetBytes(s);
}
}
}
The FileInfo() constructor only works with a full file path. It sounds like you are trying to use the constructor with just a file name, at which point it fails when you try to read the file because its not a valid path. There are a couple possibilities for dealing with this:
Create your own MyFileInfo() class inheriting from FileInfo() and add a constructor that appends your specific path to the filename.
Simply append the path in-line in your code as:
var myPath = #"c:\folder\stuff\";
FileInfo fileInfo = new FileInfo(myPath + fileName);
Normally the path would be setup as a setting in your app.config so you could change it easily if needed.
I found the answer
codes for the binding file path to the gridview and download the file using the file path
private void UploadAttachment(DataGridViewCell dgvCell)
{
using (OpenFileDialog fileDialog = new OpenFileDialog())
{
//Set File dialog properties
fileDialog.CheckFileExists = true;
fileDialog.CheckPathExists = true;
fileDialog.Filter = "All Files|*.*";
fileDialog.Title = "Select a file";
fileDialog.Multiselect = true;
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string strfilename = fileDialog.FileName;
cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value = strfilename;
}
}
}
/// <summary>
/// Download Attachment from the provided DataGridViewCell
/// </summary>
/// <param name="dgvCell"></param>
private void DownloadAttachment(DataGridViewCell dgvCell)
{
string fileName = Convert.ToString(dgvCell.Value);
if (!string.IsNullOrEmpty(fileName))
{
byte[] objData;
FileInfo fileInfo = new FileInfo(fileName);
string fileExtension = fileInfo.Extension;
//show save as dialog
using (SaveFileDialog saveFileDialog1 = new SaveFileDialog())
{
//Set Save dialog properties
saveFileDialog1.Filter = "Files (*" + fileExtension + ")|*" + fileExtension;
saveFileDialog1.Title = "Save File as";
saveFileDialog1.CheckPathExists = true;
saveFileDialog1.FileName = fileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string s = cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value.ToString();
objData = File.ReadAllBytes(s);
File.WriteAllBytes(saveFileDialog1.FileName, objData);
}
}
}
}
}

How to upload a filepath to local database and receive the file path when I click download button

The problem is when I am downloading the file, I can see the path in the download file. I am not getting the actual contents of the file inside.
When I am attaching a file called sample.txt and the path for sample.txt is== C:\Users\smohan\Downloads\databse\LocalDataBaseAp\sample.txt. I can see the path gets binded with my datagrid. But when I click the cell of the grid and download the same file. The file is downloading. But when I open.. The downloaded file I can see inside is missing the actual contents, but instead the path is saved as content (i.e.) C:\Users\smohan\Downloads\database\LocalDataBaseAp\sample.txt
What's wrong with my code?
private void UploadAttachment(DataGridViewCell dgvCell)
{
using (OpenFileDialog fileDialog = new OpenFileDialog())
{
//Set File dialog properties
fileDialog.CheckFileExists = true;
fileDialog.CheckPathExists = true;
fileDialog.Filter = "All Files|*.*";
fileDialog.Title = "Select a file";
fileDialog.Multiselect = true;
if (fileDialog.ShowDialog() == DialogResult.OK)
{
cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value = fileDialog.FileName;
SqlCeConnection cnn = new SqlCeConnection(Properties.Settings.Default.CncConnectionString);
//FileInfo fileInfo = new FileInfo(fileDialog.FileName);
byte[] imgData;
imgData = File.ReadAllBytes(fileDialog.FileName);}
}
}
/// <summary>
/// Download Attachment from the provided DataGridViewCell
/// </summary>
/// <param name="dgvCell"></param>
private void DownloadAttachment(DataGridViewCell dgvCell)
{
string strId = cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value.ToString();
string fileName = Convert.ToString(dgvCell.Value);
if (!string.IsNullOrEmpty(fileName))
{
byte[] objData;
FileInfo fileInfo = new FileInfo(fileName);
string fileExtension = fileInfo.Extension;
//show save as dialog
using (SaveFileDialog saveFileDialog1 = new SaveFileDialog())
{
//Set Save dialog properties
saveFileDialog1.Filter = "Files (*" + fileExtension + ")|*" + fileExtension;
saveFileDialog1.Title = "Save File as";
saveFileDialog1.CheckPathExists = true;
saveFileDialog1.FileName = fileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string s = cncInfoDataGridView.Rows[dgvCell.RowIndex].Cells[1].Value.ToString();
objData = System.Text.Encoding.ASCII.GetBytes(s);
string strFileToSave = saveFileDialog1.FileName;
File.WriteAllBytes(saveFileDialog1.FileName, objData);
}
}
}
}
}
}
I understand what you're doing now; So, here's the pertinent code part:
objData = System.Text.Encoding.ASCII.GetBytes(s);
The problem is I think you are misunderstanding what System.Text.Encoding.ASCII.GetBytes(string) does. It does not read a file's contents; it encodes the string you pass to it. So, you are writing your file path from your Grid - not the contents of the file. This is more like what you want:
objData = File.ReadAllBytes(s);
That reads all the bytes from the file at the path you pass to it, returning a byte[], as you were using.

Is it possible to retain Hyperlinks from PDF

string ghostScriptPath = #"C:\Program Files (x86)\gs\gs9.09\bin\gswin32.exe";
string inputFileName = Server.MapPath("pdf/myprofile.pdf");
string outputFileName = #"D:\";
string ars = "-dNOPAUSE -sDEVICE=jpeg -r300 -o" + output + "-%d.jpg " + input;
Process proc = new Process();
proc.StartInfo.FileName = ghostScriptPath;
proc.StartInfo.Arguments = ars;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
I'm using asp.net application with c# language. I'm using the code above to convert the PDF to images using Ghost Script. Is it possible to retain Hyperlinks from PDF?
You can use PDFParser to read the PDF as text (into a string) and then parse the string yourself for "http".
Just for completeness:
// create an instance of the pdfparser class
PDFParser pdfParser = new PDFParser();
// extract the text
String result = pdfParser.ExtractText(pdfFile);
if(result.ToLower().Contains("http"))
{
//split the string on known factors like a "\n" and "/" for ending the url.
}

C# - Copy File to new location, then read in PDF (With Code)

In the code below, the console prompts the user for 2 files (currently in a networked location). It then copies those files to the local drive for quicker reading of the PDF, but I'm running into a problem. If I reference the last line of code as PdfDocument pdf = new PdfDocument("C:\somepdf.pdf"); the file is accessed extremely quickly.
However, with the current copy processes, for some reason, this line of code alone is taking upwards of 18-20 minutes to process. I'm assuming that this is because the file, having recently been copied, is still locked under a process, even though the actual copy process takes less than 10 seconds.
In my research, I have seen various ways of identifying the process that's locking the file and killing it, but this doesn't seem to apply to what I'm trying to do.
Unfortunately, I'm to the point where I have to ask for help. Am I overlooking something here? I don't see why it would take 15 less minutes to process a pdf referenced locally, than one processed by a copy process, then locally.
Thoughts?
string selectFileNameO;
string selectFileNameF;
string FileNameO;
string FileNameF;
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "Choose File";
dialog.FileName = "";
dialog.ShowDialog();
selectFileNameO = dialog.FileName;
}
string ext = System.IO.Path.GetExtension(selectFileNameO);
selectFileNameF = Path.GetFileName(selectFileNameO);
selectFileNameF = selectFileNameF.Substring(0, selectFileNameF.Length - ext.Length);
selectFileNameF = "C:\\" + selectFileNameF + ".ext";
Console.WriteLine(selectFileNameF);
using (OpenFileDialog dialog2 = new OpenFileDialog())
{
dialog2.Title = "Choose 2 File";
dialog2.FileName = "";
dialog2.ShowDialog();
FileNameO = dialog2.FileName;
}
string ext1 = System.IO.Path.GetExtension(FileNameO);
FileNameF = Path.GetFileName(FileNameO);
FileNameF = FileNameF.Substring(0, FileNameF.Length - ext1.Length);
FileNameF = "C:\\" + FileNameF + ".ext";
File.Copy(FileNameO, FileNameF, true);
int distanceToString = 535;
int lengthOfString = 6;
string myDataSet;
using (StreamReader sr = new StreamReader(selectFileNameF))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
myDataSet = line.Substring(distanceToString, lengthOfString);
selectFileUIDs.Add(myDataSet);
Console.WriteLine(myDataSet);
}
sr.Dispose();
}
Console.WriteLine(FileNameF);
PdfDocument pdf = new PdfDocument(FileNameF);

Categories

Resources