The question "https://stackoverflow.com/questions/16397785/add-pages-to-mvc-deployed-website" seems to relate closely to the question I want to ask. But it my case, I have not yet developed an application, but I want to develop it in such a way that it can be customized by users after it is deployed by adding files to the deployed directory. What would be the advisable way of doing this? Specifically, I want users to be able to define custom pages, possibly replace existing pages or add controls to existing pages, and possibly define custom WebAPI functions to retrieve custom data. I tried adding .vbhtml files to the Views directory as described, but ran into the same problem described in the linked question.
4 Answers
Razor views are compiled at runtime, so you always deploy them un-compiled.
What you want is simply Razor pages, so can add them to any directory (not Views) and access them without the file extension (e.g. /Foo/Bar instead of /Foo/Bar.vbhtml).
17 Comments
.aspx. See asp.net/web-pagesI don't think I would recommend using the filesystem for this. I think you should save the razor code to the database and then, when you wish to parse it, you may do so according to this Using RazorEngine to parse Razor templates concurrently
Here is another example:
var model = new { Name = "Test" };
var template = "Hello @Model.Name";
var result = Razor.Parse(template, model);
Code taken from Using Razor engine on strings - not views
Edit to answer your questions:
The razor code would be stored in the database along with whatever controller you wanted to run it. When you retrieve the razor code from the database, you would also know the controller, then you could redirect to that controller, sending whatever model you want, to the razor code, and then parse it as shown above. Make sense?
7 Comments
The routing configuration can be customized to identify a URL pattern that identifies all requests for customized code and route them through a common controller that can then load arbitrary views based on information provided in the URL. Notice the route with the name Custom below, and how it always uses the Index action of a controller named Custom, but introduces a new parameter customization.
Public Class RouteConfig
Public Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
routes.MapRoute( _
name:="Custom", _
url:="custom/{customization}/{id}", _
defaults:=New With {.controller = "Custom", .action = "Index", .id = UrlParameter.Optional} _
)
routes.MapRoute( _
name:="Default", _
url:="{controller}/{action}/{id}", _
defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} _
)
End Sub
End Class
Once this is set up, add a controller called CustomController to the project that simply passes through to a view determined by the customization parameter:
Public Class CustomController
Inherits System.Web.Mvc.Controller
'
' GET: /Custom
Function Index(customization As String) As ActionResult
Return View(customization)
End Function
End Class
Publish this code and add a Custom directory under the Views directory in the deployed location. Now you can put any .vbhtml file in the Custom folder and refer to it with a URL like http://localhost/MyApplication/Custom/MyView, which will load MyView.vbhtml from the Views\Custom directory.
2 Comments
If the main intent is to provide extensibility, then there is a simpler answer. ASP.Net will probe all assemblies in the bin directory of the deployed web application and pick up all controllers and models in compiled assemblies there, as well as all un-compiled views in the Views directory. With some effort I was able to determine a minimal set of files necessary to create an independent template project that could be used by people who would develop and deploy custom code into the running (deployed) web application. The details are provided as an answer to a more relevant question I discovered on this topic because it was not straightforward to get Intellisense and other ASP.Net MVC4 apsects of this template project working. See https://stackoverflow.com/a/21122377/78162
Since Visual Studio Express is now available for free, my hope is that such a template project could be loaded as a starting point for developing customizations to another ASP.Net MVC4 application. My limited testing indicates this will work for both the UI layer (as demonstrated in previous link) and the API layers (as discussed at https://stackoverflow.com/a/21028825/78162).