Getting and storing the path of file in asp.net 5 - asp.net

In previous version of asp.net the HostingEnvironment had MapPath method to get and store the path of the file but in ASP.net 5 I can't use it.
var filepath = HostingEnvironment.MapPath(#"~/Data/product.json");

Are you using RC1?
In RC1 it depends if you are writing a console or web app. In console apps, you cannot use DI anymore but PlatformServices.Default.
PlatformServices.Default.Application gives you access to the base path of your application for example. The type of the static property is IRuntimeEnvironment. And having the base path of your app, you can easily build the path to files you need...
If you are building a web app, you should be able to inject IRuntimeEnvironment to your startup and use it from there.
You have to add a reference to the Microsoft.Extensions.PlatformAbstractions package to all that stuff.
See also my post here for more details

Despite IHostingEnvironment provides MapPath() method you may also need UnmapPath() too. Another useful method might be IsPathMapped().
You can find all of them here: Reading a file in MVC 6.
And all of them, thanks to PlatformServices availability, work in Consolse, MVC, and ClassLib apps.
HTH

Related

Native DLL dependencies with ASP.NET MVC Projects

EDIT: I found a way to get it to work locally, but on Azure I still get System.IO.FileNotFoundException on that assembly.
My question might seem like a duplicate to this question here. But it is slightly different, I have already tried that solution and it did not work. Here are the details.
I have an ASP.NET MVC App that has a Reference added to a third party CLR DLL. That third-party DLL requires a native DLL which it invokes. Now if I had control over where the Shadow Copying occurs and what is copied, I would be in paradise. The Shadow Copying misses copying that native DLL despite it's Build Action set as Content and Copy To Output Dir set as Copy Always.
So I searched internet and ran into this discussion on SO, which is same as what was mentioned earlier. I tried adding the code that sets the PATH Environment Variable inside Application_Init and Application_Start of Global.asax, I set the breakpoints in both the methods and to my surprise I get the ASP.NET Error Page before it even hits the breakpoint. This leads me to believe that the referenced assembly at the time of binding hits the native DLL and invokes it. What can I do? Can I delay the reference binding somehow?
EDIT: Yes we can, I opened the Referenced DLL's code which was written in Managed C++, I adjusted the linker setting to Delay Load the Native DLL and now my Application_Start executes first. Yayy! but that does not solve the same problem I am having on Azure
Here is the test solution with DLLs
Here is the source code for the Native DLL
Here is the source code for the Referenced Assembly that uses the Native DLL
To download the Native DLL distribution, Go to their distribution page, choose the windows archive with the bitness you desire (I am using 32-bit), and you will find amzi.dll inside APIs/bin directory.
Actual problem was the wrapper DLL not recognized on Azure server because of lack of support of earlier frameworks and toolsets, as well as Debug CRT.
I used XDT/Application_Start to set the PATH environment variable to include the location of my native DLL
I upgraded my Managed C++ Wrapper DLL to use Toolset 14.0 and .NET 4.6.2
Used Linker Setting of /DELAYLOAD on Managed C++ Wrapper DLL
After downloaded the DLLs and source code which you provided, I found that the native DLL depends on x64 platform. Firstly, we need to change the Platform property of our web app to x64 using Azure portal. If the platform button is disabled, you need to scale up your web app plan to Basic level plan or higher level.
In addition, the original path may end with “;”, so we need to check whether it contains “;” and append right content to it. Code below is for your reference.
string path = Environment.GetEnvironmentVariable("PATH");
Trace.TraceError(path);
string binDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Bin");
Trace.TraceError(binDir);
if (path.EndsWith(";"))
{
Environment.SetEnvironmentVariable("PATH", path + binDir);
}
else
{
Environment.SetEnvironmentVariable("PATH", path + ";" + binDir);
}
To test whether the path is set successfully, you could add a page to test it.
public ActionResult GetPath()
{
string path = Environment.GetEnvironmentVariable("PATH");
return Content(path);
}
After path is set, the native DLL can be load successfully on my side.
On my end I added a throw new ApplicationException("Test") at the beginning of Application_Start and instead of getting my test exception, I was getting the DLL load error.
It means the setting path code will not executed. To fix it, you could remove the native DLL reference from your web application. Now your application could work fine and set the path environment variable. Then you could add the native DLL reference back.
Another way to do it is that we could create a webjobs and set the path environment variable in webjobs and deploy this webjobs before deploying your web application.
I am using 32-bit distributions, my native dlls depends on x86/32-bit.
If you use 32-bit distributions and the platform targets of your CLR DLL and your web application are set to "x86 or Any CPU", you won't need to change platform to x64 in web app. Please change it back to x86.

Setting project url in VS2015 ASP.NET 5 Web API application

I'm trying to create a Web API project and a client-side web project, where the web project can access the API via ajax. Currently my project looks like this:
I saw this answer on here: Setting app a separate Web API project and ASP.NET app, which explains how the project url can be set to localhost:[port]/api.
But for ASP.NET 5 projects, the properties only have 3 tabs (as opposed to the several found in ASP.NET 4 projects):
What I'm wondering is:
Do I have to set this option somewhere else? (i.e project.json)
How would this work when I publish? Ideally I'd want [websiteURL]/api to serve up my API, whereas that link explicitly put localhost:8080.
Is having these as two projects a good idea? I could easily put API and web in the same project, but I like the separation of client-side and server-side logic.
Any help would be appreciated!
First Point:
Generally speaking in ASP.NET 5, the routing defaults are very good and should work out of the box without much in the way of configuration. You can use configuration and/or attribute based routing in your application (with a detailed overview of both here), although my personal preference is for the attributed approach. Provided you have the following line in your Startup.cs file (which you should have in a new project):
app.UseMvc();
you should be able to route requests to your api controllers in the fashion required (i.e. "/api/...") simply by using [Route] attributes as below (example taken from a standard generated ASP.NET 5 Web API application)
[Route("api/[controller]")]
public class ValuesController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
The above example will route any GET request made to "/api/values".
While this approach can be used to handle requests made to your api, in order to deliver the files needed for your front end javascript application/single page app, you will need to enable static file serving. If you add the following to the Configure method in your Startup.cs class:
app.UseStaticFiles();
this will allow your application to serve those static files - by default, these are served from the ‘wwwroot’ folder, although this can be changed in the project.json file if required. The files needed for your front end app should then be added to this folder. A tutorial on serving static files can be found here.
Second Point:
In my experience this will not be an issue when you publish your website - provided your server is set up correctly, you will not need to include the port when making a request - navigating to [yourwebsitename]/api/... will suffice.
Third point:
In my opinion this entirely depends on how large the project is likely to grow, although preference and opinion will vary from developer to developer. Generally speaking, if the project will remain small in scope then keeping both in a single project is perfectly ok, as unnecessary complexity is reduced. However it is also very useful as you have pointed out, to maintain a separation of concerns between projects. So aside from the organisational advantage of your approach, the respective dependencies of the two projects are/will be kept separate also.

Access Resource File

Can anyone tell how to access resource file in class library asp.net mvc4? I'm building a generic Class Library that I will use it in all my projects. I tried with following code:
HttpContext.GetGlobalResourceObject();
Can anyone tell any other method is there to access the resource file in class library?
Edit based on the comments, including best practices :
To create a Resource file in MVC4 :
In the solution explorer, right click on your project.
Then, you click on "Add", then on "Add ASP.Net folder", and then click on App_GlobalResources.
On the new folder, you right click. Then you add a new Resource File.
You open then this Resource file and can add new resources.
The lefter column is where you set the keys, and the righter one is for the values you have to insert inside it.
Then; it is really easy, you just have to write the following parts of code to access the values you want.
On the c# side, it is :
Resources.NameOfYourResFile.NameOfYourResKey
On the ASP side, assuming that you're using razor, it is :
#Resources.NameOfYourResFile.NameOfYourResKey
Example :
If you have created a a file named "Global.resx", and created the key "ApplicationTitle", which has "My super website" as value, you just have to write the following line of code to put it for example into a string :
string siteTitle = Resources.Global.ApplicationTitle;
and that's it
When you create your resource you have to set the access level from internal (by default) to public. After this you simply can access your resources (if you reference the assembly) by the name of the resource and the static properties generated into them.
I would suggest you to create a new library for Resources
Once you are done making resources key value pairs then add the reference of your Resource Library in to your project. and then you are able to access the resource library in this way
Namespace.ReourceLibraryName.Key
just include System.Web.dll in your class library project and access the resource file just like you would have accessed in the MVC project
HttpContext.GetGlobalResourceObject();
when you add a refrence to this class library project inside your MVC project and run the project this code will be executed in the context of the MVC project and you will get the correct instance of HttpContext.
Note:- directly using HttpContext like this would create problems when you will try to test this application
You can add your resource file any where in your class library, but I think your question is how to use it, If your resource files name is Res1.resx and there is a key in it called message then you can call
Res1.message
from your classes in that library. But you I am sure you would like to use it event from out side the library for that you need to make your resource file public, please refer Visual Studio - Resx File default 'internal' to 'public'
please do let me know if it is the one you need or some thing else?

converted web site to web application, works without namespaces

I converted a web site project to a web application using this guide
http://msdn.microsoft.com/en-us/library/aa983476%28v=vs.100%29.aspx
In the guide it says that I have to add namespaces to my classes but I did not do that. The classes I have in the Old_App_Code directory are not placed into namespaces and the application runs just fine (tested on different machines). Is it because there is something special about Old_App_Code or am I missing something? Thanks.
You are misinterpreting what the guide is saying, it is NOT saying that you need to add namespaces to get the code to compile, but rather that the conversion process does not add the namespaces into the code files by using the folder/file naming constructs.
The guide is further underscoring the fact that when you add new items (i.e. classes) in a web application versus a web site; the namespace is automatically added to the code file, based upon the folder structure and file name of the of new class.

Get .NET assembly version for aspx file

I want to make a "properties style web form" that shows the application version for various .NET applications.
If I know the URL e.g. /someapp/default.aspx is it possible via reflection to execute that page and figure out the assembly version?
It's quite easy to find the executing assembly version, but without modifying the other application, is it possible?
Both the property page and the other application is running on the same server and in the same application pool.
Update: I've had some luck with
var url = "~/SomeApp/default.aspx";
var appType = System.Web.Compilation.BuildManager.GetCompiledType(url);
But navigating appType to find the assembly file version is not the same everytime.
Without modifying the web application to expose the version number through some URL-based retrieval (a simple page GET being the easy, obvious one), you're going to need to find a way to figure out where the DLL for the web application is from the URL.
If you can know the DLL's location, either by some convention (e.g. /appX/ is always at D:\Sites\appX\bin\appX.dll) or some configuration (you manually enter where each URL base's DLL is in a database), then you can retrieve that DLL's assembly version using the following code:
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Version ver = assembly.GetName().Version;
Code taken from this question.
Edit:
I've had a little look around, and there are some APIs to inspect the IIS configuration, so this is certainly a route to explore if you're trying to get from the URL to the assembly location. This question has an example of getting the physical path from the application/site name, for example. Microsoft.Web.Administration is the assembly to explore.
The ASP.NET engine streams nothing but HTML, javascript, etc.. to the client. There is nothing left of the assembly that gets passed in the response that can show what version of .net/asp.net that the application is running unless the developer on the server side adds it.
That said, you can gather some information from a utility at http://uptime.netcraft.com/up/graph that will give you some server information. Not down to the assembly version, but this is as close as I believe you are going to get.
You may implement custom HttpModule, put it to the bin folder of each application that you wish to monitor and append register this module in web.config files. In this module for example you should handle request, retrieve all required information and put it to response cookie.

Resources