How I can create file on Xamarin.ios (PHP Session) - c#

i need to create a (.txt) file on my application root on Xamarin.ios, so a need to store in memory a String, contain a UserName, after the user logged in, I can use each String to run a "httprequest" to my mySql database online. Similar procedure to the sessions in PHP, but client side and in C#.. Thanks you. I just try, with cookie, but I need to access at the UserName in every class and in every storyBoard.
I just try to write a JSON file serializable:
String NU = "NomeUtente=" + NomeUtente.Text;
string json = JsonConvert.SerializeObject(NU, Formatting.Indented);
System.IO.File.WriteAllText(#"/558gt.txt", json);
but Xamarin.ios throw a exception:
SystemUnauthorizedAccessexception -->
access to the path /558gt.txt denied.

If you need store data, use Xamarin.Essentials.SecureStorage
Check documentation

Thanks you. I read the documents on the ios file system and managed to write the portion of code necessary for reading and writing the Session file containing the username.
try {
//creo il file nella sandbox maledetta di iOS
//create file Session
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine(documents, "Session.txt");
//filename contiene la path completa di dove sta il file
File.WriteAllText(filename, NomeUtente.Text);
}
catch (Exception) {
label1.Text = "Errore generico.";
}
and now I read the file, in a separated class and storyboard:
//Recupero il nomeutente
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine(documents, "Session.txt");
var NomeUtente = File.ReadAllText(filename); //contiene il NomeUtente

Related

Can I store an Ini file in a Resources file?

I have a Windows Forms application, .Net Framework 4.6.1, and I want to store some DB connection data in an Ini file.
I then wanted to store it in the Resources file of the project (so I don't have to copy/paste the file in the Debug and Release folder manually, etc.) as a normal file, but when I tried to compile the program and read the Ini data with ini-parser, the following exception showed up: System.ArgumentException: 'Invalid characters in path access'.
I'm using Properties.Resources where I read the Ini file, so I guessed there would be no problem with the path. Could it be a problem with the Ini file itself?
The content of the Ini file is the following:
[Db]
host = (anIP)
port = (aPort)
db = (aDbName)
user = (aDbUser)
password = (aDbUserPwd)
And my method for reading the data:
public static void ParseIniData()
{
var parser = new FileIniDataParser();
IniData data = parser.ReadFile(Properties.Resources.dbc);
mysqlHost = data["Db"]["host"];
mysqlPort = data["Db"]["port"];
mysqlDb = data["Db"]["db"];
mysqlUser = data["Db"]["user"];
mysqlPwd = data["Db"]["password"];
}
I finally could do it using what #KlausGütter told me in the comments (thanks!).
Instead of using the FileIniDataParser you have to use the StreamIniDataParser, and get the Stream with Assembly.GetManifestResourceStream.
I found this a bit tricky, because using this method you need to set the Build Action in the file you want to read to Embedded Resource.
This file is then added as an embedded resource in compile time and you can retrieve its stream.
So my method ended up the following way:
public static void ParseIniData()
{
var parser = new StreamIniDataParser();
dbcReader = new StreamReader(_Assembly.GetManifestResourceStream("NewsEditor.Resources.dbc.ini"));
IniData data = parser.ReadData(dbcReader);
mysqlHost = data["Db"]["host"];
mysqlPort = data["Db"]["port"];
mysqlDb = data["Db"]["db"];
mysqlUser = data["Db"]["user"];
mysqlPwd = data["Db"]["password"];
}
where _Assembly is a private static attribute: private static Assembly _Assembly = Assembly.GetExecutingAssembly();. This gets you the assembly that's being executed when running the code (you could also use this code directly in the method, but I used the Assembly on another method in my class, so I decided to set an attribute... DRY I guess).

Why is my download from Azure storage empty?

I can connect to the Azure Storage account and can even upload a file, but when I go to download the file using DownloadToFileAsync() I get a 0kb file as a result.
I have checked and the "CloudFileDirectory" and the "CloudFile" fields are all correct, which means the connection with Azure is solid. I can even write the output from the file to the console, but I cannot seem to save it as a file.
public static string PullFromAzureStorage(string azureFileConn, string remoteFileName, string clientID)
{
var localDirectory = #"C:\cod\clients\" + clientID + #"\ftp\";
var localFileName = clientID + "_xxx_" + remoteFileName;
//Retrieve storage account from connection string
var storageAccount = CloudStorageAccount.Parse(azureFileConn);
var client = storageAccount.CreateCloudFileClient();
var share = client.GetShareReference("testing");
// Get a reference to the root directory for the share
CloudFileDirectory rootDir = share.GetRootDirectoryReference();
//Get a ref to client folder
CloudFileDirectory cloudFileDirectory = rootDir.GetDirectoryReference(clientID);
// Get a reference to the directory we created previously
CloudFileDirectory unprocessed = cloudFileDirectory.GetDirectoryReference("Unprocessed");
// Get a reference to the file
CloudFile sourceFile = unprocessed.GetFileReference(remoteFileName);
//write to console and log
Console.WriteLine("Downloading file: " + remoteFileName);
LogWriter.LogWrite("Downloading file: " + remoteFileName);
//Console.WriteLine(sourceFile.DownloadTextAsync().Result);
sourceFile.DownloadToFileAsync(Path.Combine(localDirectory, localFileName), FileMode.Create);
//write to console and log
Console.WriteLine("Download Successful!");
LogWriter.LogWrite("Download Successful!");
//delete remote file after download
//sftp.DeleteFile(remoteDirectory + remoteFileName);
return localFileName;
}
In the commented out line of code where you write the output to the Console, you explicitly use .Result because you're calling an async method in a synchronous one. You should either also do so while downloading the file as well, or make the entire method around it async.
The first solution would look something like this:
sourceFile.DownloadToFileAsync(Path.Combine(localDirectory, localFileName), FileMode.Create).Result();
EDIT:
As far as the difference with the comment, that uses GetAwaiter().GetResult(), goes: .Result wraps any exception that might occur in an AggregateException, while GetAwaiter().GetResult() won't. Anyhow: if there's any possibility you can refactor the method to be async so you can use await: please do so.

Save XML File in Project Folder

try
{
XElement contactsFromFile = XElement.Load("App_Data/EmployeeFinList.xml");
var xEle = new XElement("Employees",
from emp in ListFromBasicPay
select new XElement("Employee",
new XAttribute("EmpID", emp.employee_personal_id),
new XElement("GrandTotal", emp.grandTotal),
new XElement("Housing", emp.housing),
new XElement("BasePay", emp.base_pay),
new XElement("XchangeRate", emp.Exchange_rate)));
xEle.Save("..\\changesetDB.xml");
Debug.WriteLine("Converted to XML");
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
I want to save the xml file in a folder i created in my project. I will then use that xml file created in my folder and read and write from it. Any idea how to do it?
Use System.Reflection.Assembly.GetExecutingAssembly().Location
To get the full path of you assembly, Combine that with System.IO.Path.GetDirectoryName().
That would be like:
String path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
xEle.Save(path + #"\myfilename.xml");
Though you should note that if your application is installed in C:\Program Files for example, you'll need some sort of elevation permissions to be able to write there depending on the security settings of the machine your app has been deployed on. It is best to always have a work directory in some other location like (Application Data) for example..
Use Red Serpent's answer for getting your project's folder:
String path = System.IO.Path.GetDirectoryName
(System.Reflection.Assembly.GetExecutingAssembly().Location);
Then use:
string mySavePath = Path.Combine(path, myFolder);
string myXMLPath = Path.Combine(SavePath,"changesetDB.xml");
You can then use myXMLPath to read and write from XML file you just created.

C# Path Problem

I have this file: C:\Documents and Settings\extryasam\My Documents\Visual Studio 2010\Projects\FCR\WebApplication4\config\roles.txt and I want to import it into my C# application. If I insert the full path it's ok, but I want to do something similar to what we do with websites, and that is "\config\roles.txt"
However with the below code, this is not working.
This is my code:
public string authenticate()
{
WindowsIdentity curIdentity = WindowsIdentity.GetCurrent();
WindowsPrincipal myPrincipal = new WindowsPrincipal(curIdentity);
//String role = "NT\\Internet Users";
//string filePath = Server.MapPath("config/roles.txt");
//string filePath = (#"~/WebApplication4/config/roles.txt");
//string filePath = Path.GetDirectoryName(#"\config\roles.txt");
string filePath = Path.GetPathRoot(#"/config/roles.txt");
string line;
string role = "";
if (File.Exists(filePath))
{
StreamReader file = null;
try
{
file = new StreamReader(filePath);
while ((line = file.ReadLine()) != null)
{
role = line;
}
}
finally
{
if (file != null)
{
file.Close();
}
}
}
if (!myPrincipal.IsInRole(#role))
{
return "401.aspx";
}
else
{
return "#";
}
}
In ASP.NET, you can use ~/config/roles.txt - in combination with Server.MapPath(), you can get the full path.
[...] ASP.NET includes the Web application root operator (~), which
you can use when specifying a path in server controls. ASP.NET
resolves the ~ operator to the root of the current application. You
can use the ~ operator in conjunction with folders to specify a path
that is based on the current root.
(see http://msdn.microsoft.com/en-us/library/ms178116.aspx)
So you could try the following:
string filePath = System.Web.HttpContext.Current.Server.MapPath("~/config/roles.txt");
You can use Server.MapPath to map the specified relative or virtual path to the corresponding physical directory on the server.
Since you are working locally you can use absolute path to that file and it's will works.
But what about situation when web application that contains roles.txt file will be deployed on some web server and user will try to access this file from another machine?
You can use the approach below to access file hosted on a web server from a Windows application:
using (var stream = new WebClient().OpenRead("your_web_application_root_url/configs/roles.txt"))
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
Be warned that share security settings over network is not quite good idea.
You should select your file and press F4, and choose copy to output directory. Then you will be able to work with it
You could try embedding the file as a resource in your project. Something like this: How to embed a text file in a .NET assembly?

IManExt ImportCmd trouble

I have been writing a small application using C# to copy a document into an individuals 'My Documents' folder on our DMS server.
I've beased the code around the listing provided in the 'WorkSite SDK 8: Utilize the IMANEXT2Lib.IManRefileCmd to File New Document Folders' blog.
Using this code in a WinForm application I have no problems copying the file from the source folder into the users DMS 'My Documents' folder.
However if I use the code in a command line application/.dll or any other type of application (other than WinForm) during the copy process I receive the error messages;
1.
Error occurred when try to log the event!
IManExt: Error occurred when try to log the event!
Access is denied.
2.
The document was imported to the database, but could not be added to
the folder.
IManExt: The document was imported to the database, but could not be
added to the folder.
IManExt.LogRuleEventsCmd.1: Error occurred when try to log the event!
IManExt.LogRuleEventsCmd.1: Access is denied.
Error occurred when try to log the event!
-%-
Does anyone know why I'd receiving the 'Access Denied' error messages when using a non-WinForms application to copy documents?
What would I need to do to get around this issue?
Any help would be amazing!
Code in place:
public void moveToDMS(String servName, String dBName, String foldName)
{
const string SERVERNAME = servName; //Server name
const string DATABASENAME = dBName; //Database name
const string FOLDERNAME = foldName; //Matter alias of workspace
IManDMS dms = new ManDMSClass();
IManSession sess = dms.Sessions.Add(SERVERNAME);
sess.TrustedLogin();
//Get destination database.
IManDatabase db = sess.Databases.ItemByName(DATABASENAME);
//Get destination folder by folder and owner name.
IManFolderSearchParameters fparms = dms.CreateFolderSearchParameters();
fparms.Add(imFolderAttributeID.imFolderOwner, sess.UserID);
fparms.Add(imFolderAttributeID.imFolderName, FOLDERNAME);
//Build a database list in which to search.
ManStrings dblist = new ManStringsClass();
dblist.Add(db.Name);
IManFolders results = sess.WorkArea.SearchFolders(dblist, fparms);
if (results.Empty == true)
{
//No results returned based on the search criteria.
Console.WriteLine("NO RESULTS FOUND!");
}
IManDocumentFolder fldr = null;
if (results.Empty == false)
{
//Assuming there is only one workspace returned from the results.
fldr = (IManDocumentFolder)results.ItemByIndex(1);
}
if (fldr != null)
{
// Import file path
string docPath = #"C:\Temp\";
string docName = "MyWord.doc";
// Create an instance of the ContextItems Collection Object.
ContextItems context = new ContextItemsClass();
// Invoke ImportCmd to import a new document to WorkSite database.
ImportCmd impCmd = new ImportCmdClass();
// The WorkSite object you pass in can be a database, session, or folder.
// Depends on in where you want the imported doc to be stored.
context.Add("IManDestinationObject", fldr); //The destination folder.
// Filename set here is used for easy example, a string variable is normally used here
context.Add("IManExt.Import.FileName", docPath + docName);
// Document Author
context.Add("IManExt.Import.DocAuthor", sess.UserID); //Example of a application type.
// Document Class
context.Add("IManExt.Import.DocClass", "BLANK"); //Example of a document class.
//context.Add("IManExt.Import.DocClass", "DOC"); //Example of a document class.
// Document Description (optional)
context.Add("IManExt.Import.DocDescription", docName); //Using file path as example of a description.
// Skip UI
context.Add("IManExt.NewProfile.ProfileNoUI", true);
impCmd.Initialize(context);
impCmd.Update();
if (impCmd.Status == (int)CommandStatus.nrActiveCommand)
{
impCmd.Execute();
bool brefresh = (bool)context.Item("IManExt.Refresh");
if (brefresh == true)
{
//Succeeded in importing a document to WorkSite
IManDocument doc = (IManDocument)context.Item("ImportedDocument");
//Succeeded in filing the new folder under the folder.
Console.WriteLine("New document number, " + doc.Number + ", is successfully filed to " + fldr.Name + " folder.");
}
}
}
}
Just in case this helps someone else.
It seems my issue was the result of a threading issue.
I noticed the C# winform apps I had created were automatically set to run on a single 'ApartmentState' thread ([STAThread]).
Whereas the console applications & class library thread state and management hadn't been defined within the project and was being handled with the default .NET config.
To get this to work: In the console application, I just added the [STAThread] tag on the line above my Main method call.
In the class library, I defined a thread for the function referencing the IMANxxx.dll and set ApartmentState e.g.
Thread t = new Thread(new ThreadStart(PerformSearchAndMove));
t.SetApartmentState(ApartmentState.STA);
t.Start();
In both cases ensuring single 'ApartmentState' thread was implemented set would resolve the issue.

Categories