read the content of file by getting it from dll - c#

I have a C# project name as ("Test") which has a class and a folder contains a html file and my senior has compile this project into a dll.
the content of the html file is = "Hello World"
the class contains :
string that read the whole html file.
context.Respone.Write(the string above).
I have another web project which has a page to call the method above by adding the test dll. The question is, how can I read the content of the html file by getting it from the dll ? So that the web page can display "Hello World"

Put your file in Embedded resource and read it using code liek that
public static string GetResourceFileContentAsString(string fileName)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "Your.Namespace." + fileName;
string resource = null;
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
resource = reader.ReadToEnd();
}
}
return resource;
}

Related

C# Read text file from resources rather than locally error, adding namespace didnt work

I have tried multiple solutions on here but non of them I can get to work. All i want to do is read a text file from my resources folder rather than the actual local folder.
File name: TextFile.txt
Set to embedded resource.
"Local File" Code that works:
string[] spaces = File.ReadAllLines("C:\\Users\\a\\source\\repos\\a\\bin\\Debug\\TextFile.txt");
Current Code:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
But I am getting the following error:
System.ArgumentNullException: 'Value cannot be null.
Parameter name: stream'
On this line:
using (StreamReader reader = new StreamReader(stream))
EDIT1 Tried this as per link (Why does GetManifestResourceStream returns null while the resource name exists when calling GetManifestResourceNames?) and this NULL ERROR:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "programname.TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
Same error, am I putting the namespace bit in the wrong place?
Edit 2, tried this:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "programname.Resources.TextFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
string[] spaces = File.ReadAllLines(resourceName);
New error:
System.IO.FileNotFoundException: 'Could not find file 'C:\Users\a\source\repos\a\bin\Debug\programname.Resources.TextFile.txt'.'
Location of TextFile.txt
programname
Resources
TextFile.txt
Got this to work by opening Resources.resx, Setting Access Modifier to Public Then adding the file in there.
Then replaced:
string[] spaces = File.ReadAllLines("C:\\Users\\a\\source\\repos\\a\\bin\\Debug\\TextFile.txt")
With:
var resourceText = Properties.Resources.TextFile;
var Lines= resourceText.Replace("\r", "").Split('\n');
A little background:
MSDN:
If you add a resource to your project in the normal way, it will
automatically provide a typesafe wrapper for that resource.
For example, in the Solution Explorer, expand the "Properties" node
and double click the "Resources.resx" entry. Then add an image via the
"Add Resource" button. Give that resource a name, say "MyImage".
You will then be able to programmatically access that image via
"Properties.Resources.MyImage"
This is the simple and recommended way; it will let you edit the name in the resource file and will check while coding that the name is correct.
Note that the names are stripped of the extension and, as other c# names, are case-sensitive!
The other way doesn't register the resources with the .resx file but only add them to the resource folder and marks them as embedded.
To use them you can't use a code as simple as the one above. Instead you need to find out the name (Intellisense will not help you there) and them use calls to the Reflection namespace.
Note that here the names are __not_- stripped of the extension but still are case-sensitive!
Example:
If we don't know the exact name we can search in the assembly:
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var ress = assembly.GetManifestResourceNames()
.Where(x => x.Contains(somepattern)).First();
Usually the 1st way is much recommended. Typesafety and Intellisense support alone are well worth mainainting the resx file!
Now we can open a stream to read the resource:
List<string> results = new List<string>(); ;
using (Stream stream = assembly.GetManifestResourceStream(ress))
using (StreamReader reader = new StreamReader(stream))
{
while (reader.Peek()>=0) results.Add(reader.ReadLine());
}
This function will return the correct resource name for your file:
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("TextFile.txt"));
2nd issue:
For string[] spaces = File.ReadAllLines(resourceName);
You can't use the same resourceName (embedded resource). If you need to read text line by line use for example:
using (StreamReader reader = new StreamReader(stream))
{
while (reader.Peek() >= 0)
{
Console.WriteLine(reader.ReadLine());
}
}

Xamarin Android System.IO.FileNotFoundException: Could not find file Exception

I use Visual Studio 2015 with Xamarin Android.
I want to read some JSON data from file, but I keep getting this System.IO.FileNotFoundException, even though I have set my files properties "Build: Content, Copy to Output Directory: Copy if newer" and I can see the file physically in my build folder.
I use this code:
var path = #"AedJson.json";
using (var streamReader = new StreamReader(path))
{
string json = streamReader.ReadToEnd();
//JObject o1 = JObject.Parse(json);
}
The exact exception is:
System.IO.FileNotFoundException: Could not find file "/AedJson.json".
Error Picture
You need to add your json file to your Xamarin.Android project as an Asset (within the Assets folder) and flag it as an AndroidAsset build type, then you can use the AssetManager to read it.
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("AedJson.json")))
{
string json = sr.ReadToEnd ();
}
Ref: Using Android Assets
I'm not sure it really is an error, but looking at the error, it seems like the path is incorrect. Do you really need to save your file precisely where you're actually saving it ? If not, try this :
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string filename = Path.Combine(path, "myfile.txt");
using (var streamReader = new StreamReader(filename))
{
string json = streamReader.ReadToEnd();
//JObject o1 = JObject.Parse(json);
}
Use this path to save and to load. I'm proceeding like this for all my files and it seems to work well.
This works using Microsoft.Extensions.Configuration.Json
Set json file build action in properties as embedded resource
Project : Client
FileFolder : Configuration
FileName : appsettings.json
JSON :
{
"Rest": {
"Server": "192.168.0.199",
"Port": "5003"
}
}
CODE:
string Namespace = "Client.Configuration";
string FileName = "appsettings.json";
Assembly assembly = GetType().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{Namespace}.{FileName}");
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonStream(stream);
var root = configurationBuilder.Build();
IConfigurationSection restClientConfigration = root.GetSection("Rest");
string server = restClientConfigration.GetSection("Server").Value;
string port = restClientConfigration.GetSection("Port").Value;

Reading a file from resources

I have embed sample.txt(it contains just one line "aaaa" ) file into project's resources like in this answer.
When I'm trying to read it like this:
string s = File.ReadAllText(global::ConsoleApplication.Properties.Resources.sample);
I'm getting System.IO.FileNotFoundException' exception.
Additional information: Could not find file 'd:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\bin\Debug\aaaa'.
So seemingly it's trying to take file name from my resource file instead of reading this file. Why is this happening? And how can I make it read sample.txt
Trying solution of #Ryios and getting Argument null exception
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication.Resources.sample.txt"))
{
TextReader tr = new StreamReader(stream);
string fileContents = tr.ReadToEnd();
}
The file is located in d:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\Resources\sample.txt
p.s. Solved. I had to set Build Action - embed resource in sample.txt properties
You can't read Resource Files with File.ReadAllText.
Instead you need to open a Resource Stream with Assembly.GetManifestResourceStream.
You don't pass it a path either, you pass it a namespace. The namespace of the file will be the Assemblies Default Namespace + The folder heieracy in the project the file is in + the name of the file.
Imagine this structure
Project (xyz.project)
Folder1
Folder2
SomeFile.Txt
So the namespace for the file will be:
xyz.project.Folder1.Folder2.SomeFile.Txt
Then you would read it like so
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt"))
{
TextReader tr = new StreamReader(stream);
string fileContents = tr.ReadToEnd();
}
Hello the proposed solution doesn't work
This return null:
Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt")
Another way is to use a MemoryStream from the Ressource Data:
byte[] aa = Properties.Resources.YOURRESSOURCENAME;
MemoryStream MS =new MemoryStream(aa);
StreamReader sr = new StreamReader(MS);
Not ideal but it works

windows phone 8 resource path at runtime

I have to include some files with my windows phone 8 app. the app will accordingly get those file from resource and read or show partly the content according to the algorithm. how do i get the path to my embedded resource?
If you include file in you project, for instance in Data folder of your project (in our case json file) as a resource then use next code to get content from that file:
string content = string.Empty;
string resource_file = "Data/myfile.json";
if (IsLocalResourceFileExists(resource_file))
{
var resource = Application.GetResourceStream(new Uri(#"/YourProjectName;component/" + resource_file, UriKind.Relative));
StreamReader streamReader = new StreamReader(resource.Stream, System.Text.Encoding.UTF8);
content = streamReader.ReadToEnd();
streamReader.Close();
}
To check if file exist in resource use this:
public bool IsLocalResourceFileExists(string relativePath)
{
return Application.GetResourceStream(new Uri(#"/YourProjectName;component/" + relativePath, UriKind.Relative)) != null;
}
Change YourProjectName to name of you project.
After this, conten holds json file as string.
Hope this help

Reading embedded XML file c#

How can I read from an embedded XML file - an XML file that is part of a c# project?
I've added a XML file to my project and I want to read from it. I want the XML file to compile with the project because I don't want that it will be a resource which the user can see.
Any idea?
Make sure the XML file is part of your .csproj project. (If you can see it in the solution explorer, you're good.)
Set the "Build Action" property for the XML file to "Embedded Resource".
Use the following code to retrieve the file contents at runtime:
public string GetResourceTextFile(string filename)
{
string result = string.Empty;
using (Stream stream = this.GetType().Assembly.
GetManifestResourceStream("assembly.folder."+filename))
{
using (StreamReader sr = new StreamReader(stream))
{
result = sr.ReadToEnd();
}
}
return result;
}
Whenever you want to read the file contents, just use
string fileContents = GetResourceTextFile("myXmlDoc.xml");
Note that "assembly.folder" should be replaced with the project name and folder containing the resource file.
Update
Actually, assembly.folder should be replaced by the namespace in which a class created in the same folder as the XML file would have by default. This is typically defaultNamespace.folder0.folder1.folder2......
You can also add the XML file as a Resource and then address its contents with Resources.YourXMLFilesResourceName (as a string, i.e. using a StringReader).
Set the Build Action to Embedded Resource, then write the following:
using (Stream stream = typeof(MyClass).Assembly.GetManifestResourceStream("MyNameSpace.Something.xml")) {
//Read the stream
}
You can use Reflector (free from http://www.red-gate.com/products/reflector/) to find the path to the embedded XML file.
Then, it's just a matter of
Assembly a = typeof(Assembly.Namespace.Class).Assembly;
Stream s = a.GetManifestResourceStream("Assembly.Namespace.Path.To.File.xml");
XmlDocument mappingFile = new XmlDocument();
mappingFile.Load(s);
s.Close();
Add the file to the project.
Set the "Build Action" property to "Embedded Resource".
Access it this way:
GetType().Module.Assembly.GetManifestResourceStream("namespace.folder.file.ext")
Notice that the resource name string is the name of the file,
including extension, preceded by the default namespace of the project.
If the resource is inside a folder, you also have to include it in the
string.
(from http://www.dotnet247.com/247reference/msgs/1/5704.aspx, but I used it pesonally)
#3Dave really helped (up vote given), however my resource helper was in a different assembly so I did the below
public string GetResourceFileText(string filename, string assemblyName)
{
string result = string.Empty;
using (Stream stream =
System.Reflection.Assembly.Load(assemblyName).GetManifestResourceStream($"{assemblyName}.{filename}"))
{
using (StreamReader sr = new StreamReader(stream))
{
result = sr.ReadToEnd();
}
}
return result;
}
Called by
GetResourceFileText("YourFileNameHere.ext", Assembly.GetExecutingAssembly().GetName().Name);

Categories