Read .xml file from project directory in Xamarin project - c#

I have difficulty in reading the .xml file from Xamarin project. Whenever I debug my code I get below error
Could not find a part of the path "/storage/emulated/0/Xml/SupportedTypes.xml".
Below is the code what I am using
public static void Initialize(ConnectedDeviceCommType type)
{
string fileName = #"Xml\SupportedTypes.xml";
string filePath = Path.Combine(OS.Environment.ExternalStorageDirectory.ToString(), fileName);
try
{
var xml = XDocument.Load(filePath);
}
catch(Exception ex)
{
string st = ex.Message;
}
}
I have read that in some of the blogs that they say the .xml file needs to add to the Asset folder but in my case, I don't have any Asset folder in my project and The project I am trying to load is not an activity as well.
So can you please tell me is there any approach to read XML files directly in XAMARIN?

I finally made it work Thanks to Dimitris.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/files?tabs=windows

I don't really understand why you want to keep your xml file on your directrory. Because ,if you release your application, you probably won't set up the same directory structure as development. I suggest putting the files in the same folder as the application. Below the code can helps you to access your xml file from directory.
string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SupportedTypes.xml");

Related

Hide Json file containing GOOGLE_APPLICATION_CREDENTIALS when building executable file in Visualstudio [SOLVED]

currently I am developing a tool that interacts with a Firebase Firestore database. When I want to make the C# Forms Application an executable file I get the .exe but also the json file which contains the Google App Credentials. However, I want to forward the tool so that you can't see the json file or read the contents of the file, so you only need the .exe file. Is there a way to achieve this? For example, define the app credentials in a C# script so that it compiles to the .exe file? If so how?
My current implementation looks like this:
string path = AppDomain.CurrentDomain.BaseDirectory + #"cloudfire.json";
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", path);
The cloudfire.json file is directly contained in the namespace "LUX".
I also tried making the cloudfire.json file a resource, since i read this post but then the problem is, that i can't set the path of the .json, if i try it like that:
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("cloudfire.json"));
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", resourceName);
I get the error: System.InvalidOperationException: "Sequence contains no matching element"
Is there maybe a way to set the "GOOGLE_APPLICATION_CREDENTIALS" to the embedded cloudfire.json ressource file?
EDIT:
I solved the problem by adding the "cloudfire.json" file to Resources.resx and changed the modifier to public. Like mentioned here.
Since you can only set the GOOGLE_APPLICATION_CREDENTIALS by using this code:
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "path to file");
I solved it by creating a temporary file:
byte[] resourceBytes = Properties.Resources.cloudfire;
// Write the resource to a temporary file
string tempPath = Path.GetTempFileName();
File.WriteAllBytes(tempPath, resourceBytes);
// Set the GOOGLE_APPLICATION_CREDENTIALS environment variable
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", tempPath);
Add you file as embedded resource with name. And try to read by following code:
var resources = new ResourceManager("<namespace>", Assembly.GetExecutingAssembly());
var obj = resources.GetObject(<embedded_resource_key>);
or
var str = resources.GetString(<embedded_resource_key>)

Read JSON file from project folder in ChatBot

I would like to read json files to present an adaptive card, but I am missing how to get the path to the files.
Like I have a card_a.json file in my wwwwroot folder.
public async Task<string> GetCardText(string cardName)
{
var path = $"/wwwroot/{cardName}.json";
if (!File.Exists(path))
return string.Empty;
using (var f = File.OpenText(path))
{
return await f.ReadToEndAsync();
}
}
I tried $"/wwwroot/{cardName}.json", $"/{cardName}.json" and $"{cardName}.json", none of them worked.
I've read this article, but didn't help, the sample fails here:
var path = HostingEnvironment.MapPath($"/Cards/{cardName}.json");
With an error: HostingEnvironment does not contain a definition for MapPath. Adding using System.Web didn't solve this issue. VS says that adding this is unnecessary.
Does the cardname.json file need to reside in the wwwroot folder? You could save a lot of permission and path problems by storing them in the application root, or a subfolder of that.

Xamarin Android project can't find XML file

I have a file in my Xamarin Android project called "SaveData.xml". I can't save it in the assets folder because I need to write to it during runtime. I am trying to access it with my LoadXML() function:
XmlDocument doc = new XmlDocument();
XmlDocument saveData = new XmlDocument();
public void LoadXML()
{
saveData.Load("SaveData.xml");
//This bit works fine.
AssetManager assets = this.Assets;
using (StreamReader sr = new
StreamReader(assets.Open("Spices.xml")))
{
doc.Load(sr);
}
}
I've tried reading up on it but all the answers say to just save in assets folder. I can't do that because I need to write to this file and then read it again every time the app starts. I also tried putting it in the resources folder and changing the build action. Is the file path wrong? do I need to save it somewhere else? I'm stumped.
EDIT: Sorry for not being specific. "saveData.Load("SaveData.xml")" Is throwing a file not found exception and I want to know why.
Here is the xml file.
SaveData.xml
<?xml version="1.0" encoding="utf-8" ?>
<list>
<cupboard></cupboard>
<shoppingList></shoppingList>
</list>
Yes, if you need to write to the xml during runtime application, we can't put it into the assets folder as it's read-only.
Besides, when you execute saveData.Load("SaveData.xml"), you're not specifying a target directory, so it's defaulting to the root directory, then it will throw a file not found exception.
So you'll need to write the file to a location you have write access to.
The code below will specify a file in the user's home directory, which will be writeable:
using System.IO;
string backingFile_path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "SaveData.xml");
For more details, you can check: https://learn.microsoft.com/en-us/xamarin/android/platform/files/
Note:There is a sample included in this link which you can refer to.

Correct Way to use Relative Path to Access a file in Client Bin in a Silverlight Application

I have a WCF Service that I call from the client of my silverlight application, and I pass it a string filename parameter and a string parameter containing xml. In the service method I construct an XDocument instance containing the xml string, and then save it to a file in the ClientBin folder on the server. I have been using an absolute path, and now am trying to switch to a relative path, but am unsure how to do it correctly. My code looks like this:
public void WriteXmlToServer(string filename,string xmlString)
{
//xml document to hold the information for the group that is registered
XDocument xDoc = new XDocument(XDocument.Parse(xmlString.ToString()));
XDocument DataInFile = new XDocument();
try
{
xDoc.Save(Path.Combine("..\\ClientBin\\", filename));
//the complete absolute path to the .xml file ->C:\Users\Me\Documents\Visual Studio 11\Projects\SL_xMonitor_Frontend_RefactorV1_Backup82212\SL_xMonitor_Frontend_RefactorV1.sln
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.InnerException.ToString());
}
}
I am currently getting this exception message:
System.IO.DirectoryNotFoundException was unhandled by user code
HResult=-2147024893
Message=Could not find a part of the path 'C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\ClientBin\ServerGroups.xml'.
Could someone please instruct me on the correct way to use a relative path to a file in the client bin in a Silverlight application?
Try a single . instead of .. as .. means to back up one directory level before descending into the Directory you want, where as . means starting at the current Directory, then descend into the desired directory.

Visual Studio 2010 working directory

I'm developing a C# asp.net web application. I'm basically done with it, but I have this little problem. I want to save xml files to the "Users" folder within my project, but if I don't psychically hard code the path "C:......\Users" in my project it wants to save the file in this "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\Users" folder, this is an annoying problem because I can't use the hard coded directory on our web hosts server. Also, I have a checkbox list that populates from the the "DownloadLibrary" folder in my project, and its suppose to download the files from that fold but its also looking to the "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" folder for download even though its populating from the correct folder. I'm very confused by this, its the first time something like this has ever happened to me. Can anyone please help me with this, its the only thing standing in my way to complete this project.
You don't want to use the working directory at all; you want to use a directory relative to where the web application is located (which can be retrieved from HttpRequest.ApplicationPath.
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string pathToApp = request.MapPath(request.ApplicationPath);
string usersPath = System.IO.Path.Combine(pathToApp, "Users");
Update
As VincayC points out; asp.net development is not my strongest skill ;) The above code is essentially equivalent of this (much simpler) code:
string usersPath = HttpRequest.Current.Request.MapPath("~/Users");
If this code appears in the code-behind of a page, you can probably cut HttpContext.Current as well, since the page has a Request property.
That did fix the one problem I'm having, but the downloads are still not downloading from the right place, the program still wants to get the files from "C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\" directory here is the code I'm using
--Code to populate the checkbox--
HttpRequest request = HttpContext.Current.Request;
// get the physical path to the web application
string appPath = request.MapPath(request.ApplicationPath);
string directory = System.IO.Path.Combine(appPath, "DownloadLibrary/");
// Get the list of files into the CheckBoxList
var dirInfo = new DirectoryInfo(directory);
cblFiles.DataSource = dirInfo.GetFiles();
cblFiles.DataBind();
--Download Button Code--
// Tell the browser we're sending a ZIP file!
var downloadFileName = string.Format("Items-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-HH_mm_ss"));
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", "filename=" + downloadFileName);
// Zip the contents of the selected files
using (var zip = new ZipFile())
{
// Add the password protection, if specified
/*if (!string.IsNullOrEmpty(txtZIPPassword.Text))
{
zip.Password = txtZIPPassword.Text;
// 'This encryption is weak! Please see http://cheeso.members.winisp.net/DotNetZipHelp/html/24077057-63cb-ac7e-6be5-697fe9ce37d6.htm for more details
zip.Encryption = EncryptionAlgorithm.WinZipAes128;
}*/
// Construct the contents of the README.txt file that will be included in this ZIP
var readMeMessage = string.Format("Your ZIP file {0} contains the following files:{1}{1}", downloadFileName, Environment.NewLine);
// Add the checked files to the ZIP
foreach (ListItem li in cblFiles.Items)
if (li.Selected)
{
// Record the file that was included in readMeMessage
readMeMessage += string.Concat("\t* ", li.Text, Environment.NewLine);
// Now add the file to the ZIP (use a value of "" as the second parameter to put the files in the "root" folder)
zip.AddFile(li.Value, "Your Files");
}
// Add the README.txt file to the ZIP
//zip.AddEntry("README.txt", readMeMessage, Encoding.ASCII);
// Send the contents of the ZIP back to the output stream
zip.Save(Response.OutputStream);</pre></code>
I'm not sure how to get the downloads to point to my application directory,I tried everything I can think off.

Categories

Resources