Read JSON file from project folder in ChatBot - c#

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.

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 .xml file from project directory in Xamarin project

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");

Referencing a file inside of a Project without using its absolute path?

I'm using StreamReader to dynamically replace content in an HTML template. The HTML file has been imported into my project.
Right now I'm having to referencing the HTML file a static location on my dev box because I'm not able to find the right syntax to reference it once it's been imported into my VS project.
How do I refer to the file without using an absolute path?
Current implementation for reference:
StreamReader reader = new StreamReader(#"C:\Users\n00b\Desktop\EmailTemplate.html");
{
body = reader.ReadToEnd();
}
One common thing I've seen is to put the file's location in a configuration file. This lets you change the file location at will without having to recompile.
You can add it as an embedded resource and extract it this way.
using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("<namespace>.Resources.EmailTemplate.html"))
per your comment
using (System.IO.StreamReader sr = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("<namespace>.Resources.EmailTemplate.html"))
{
body = sr.ReadToEnd();
}
There are 2 main ways to do this, In a desktop application, the current directory of the .exe is set to the directory where it is launched from by default. Unless that is changed by launching the .exe by a shortcut with special settings, or by another process using a special feature, it should be the default value. If that is the case, you can just use a relative path. For example, if you have a file named "data.txt" in a folder called "things" inside a folder called "stuff" in the same directory as your app, you can just us the relative path "stuff/things/data.txt" directly and Windows will work it out for you.
If you need to be absolutely sure you are targeting that file, even if the app launches with a modified current directory, you can get the .exe's path, and combine it with a relative path using System.IO.Path.Combine.
var appPath = Assembly.GetEntryAssembly().Location;
var filePath = "stuff/things/data.txt"
var fullPath = System.IO.Path.Combine(appPath, filePath)
If, for some reason, you need to up "up" from the application's directory, you can use ".." to represent that parent folder of a directory. So "../data.txt" would look in the folder that contains the current directory for a file named "data.txt".
You could also change the app's current directory when it starts to be the directory of the .exe, and then reference everything via relative path, as in the first example.
var appPath = Assembly.GetEntryAssembly().Location;
System.IO.Directory.SetCurrentDirectory(appPath);
I found two solutions to this:
If you don't care if the external file is visible in the build directory/installdir of your app:
StreamReader reader = new StreamReader(#"../../EmailTemplate.html");
{
body = reader.ReadToEnd();
}
If you want your external file to be invisible once compiled:
var embeddedResource = "<namespace>.EmailTemplate.html";
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedResource))
{
StreamReader sr = new StreamReader(stream);
body = sr.ReadToEnd();
}
Note the 2nd solution requires adding your external file and changing the build action to "Embedded Resource" on the properties menu of that file within Visual Studio.

asp.net 404 - File or directory not found on website but locally it can

I have a folder "res/resx/" which contatins .resx files. What I want is to get all those .resx files.
Here is my code for that.
var Path = Server.MapPath("~/");
var SampleUrl = System.IO.Path.GetFullPath(System.IO.Path.Combine(Path, "Res/resx/"));
string[] files= System.IO.Directory.GetFiles(SampleUrl);
var AllFiles = new System.Collections.ObjectModel.ReadOnlyCollection<string>(files);
foreach (string sFileName in AllFiles)
{
Response.write(sFileName + " <br>");
}
This code is working on my local and i was able to see a list of my resx files. But when i deploy this to my website and access it, an error occurs on the 2nd line of code which says:
Could not find a part of the path
'D:\Websites\mywebsite.com\Res\resx'
I tried allowing directory browsing to see if my files exist. In my local, i can browse the files but on the website, I cannot. And it seems the system cannot find the folder "Res/Resx" too. it says:
404 - File or directory not found. The resource you are looking for
might have been removed, had its name changed, or is temporarily
unavailable.
But the folder exist and it is running on my local. Any advice as to what i should do or is their something i have missed? Thanks
Try this
string[] filePaths = Directory.GetFiles(Server.MapPath("Your folder"));
Look at the System.IO.Directory class and the static method GetFiles. It has an overload that accepts a path and a search pattern. Example:
string[] files = System.IO.Directory.GetFiles(path, "*.resx");
answered by
Anthony Pegram here.

WriteTextAsync not writing to file

I have this piece of code:
string jsonPath = #"Model\Datamodel\UserData.json";
User userItem = JsonConvert.DeserializeObject<User>(user);
User.Add(userItem);
string content = user;
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var file = await folder.GetFileAsync(jsonPath);
await FileIO.WriteTextAsync(file,content);
Debug.WriteLine(String.Format("DONE"));
The "Done" debug line is written in console but it does not write anything to the file.
I also don't get any errors. When I debug and look at Folder and file I see that they are correctly.
Can anybody help?
You can't write to files in Windows.ApplicationModel.Package.Current.InstalledLocation, you need to use one of the other writeable locations available to you instead. (e.g. ApplicationData.Current.LocalFolder)
If you need to access the content of the file that was shipped with the package, I would suggest copying it to the local folder, and using the copy for read/write access.

Categories

Resources