MVC Razor Shared external layout - asp.net-mvc

I'm looking for a way to reference a shared external _layout.cshtml from MVC 3 and Razor.
A little back story:
We have multiple developers. All of them are working on separate MVC applications that all need the same look and feel. All these applications will be deployed to the same site for example
http://www.example.com/App1/
and
http://www.example.com/App2/
The look and feel will be generated by the CMS and dropped into a different folder
http://www.example.com/Layout/_layoutExt.cshtml
I've tried
MasterName = #"C:\inetpub\wwwroot\layout\_LayoutExt.cshtml";
But it gives me the error that it can't find the file
The view 'Index' or its master was not
found or no view engine supports the
searched locations. The following
locations were searched.

My eventual solution was to use Symbolic links (or junctions or hard links) to link the needed file into the view folder. This way the CMS writes to one location and my app reads from another. Not the clean solution I was looking for.

You'll probably need to make your own view engine that support reading file outside the web application home directory.

Related

AngularJS + ASP.NET MVC: routing URLs without corresponding physical view

Context
We have a web app using AngularJS with ASP.NET MVC. It aims to replicate a file-system structure through URLs, like this:
http://(site1)//rootFolder//NFolders//File
For views in Angular, we are using stateProvider, with different states associated to existing views in disk (.cshtml files).
The problem issues when we request a file or folder from the browser and we try to serve a virtual view that doesn't really exist. We have just been able to achieve it with a full postback and some hacks, making a complete reload on each file/folder request.
Question: Is there a way of achieving that in Angular? Other way, the request for different URLs which don't have either their corresponding physical view as a file or any state in stateProvider, handling them with Angular and customizing a specific view which would deal with disk routes requested by URL?
RE-EDIT
We will have:
a fixed root view for the website: http://website
several root projects with a name:
http://website/site1
http://website/site2
....
http://website/siteN
each site may have different files and folders accesible via the URL:
http://website/site1/folder1/folder2/.../foldern
http://website/site1/folder1/folder2/.../foldern/fileX
RE-QUESTION: is it possible to handle this "virtual" URLs without having a physical view behind for folders or files? Our idea is to have one unique view called siteController which would control all the sites, and paths to folders and files.
I would suggest you define rootFolder/NFolders/File as parameters. Then you can have a html file as the view template to populate data from server.
Have a look at this link
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service

MVC Web Api - barebones minimal project structure

I'm looking at this MVC WebApi starter kit (for Angular/TypeScript)
Ignoring all the client side code, I noticed the author has made a WebApi that is extremely bare bones. Has has taken out most scaffolding including _ViewStart.cshtml, _Layout.cshtml, and forgoed the convention of controllers in Controllers folder and views in View folder under subdirectory with same name of controller, etc.
He added some interesting Routing and Validation classes that I havent seen before in a Core folder and put controllers in Api folder and Views directly into Views folder with an Index.cshtml at the root.
It's very clean and barebone project structure for a standalone web api that will do nothing except serve data to a client heavy application. I kind of like it this way but before jumping ship I'm wondering what drawbacks this approach has and if I'm actually giving up any core features of the framework by doing it this way. For example, clearly MVC Areas are being given up here in favor of flexibility to create your own view folders structure and seperation of application sections (I'm okay with getting rid of MVC Areas I rarely used them anyways). Another thing is I don't think a Controller action method can return View() and it will find it in the Views folder by convention of the controller name. I'm also okay with that since I will only be serving JSON data and will use 100% client side templating.
Are there any other core features that are being abandoned that I'm missing that may make me regret going with this project structure?
When I create Web APIs that are hosted in IIS, the only files in my web application are web.config, global.asax and global.asax.cs. Everything else is not required.
Take a look at this template if you haven't already before you decide how to structure your ASP.Net MVC / Angular project:
http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83
You can always add components into your project later, so I wouldn't seat it too much. I like to start with a lean/mostly empty project first and add things myself so that I fully understand what I'm adding.

Durandal and ASP.NET MVC conventions

I'm currently evaluating Durandal for use in an enterprise ASP.NET MVC application.
However the default conventions used by Durandal seem to conflict with the MVC conventions I've grown accustomed to.
The HotTowel MVC template by John Papa is great, but this too seems to "do away" with MVC conventions in favour of Durandals by putting things in an App folder.
A couple of the issues I have with these conventions are:
Views are potentially split across two locations (/App/views and /Views).
Scripts are also split across two locations (/App/durandal and /Scripts).
Views are not in the default MVC locations for the RazorViewEngine.
I would prefer to keep each element contained in the appropriate MVC conventions e.g.
/Controllers/
---- HomeController
---- AdminController
/Scripts/
---- durandal/
---- viewmodels/
-------- Home
-------- Admin
/Views/
---- Home
---- Admin
My questions are:
Is it possible to configure Durandal to achieve the above (or something similar)?
Is it wise to venture away from the default Durandal conventions?
What are the potential issues in doing so?
1. Is it possible to configure Durandal to achieve the above (or something similar)?
Yes, you can have any folder structure your heart desires. Durandal does not impose any folder structure on your application but it does have a default convention which is completely overridable.
If you are using Durandals router then you will want to look into how to configure it to find modules. There are many ways of doing this, I prefer to create my own convention by overriding the router.autoConvertRouteToModuleId.
If you are not using the router plugin then you will have to manage the uris for your modules yourself and this is done by following requirejs' convention and using this convention along w/ durandals composition module.
Also, you can override how it finds the views to bind to your modules by overriding the viewlocators convention. Durandal provides an very simplistic way of structuring small applications right out of the box but if you need to build larger applications then it is recommended you create your own conventions.
2. Is it wise to venture away from the default Durandal conventions? 3. What are the potential issues in doing so?
So, there are the conventions of how to discover modules and how to discover views which are completely overridable. And I recommend you do override these and choose a way that suites you best. But, as for placing durandal inside your scripts folder as you have listed above I dont think its a good idea.
The reason I dont recommend this is because I see the scripts folder as a place for all your third party scripts that are NON-AMD modules. This is because Durandal also comes with an optimizer.exe which makes minifying/compressing/uglifying all your html/css/js (amd) files into 1 file.
If you keep your entire application under an app folder and then have the durandal folder inside your app folder the optimizer just works because it lives inside the app/durandal/amd folder. So, when you execute it, it will transverse up 2 directories to your app folder and then scan every subfolder to create a app.build.js requirejs optimization file.. and then it will compress your entire application to one file for you.
This beats having to hand edit an app.build.js file everytime you add a new file to your project. Sure.. there are other tools out there which can do this too.. but you will have to spend time learning their api and how to configure them. If you dont feel like devoting the time to learning something like grunt then this optimizer is kick ass. Personally, I like the ability to just double click something and have my whole application built for me.
As for placing all your third party libraries which are non-amd in a seperate scripts folder I would look into compressing those seperately like using MVC's bundling. The reason I would bundle those seperately is because you know those files arnt changing very often and if you bundle those into a seperate js file they can be cached by the browser seperately. Whereas if your spa is changing, which it it probably will.. then you want the browser to cache that seperately so it only has to re-download your compressed application.
What we do (this is what I have seen Rob doing too:) is that to create folders inside the /App folder depending on the functional areas of the app. Then just create view and view model file inside these folders.
Trick is to have a "viewUrl" property in each view model to tell durandal which view to use.
This way of structuring the application is useful for large projects where there are many views/view models ; avoids confusion when your project grows.
define(['durandal/app', 'durandal/system', 'plugins/router'],
function (app, system, router) {
var vm = {
viewUrl: 'myfolder/myview.html',
};
return vm;
}
);
You can still use viewLocator.useConvention(); when you bootstrap your application; durandal will still find the view as long as you have viewUrl property.

How do I serve static files from mvc without using content folder?

I want to be able to have a folder which allows regular access like the \content folder except that it holds a ClickOnce application. I can't seem to be able to achieve this using Mvc, but I'd like to have this folder accessible without Mvc seeing it as a controller action.
I tried using routes.Ignore(theUrl), but this seemed to have no effect.
There are two ways you can do this. The first is where you are currently going, which is to satisfy it with routing. You should be able to use the following to ignore the intended route:
routes.IgnoreRoute("...")
However, this might not be the right approach from a security stand point. I would recommend you define an explicit action to download your click-once exe. Have a look at this q/a as an example of using the FileContentResult class.
The reason for this is that you can control security for that file without having to open up access levels to other directories.
Edit: If this is for an entire directory, you can still follow this same approach.
Set up the folder as a virtual folder in the website on IIS. then you can set the url in the code to point to the machine serving the request and to the virtual folder on the web server.

Render View (or Partial) In another project?

i have a solution with the following two projects - MyNamespace.Services and MyNamespace.Web.
Web contains a MVC web application.
In the Service project i have a EmailService class that takes care of sending out emails to the user.
I want to use either a partial or a view (ascx or aspx) for email templates.
I have found several solutions on how to render a partial view and get the result as a string which works fine if the template is inside the web project (as it is a controller in the web project that calls the email service).
(the 2 methods i am trying to use is either http://developersisland.blogspot.com/2009/01/renderpartial-to-string-in-aspnet-mvc.html (at the bottom of the blog) or http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc/)
But my email templates are located in the Services project.
How can i refference the path to the templates (partial/view) in my Service project from inside the Web project, that works with either LoadControl or RenderPartial which both takes a virtual path as a parameter ?
It seems like no matter what i do the root directory is set to the Web projects directory.
Is it possible ?
Would be nice to be able to make it work independently of the web project somehow.
I don't think this is possible without developing your own view engine. The default view engine will only look in certain locations for the partial view -- which includes the current view folder and the shared views folder. I don't think you can search for views outside the current project since those views aren't registered with the view engine.
You can consider just creating your HTML helpers to render emails and return it as a string.
Doesn't really matter whether it is partial view or a method returning a string with HTML. i actually think that for your case helper methods would be a better choice.
A simple helper method is also more flexible in the ways you can use it.
You could try creating a custom view engine locator or virtual path provider. Here are a few examples that may help you get going:
Views in seperate assemblies in ASP.NET MVC
Grouping Controllers with ASP.NET MVC
How to use virtual path providers to dynamically load and compile content from virtual paths in ASP.NET 2.0
All of the links above are good, this might help as well. you will certainly be able to get it to find and use the views. The problem I had was in working with them, there was no code completion etc in the other projects. It was semi possible to get that as well by fiddling around with the project file but to be honest I ended up going with the Grouping solution above
Plug in architecture for ASP.NET MVC

Resources