ASP.NET 5 keeping the wwwroot 'clean' - asp.net

I'm working on a website and I use ASP.NET 5 CLR (rc1-final x64).
I want to have my wwwroot folder 'clean'. I feel everything that should exist in wwwroot should be added on build or through tasks (for example through Grunt). I'm using Grunt for this, and this works fine with JavaScript and CSS files.
Now I'm at that point of adding images to my website. Right now my .gitignore says to exclude the wwwroot. I don't know how to move images from outside the wwwroot to inside it. Is there any good way to move files to the wwwroot? I really want my wwwroot 'clean' without any libraries. I have those outside of the wwwroot, so I don't accidentally serve unwanted files.
I want to move them from:
[Application Root]/static/img to wwwroot/img.
Currently I have the following grunt tasks:
grunt-contrib-concat
grunt-contrib-cssmin
grunt-contrib-uglify
I think this may be very in-efficient because on build we need to move all the files every time.
Is there any way to do this better / more efficiently?
EDIT #1:
Yeah, so I read the documentation: http://docs.asp.net/en/latest/fundamentals/static-files.html.
I could actually just pass in a parameter to the app.UseStaticFiles() method like this:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(#"D:\Source\WebApplication1\src\WebApplication1\MyStaticFiles"),
RequestPath = new PathString("/StaticFiles")
});
Here the PhysicalFileProvider contains the absolute path. Is it possible to use a relative path here?
EDIT #2:
Actually this works:
public void Configure(IApplicationBuilder app, IHostingEnvironment environment, ILoggerFactory loggerFactory, IApplicationEnvironment appEnvironment)
{
app.UseIISPlatformHandler();
app.UseDeveloperExceptionPage();
app.UseMvcWithDefaultRoute()
.UseStaticFiles()
.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(string.Concat(appEnvironment.ApplicationBasePath,"/static/images")),
RequestPath = new PathString("/img")
});
}
Here we add the UseStaticFiles middleware twice to serve the default, which is wwwroot. We will also serve files from within the solution where the images are.
However, I don't know if there would be any performance or security problems or other problems by adding this middleware twice. You need to be careful in what you add in this folder. Directory Browsing should atleast not be enabled.

Are you sure you want to keep wwwroot "clean"?
You cannot easily reference static content outside of wwwroot so doesn't it make more sense to keep the static files below wwwroot and just segregate them into sub folders for dev vs production and then just use publishexclude in project.json to leave out the dev stuff.
Myself, I only want to run grunt tasks prior to publishing to produce the production set of files, then I want to leave the dev versions of the files out of publishing. I do not want to run grunt just to move files so I can use them during development and I don't want to run grunt every time I edit the dev/src versions of my js files.
The problem of that approach becomes more obvious if you pull in something like ckeditor which is a huge number of files that I don't want to copy or move around the file system much, at most I would move them once pre-publish to clean out any extra files as I move it to a production folder.
Back in MVC 5 there was no concept of separating the static files from the code, the web app just served files out of the same root app directory that also had server side code. At that time having static files in a /Content folder or js in other folders made sense. But trying to keep static assets outside of wwwroot in MVC6/aspnet5 seems to me to be working against the grain of the wood.
By keeping all static assets including the dev versions of them below wwwroot I have an easy workflow where I can just edit a js file and refresh the page as discussed in this question. This feels like I'm working with the framework and not against it.

Related

Trouble initializing less stylesheets on my meteor app

My less style sheets are located in my /public folder for now. I'm trying implement them on my meteor app but to no avail.
This is the error I get:
The stylesheets are located in the /less folder, which is inside the public folder, so the URL should be correct. By the way, all those files that are in the screenshot above are files that import dozens of other variables located deeper in the folder.
I also checked and I have the latest version of less installed. Any help would be appreciated.
The public folder isn't the right place to store the files. Files stored in a “public” folder are served to visitors. These are files like images, favicons, and the “robots.txt” file. So they get served 'as-is', not processed by LESS and served as CSS.
More about Meteor folder conventions.
After discussion in the comments, it seems something is not working right in your less compiler, the less file should not be in the public folder, as already mentioned, and you should not need to include it with a script tag. You can follow these steps to create a new app and test less and see if you can find a difference between this and your current app.
Create a new meteor project
meteor create test
Add less
cd test
meteor add less
Start your server
meteor
add a file sytles.less to the top level folder with this...
.fun {
color: red;
}
Update the test.html file to add the fun class to the text output...
<div class="fun"><p>You've pressed the button {{counter}} times.</p></div>
Load the page, the text should pick up the class and become red. No link to the styles.less file needed. You can try moving it around to different folders, it worked fine from client for me as well. Look around and see what else might be different.
If you still have issues, try providing more information on how the project is set up.

Default .bowerrc pointing to wwwroot/lib in asp 5

Why is this a default point for an empty asp project in the .bowerrc file?
{
"directory": "wwwroot/bower_components"
}
In most cases one would use gulp and create tasks to include only the requested files
gulp.src([
'bower_components/jquery/dist/jquery.min.js',
'bower_components/bootstrap/dist/js/bootstrap.min.js'
])
Thereby creating a cleaner wwwroot. The project.json file even includes an exclude for "bower_components"
It looks like it initially was outside of the wwwroot folder, but developers who weren't used to this workflow (ie. using Grunt/Gulp to copy the relevant files) were getting confused. So they changed it to be inside the wwwroot folder.
Scott Hanselman has a good post about why they did this, and how to change it back to be being outside ...
http://www.hanselman.com/blog/ControlHowYourBowerPackagesAreInstalledWithAGulpfileInASPNET5.aspx

Using grunt-usemin with Mean.io (separate public/ and app/ folders)

I created a new project using yeoman angular generator which I then modified to some extend to fit my own needs. However later on I realized I'd like to use mean.io for express and mongodb supports. It took me quite some time to copy necessary parts from the mean.io default project to my own project. However I am still facing serious problems with grunt-rev and grunt-usemin.
The original yeoman generated project had app/ folder which contained all the AngularJS items. The new project however has app/ folder for all the items that exist in the server and then public/ folder for all the items needed in the client end. Now the grunt-rev plugin renames the css and image files to contain some identifier that matches the version of that item. I think this is pretty useful so I would like to keep it in my project. Now then; my index.html is located in the app/ folder and all the css and images are in the public/ folder. In my index.html I got images in format like "<img src="images/imagename.png">". This works when I test the project by launching the node express server since it offers both the app/views/ and public/ from the same location which is the server root. Usemin doesn't understand this however as the image sources don't match the absolute folder structure. I tried to move app/views/ content to app/ but to no avail. The same happens with css files that are built with cssmin. I got property in my index.html and under that all my css. After the build I got styles/main.css there but as usemin doesn't realize the folder structure, I end up with styles/main.css in index.html and 986a2d75.application.css in styles/.
Is there any way to let usemin know that two folders should be handled like they are one? I found that you could force usemin to look for certain pattern but that would force me to remember to add every image to gruntfile separately so I'd rather not use these plugins at all before I'd do that.
Finally found out about Generator Angular Fullstack which did everything I needed and more. It properly handles the copying of files from src->.tmp->dist and does all the necessary usemin magic in the process. Awesome tool!

asp.net static content in separate project. now how to refer?

Project1.csproj is the website project and StaticContent.csproj is the static content project to hold all .css, .js and image files. I am keeping it separate so that designers can work without touching the main project file and may be use cdn in future. But the problem is how do my .ascx and .aspx pages will refer to these css and js files as that when I run in localhost, it still picks up.
I think the best way is you create a website in IIS for the Static project, and reference it trough something like static.myproject.com (having the appropiate setup) on the other one.
You can still use Webdevserver on Project1.
Is most like what you will have when deploy, and you can put the URL on web.config for easy change

How might i setup my ASP.NET project to find my files?

edit I do not want to redirect pages, specific files etc. I would like to change the path where images, videos and other media are stored from the root source directory to the directory of my choosing. In this case c:/dev/prjfiles/prjname/public (c:/dev/prjfiles/prjname/ is my working directory) and i except when my html does img src="/pic.png" it will find the image in c:/dev/prjfiles/prjname/publi/pic.png. I need a working solution, i tried looking at how to set virtual directories and etc. I cant figure it out. Thus the bounty. I am generating the html, i am not writing asp:image runat="server" etc i am pulling data from a DB and outputing the html. The part that is still a WIP is the code that handles POST request. The html already exist but i cant have hundreds of files in site.com/here pollution my source directory (c:/dev/trunk/thisprj/thisprj/where my .aspx files are and i do not wish 500 .png/gif/jpg here)
I dont know how asp.net environments are usually set up. I am assuming i have a root path that is not available from the web, a bin/ where i may put my asp.net dll and a public where i stick in any files i want.
I would like to have my project files seperated from everything else. My JS, css and image files are in prjfiles/prjname/public with my sqlite db in prjfiles/prjname/ and extra binaries in prjfiles/prjname/bin.
The problem comes when i run my app and try to load an image. Such as /cssimg/error.png. My project does not find resource in my /public folder and i have no idea how to make it find them. How can i set my project up so it does?
NOTE: I set the working directory path so its at prjfiles/prjname/. In code i write ./bin/extrabin.exe and db.sqlite3 which access the files properly.
You might want to watch the getting started videos for ASP.NET
http://www.asp.net/get-started/
EDIT: More info added
As #Murph suggests, your assumptions are incorrect.
IIS takes care of blocking HTTP access to any important files and folders like your *.aspx.cs, and *.cs in the App_Code, any DLLs, anything under the App_Data directory and the web.config.
Content files, such as *.html, *.css, *.js, .gif, .jpg, .png are all served in the normal manner.
In this way, there is no need for a "public" folder.
I dont know how asp.net environments are usually set up. I am assuming i have a root path that is not available from the web, a bin/ where i may put my asp.net dll and a public where i stick in any files i want.
This is wrong assumption!
You have a root folder, which IS available in public. You set IIS or ASP.NEt Development Server to this folder.
(optional, but always needed) You have a web.config file in this root folder for configuration
You have a bin folder for your assemblies (each page or user control "include" compiles to a class)
(optional) You have App_Data as default folder for file-based DBs and/or other data files (say XML storage, ..)
(optional) You have an App_theme folder for styling and images. Read about ASP.NET themes.
(optional) You can add App_Code folder if you want to add classes to be compiled by the server.
You can create folders for scripts, etc...
Normally for complex logic, etc.. you create in a separate project outside the root and reference the result assembly in the bin folder.
Seriously, you cannot do ASP.NET work without an IDE or a manual. Visual Web Developer 2008 Express IDE is free and http://asp.net has tons of resources for getting started.
I don't know if I got the question right, but maybe you could try the <BASE> HTML tag.
HTML <base> Tag
"Specify a default URL and a default target for all links on a page"
There's a nice and simple example at W3Schools, check it out.
The negative side is that you need to put a <BASE> tag in each page you want.
It sounds like you should be able to create a virtual directory to do what you're asking -- but it's a very non-standard setup.
Keep in mind that IIS will prevent users from downloading DLLs and other project-level files, so you usually don't need to partition them off in a separate layer.
For example, just have a cssimg folder at the top level of your project, and skip the whole public folder thing.
I see where you're coming from. ASP.NET projects are set up a little differently from how you're treating them, but you can make them work like you want.
The root of an ASP.NET project IS publicly accessible. When you created your WebSite within Visual Studio, it created a default.aspx page right on the root. Are you hosting in IIS? If so, it's set up to serve up default.aspx by default. But I digress.
Here's how to make it work like you want (mostly):
Create a WebSite, then right-click the site and add a folder named "prjfiles". Right-click that folder and make another named "public". Create another subfolder of that one called "cssimg".
Now, if you want to use the image you mentioned, you'd reference it like this: "~/prjfiles/public/cssimg/error.png" (pathing starting with the root) or "./cssimg/error.png" if you're coming from a page in the public folder (relative pathing).
Really, though, you're doing too much work. Here's how to make it work with less effort:
Create your WebSite, right-click the project and add a folder called "cssimg".
Treat the root as you would the "public" folder- put your pages right there on the root or in subfolders, as needed. You can reference that same image file like this now: "./cssimg/error.png" (relative) or "~/cssimg/error.png" (start from root)
There's also another way to tell the engine where to look for resources, but it's for your css files. Inside the "head" tag, you can add a "style" element (with type="text/css") and inside that you can add something like this: #import '<%= ResolveUrl("~/prjfiles/public/cssimg/styles.css") %>';
Good luck!
If I correctly understood your problem, you're trying to find files which aren't physically stored on a filesystem folder, or stay on a different folder. You can deal with this problems by implementing a UrlRewrite mechanism.
I suggest you to read URL Rewriting in ASP.NET and, after, to take a look into this implementation: A Complete URL Rewriting Solution for ASP.NET 2.0.
If I understand all this correctly (please comment with any correction) right now all your files are together in the root directory and you use <img src="/img.png" /> and it works.
If this is the case, make another directory in the directory the images are in, say call that directory images and put the image files there. now use <img src="/images/img.png" />.
Done.

Resources