I am creating class library file. In this I embedded stored procedure script file. so I need to take sp data as a string and I have to create in c#. so for this GetManifestResourceStream method need full-name of assemble and script file. so I did . But I did not figure out why my stream object getting null value.
string strNameSpace = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
using (Stream stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(strNameSpace + "GP_SOP_AdjustTax.sql"))
{
// Here stream is null.
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
}
It is sort of strange to get constant string value by getting assembly name... But you are missing "." in the way to construct the name:
Assembly.GetExecutingAssembly()
.GetManifestResourceStream(strNameSpace + ".GP_SOP_AdjustTax.sql"))
It will likely be safe and easier to simply hardcode the name:
Assembly.GetExecutingAssembly()
.GetManifestResourceStream("WhateverYoourNamespaceIs.GP_SOP_AdjustTax.sql"))
Note "How to embed and access resources" is available on Micorsoft support site and covers this topic.
Related
I use stream reader to read sql data. Although resourceName is correct and the resource Build Action property is Embedded Resource it still throws following error on StreamReader:
System.ArgumentNullException: Value cannot be null.
var namespace1 = typeof(Toolbox).Namespace;
var name1 = name.Replace('\\', '.');
string resourceName = $"{typeof(Toolbox).Namespace}.{name1}";
//Innosys.Ap.GetCurrentTimeKey.sql
using (Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
)
{
using (StreamReader streamReader = new StreamReader(manifestResourceStream))
return streamReader.ReadToEnd();
}
Following are my debugging results so far.
namespace1 returns the correct name space used for the class from the project i.e. The class from which I call streamReader, resource file.
name1 returns resource file name with extension. ie. myquery.sql
resourcename which basically combines the path and the file name returns from my point of view the correct resouce address. i.e. myNamespace.myquery.sql
I need to analyze Properites and Methods inside of classes in a custom framework that is being referenced by my active solution with a nuget package.
I can read the files on my active solution successfully because I can use the local path of the file.
I can also pull the FileStream of the file from the referenced framework assembly, but StreamReader is only reading "MZ�", and since the files are from a Nuget package, I do not have a local path.
Here are the three solutions I've tried and the problems I'm running in to in comments:
//attempt at using FileStream
PortableExecutableReference location =
MetadataReference.CreateFromFile(Assembly.Load(assemblyName).Location);
var assembly = Assembly.LoadFrom(location.FilePath);
FileStream f = assembly.GetFiles()
.Where(t => type.Name == name).FirstOrDefault();
if (f != null)
{
using (StreamReader sr = new StreamReader(f))
{
while (!sr.EndOfStream)
{
fileString = sr.ReadLine();
}
}
}
//StreamReader does not read the FileStream, fileString value = "MZ�"
//attempt at geting the path thru f.Name
PortableExecutableReference location =
MetadataReference.CreateFromFile(Assembly.Load(assemblyName).Location);
var assembly = Assembly.LoadFrom(location.FilePath);
FileStream f = assembly.GetFiles()
.Where(t => type.Name == name).FirstOrDefault();
return f.Name;
//only returns the framework path. StreamReader can't read the file with this and since its metadata I can't find the file in framework solution.
//attempt to at least get the base class information
Assembly a = Assembly.GetAssembly(typeof(type));
using (FileStream fs = a.GetFile(name))
{
using (StreamReader sr = new StreamReader(fs))
{
return fileString = sr.ReadLine();
}
}
//fs = null
fileString should contain my class file in the form of a string.
The source code isn't included when you build a .NET program; it is compiled to IL (in a dense binary form, not as text IL source), and the IL is sent. The fact that you can do this locally is purely an accident of having the source files on your machine. This will not apply in general.
Basically, you're going to need a different option. .NET has a full reflection API, allowing you to inspect an awful lot of metadata at runtime (including fields, methods, properties, attributes, etc) - but it does not include the actual source code, because: you don't (usually) ship that.
If you can be more specific about what you need to do with what is currently fileString, we can probably guide you on the best approaches, and what is/isn't possible, etc.
I can write data to the App_Data folder in my ASP.NET Web API app like so:
string appDataFolder = HttpContext.Current.Server.MapPath("~/App_Data/");
var htmlStr = // method that returns html as a string
string htmlFilename = "platypus.html";
string fullPath = Path.Combine(appDataFolder, htmlFilename);
File.WriteAllText(fullPath, htmlStr);
I want to do something similar in an ASP.NET MVC app (the data is different - a PDF file instead of an html file), but "File" is not recognized. I try this:
using (var ms = new MemoryStream())
. . .
var bytes = ms.ToArray();
string appDataFolder = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
string pdfFilename = "test.pdf";
string fullPath = Path.Combine(appDataFolder, pdfFilename);
File.WriteAllText(fullPath, bytes);
...but get, "'System.Web.Mvc.Controller.File(byte[], string)' is a 'method', which is not valid in the given context'"
In the first place, I don't think my code is what the err msg seems to indicate it is, but nevertheless it's not accepted, so: how can I write data to the App_Data folder in ASP.NET MVC?
It looks like a namespace collision. The compiler is grabbing File from a different namespace than is expected. The File class that should make this work is in the System.IO namespace and not the System.Web.Mvc.Controller namespace.
This can be fixed by explicitly specifying the correct namespace when calling File.WriteAllText():
System.IO.File.WriteAllText(fullPath, bytes);
I must download a file using SSH.NET library. After I download a file I must delete the remote file.
Everything works but the file name is encoded. I mean that for example, if I have a file named New file, I download/upload a file named New%20file. Now, if I download/upload the new file I obtain New%25%20file and again New%252520file... and so on...
This is very problematic. How can I avoid to change the file name after I download it?
Here the code I am using to download:
string fileName = base.Uri.GetFileName();
string fullPath = Path.Combine(pathFolder, fileName);
using (SftpClient client = new SftpClient(
new PasswordConnectionInfo(
base.Uri.Host, SftpFlowGateway.CONST_PORT_NUMBER,
base.Credential.UserName,
base.Credential.Password))
)
{
client.Connect();
using (FileStream fileStreamToDownload = new FileStream(fullPath, FileMode.Create))
{
client.DownloadFile(base.Uri.LocalPath, fileStreamToDownload);
}
client.Disconnect();
}
EDIT:
base.Uri is just defined as follow:
private Uri _uri;
public Uri Uri
{
get { return _uri; }
protected set { _uri = value; }
}
And the GetFileName method is:
public static string GetFileName(this Uri path)
{
return path.Segments.Last();
}
When I debug, I can see that the properties of the class Uri have the correct value... It is not encoded
Thank you
You are passing a stream you have created yourself (new FileStream) to the SSH.NET. The library does not even know it's a file it is writing to, nor its name. So it's not the library that URL-encodes the file name. It has to be URL-encoded in the fullPath variable already.
It's the Uri.AbsolutePath and Uri.Segments that return URL-encoded path. That's how the System.Uri class works. I assume you use the constructor overload Uri(string uriString).
Use the static method Uri.UnescapeDataString to reverse encoding done by the Uri constructor.
Note the obsoleted constructor overload Uri(string uriString, bool dontEscape).
It looks like the SSH.Net library simply URL encodes the file names.
I suppose you could rename the file after you've downloaded it using the System.Web.UrlDecode method?
Or UrlEncode the filename when you upload.
Unfortunately, I haven't used the library myself but you could help further by letting us know if the name change occurs on download or upload or both.
EDIT:
As martin mentioned, its not the library doing any encoding.
I've just tried it myself.
string fileName = "file with spaces.txt";
using (Stream outputFile = File.OpenWrite(localDir + "\\" + fileName))
{
sftpClient.DownloadFile(fileName, outputFile);
}
The created file is also named "file with spaces.txt" though that would've been the case anyway since it was created via the stream.
I am doing an application in c#.
I get the error:
Value cannot be null. Parameter name: stream while reading the contentxs of embedded file
in the code
Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);
How to solve this error?
What I found is as once I faced this problem after adding a text file or template file to read the email body and than reading the path to that template file using
below syntax:
Assembly asm = Assembly.GetExecutingAssembly();
string assemblyName = asm.GetName().Name;
string emailTemplateName = xyz.tt;
emailTemplateName = assemblyName + "." + emailTemplateName;
using (StreamReader reader = new StreamReader(asm.GetManifestResourceStream(emailTemplateName)))
{
body = reader.ReadToEnd();
}
The file by default gets added to project library with property "Build Action"= Content. I changed value from "Content" to "Embedded Resource" and everything worked good.
The prefix to embedded resources is not the assembly name, but rather: the default namespace specified on the project. Your best tactic, though, is to look at:
string[] names = Asm.GetManifestResourceNames();
foreach(var name in names) Debug.WriteLine(name);
and see what the names actually are, and tweak the prefix accordingly. You will get null if it is not a complete match.