Path error when accessing .cshtml file in Azure App Service - c#

I have an asp.net core 5 application running on Azure App Service, which should fetch a .cshtml file that serves as an email template. I use the .ContentRootPath attribute of the IWebHostEnvironment interface to return the first part of the path, and I concatenate the rest of the path to the file, with a string. Locally, everything works fine, but there is something wrong with fetching the .cshtml file when the application is running in Azure.
When fetching the .cshtml, the following error is observed:
Could not find a part of the path '/home/site/wwwroot/wwwroot/Templates/Email/EmailRegistroAssinatura.cshtml'
But locally, none of that happens. I expected the .ContentRootPath attribute to return the first part of the path according to the environment where the application was running.
My code is the following:
using Microsoft.AspNetCore.Hosting;
string projectRootPath = _hostingEnvironment.ContentRootPath;
string file = "wwwroot/Templates/Email/" + fileName + ".cshtml";
string path = Path.Combine(projectRootPath, file);
using (StreamReader reader = File.OpenText(path))
{
htmlStringEmail = reader.ReadToEnd();
}
What to do to get the path correctly, using the same code in both environments?

After my test, I found the root cause. The reason is the static files(folder) not include when you deploy it. You can go to kudu site and check it.
I face the error message like below.
I check the static files under wwwroot, and can't find the Templates folder, then I add all the folders and file manually like below.
Then I test again and it works well.
Summary
You can search the official doc about how to include static files when you deploy the project. Or add it manually.
Pls not use .cshtml file as template, you should use .html file, as we know, the contents under wwwroot should be static files. Normally we will create new .cshtml files under Views folder.

Related

How to get the path of the uploaded file within the AppBundle?

We are using Autodesk Forge's Design Automation API. We have an AppBundle ready and we put an .rfa file into the same folder which contains the .dll file. When the AppBundle is unzipped on the Forge servers, which path can lead to our .rfa file? (how can we access it?) Our goal is to place the attached Family file's contents into the input file which is being uploaded with the API, and the result should be a new file which contains the additions from the file which we uploaded within the AppBundle. The process works when testing with Revit locally, but it doesn't work with the API. In the report we are retrieving it's obviously pointing out that the attached file cannot be found:
Autodesk.Revit.Exceptions.FileNotFoundException: T:\Aces\Jobs\ced628d35ecf4412b68c024e2cec098b\something.rfa
On the code side, we are trying to access the .rfa file via this path:
static string currentDir = Environment.CurrentDirectory;
static string path_input = currentDir+#"\something.rfa";
This seemed as a logical path, but as it turned out, it's not..
Is there a way to access the .rfa file inside the uploaded AppBundle?
I took a look at the Restrictions but reading the file from the AppBundle is not mentioned as restricted or not approachable. Am I missing something?
A .NET assembly knows its own path. You can call System.Reflection.Assembly.GetExecutingAssembly().Location within it to find the current path of the dll. You can then compute the path of the .rfa file relative to the folder of the dll and use it / open it. Thus you should be able to open any file you package along with your addin in your appbundle.
You can simply modify your code to:
static string assemblyLocation = Assembly.GetExecutingAssembly().Location;
static string assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
static string path_input = assemblyDirectory+#"\something.rfa";
One thing to note however, is that you only have readonly access to files in appbundle. If your code relies on modifying these during execution, then you may simply copy the source rfa file to the current working folder and then work with the copied file instead.
Also see more details in blog for similar ideas.
We have a blog post on how you can either pass in the app bundle path in the commandLine parameter or find the path via the location of the add-in dll:
https://forge.autodesk.com/blog/store-template-documents-appbundle

System.IO.FileNotFoundException when saving file on server

I know that this error has more awnsers on this form but none seem to be working since they are having problems with localhost. But localhost works fine for me.
I'm trying to create a .xlsx file from a button click on the server.
I already contacted the hosting company to make sure that it is possible to place files like this on there server and they told me that I could. So.... that is not the probleme.
This works perfect on localhost. But when I move it to the webhost I get this error:
I use this code:
using (var stream = new MemoryStream())
{
// local path
//string path = #"D:\local\Test\order.xlsx";
// Server path
string path = HostingEnvironment.MapPath(#"~\Excel-Exports\order.xlsx");
workbook.SaveAs(path);
var content = stream.ToArray();
File(
content,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"order.xlsx");
}
Before this part of code I build the Excel file. So I don't think that is the probleme.
I think the probleme is with the path since the tells me that I cant not find the file.
For the record I do use the same method for reaching a path on a different location and this works just fine.
Working code on other location
string path = HostingEnvironment.MapPath(#"~/img/MetropolisGO_RGB-kleur1.png");
LinkedResource Img = new LinkedResource(path);
Does anyone have a solution for me to save this file on the server?
The error indicates that the project is missing "ClosedXML" version 0.95.4 that is reference or using it but there is no DLL or library or project to be used.
If it's in your project, check the order of the building.
If is third-party, check the DLL or library is "copy always" in the build

Is there any way to set a generic root path for content in ASP.NET Core?

I have faced problem with accessing static files from wwwroot folder in ASP.NET Core application in release mode. I keep my static files in wwwroot folder and access them with a relative path, for example to access wwwroot/images/test.png for src attribute of img tag I specify /images/test.png and the picture loads correctly in local IIS Express development mode.
Now I have created Website in IIS Manager (TestWebsite) and deployed my web application to it, and also I created Application pool in site (TestApplicationPool) so that it's hierarchy looks like this:
The problem I have faced is that after deploy my paths to static files has crashed and to access them I need to have /TestApplicationPool before any path (for the example above, now I need to specify /TestApplicationPool/images/test.png to access image). So my question is there any way we can configure ASP.NET application to always use current Application as content root path, so that we don't need to specify nothing in path except the path of static file relative to wwwroot folder?
I have tried to get application name from ContentRootPath variable of IWebHostEnvironment and insert it before the path to the static file and in this case everything works, but it is inconvenient to do this every time we need to load static file from wwwroot folder.
In MVC views or Razor pages you can use a tilde and slash (~/) prefix on the path to represent the web root (wwwroot by default) in most places in your cshtml views/pages.
For example:
<img src="~/hello.jpg" />
This should translate to the correct path even when deployed under a virtual directory in IIS (like your example).
Relevant documentation about web root can be found here, and this mentions the ~/
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/?view=aspnetcore-5.0&tabs=windows#web-root

ASP.NET Web application cant find my XML file, sayis its not in IIS Express folder

I have in my another project a class which loads XML.xml file for XmlTextReader object. Then my another project(website) uses this project for loading xml file. So when I run this website it sayis it cant find XML.xml file inside C:\Program Files(x86)\IIS Express\XML.xml .
I cant create a new file there and I have no absolutely idea how to config this website to find my XML file from another directory. I tried to google a lot but couldnt find any good answers. Any fast fixes or something.
Heres the code in asp.net
protected void Page_Load(object sender, EventArgs e)
{
XMLObjectParser parseri = new XMLObjectParser("XML.xml");
parseri.readFileAndSave();
item = parseri.getItem(1);
And code inside my XMLObjectParser
public XMLObjectParser(string file)
{
xmlreader = new XmlTextReader(file);
this.file = file;
}
Thanks
Your code tries to open a file without specifying a path name.
In this scenario the resulting location of your file is the IIS process startup directory, not a folder inside you web site.
If you want to reach a file inside your web site folder you use Server.MapPath.
As explained in the docs, if you don't set any relative path then the file is assumed to be present in the same folder where is located your ASP page.
So, you could write
XMLObjectParser parseri = new XMLObjectParser(Server.MapPath("XML.xml"));
if your file should be located in the current folder relative to the calling page.
You can specify any folder inside the folder structure of your web site using something like this
XMLObjectParser parseri = new XMLObjectParser(Server.MapPath("/APP_DATA/XML.xml"));
More info on Server.MapPath here

C# + File.OpenRead(path_to_file)

I am developing a HTML5 based WebApp being hosted in IIS7. This webapp sends requests to webservices being hosted in IIS7.
The service initialization looks up for a specific file e.g: "appfile.txt" as
FileStream stream = File.OpenRead("appfile.txt"); // opens file for reading.
This call when run as a console application looks up in the project\bin or output directory and able to locate the specified file.
But the same hosted in IIS7 looks up in "C:\windows\system32\inetsrv\appfile.txt".
Are there any configuration item having used in web.config locates the file from the Bin directory of the IIS7 application and not anywhere else?
Any help is much appreciated.
If the app file is in your web application folder, try using Server.MapPath to get The location of the file relative to the root of the web app:
File.OpenRead(Server.MapPath("~/appfile.txt"))
That should work. You probably need to set up the appfile.txt properties so it is copied to the output folder.
You can certainly create your own section in the web.config file to grab the file path that you want. It doesn't need to have been predefined. Then just use any XML reader you want.
Alternatively, you can make a .resx file very easily in Visual Studio and just populate the path there as a variable.
Thanks for all your valuable comments, I could resolve this issue myself using the following code snippets
string path = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
string[] labs = File.ReadAllLines(path + "/appfile.txt");
This bit of code allows me to read the file contents without any issues.

Categories

Resources