ASP.NET MVC3 - Distributing EditorTemplate in library project? - asp.net-mvc

Is it possible to distribute an EditorTemplate control ASCX along with a type in a library project and have it be used by MVC3 when the type is rendered with the EditorFor() method?
Where I work we have a lot of DateTime, Gender and a few more custom fields which have a specific but concsistent way of (HTML) input and a corresponding backing ViewModel type for them (i.e. DateTimeViewModel with separate month, day, year field etc.) and they are in a shared library project.
However we still have to copy the EditorTemplates for these types to each project which is not very DRY.
So is there a way to bundle such EditorTemplate along with the library project and make sure that it's used when the corresponding ViewModel is used without having to copy all EditorTemplate to every projects?

You need a custom VirtualPathProvider to achieve this but nothing out of the box. Here's a blog post you may take a look at.
Disclaimer: Custom VirtualPathProviders don't work with precompiled web applications. So if you intend to precompile your web application before shipping don't use virtual path providers.
Because of this limitation personally I use custom NuGet packages that allow the developers to pull all the necessary templates to their corresponding locations.

You could create your own VS Template, Export it and distribute it to all of your developers I think.
Write Templates for VS2010

You can register your own VirutalPathProvider implementation:
HostingEnvironment.RegisterVirtualPathProvider(new YourViewProvider());
Then you will be able to get your files from basically anywhere (for example from embedded resource).
Hope this helps.

I think this is not currently possible. ASP.NET MVC editor templates should be defined in a partial view file. There is no way to define them in code only.

Related

Cakephp bake equivalent in asp.net mvc

I was developing with cakephp for a few years and now want to try out asp.net mvc.
In cakephp there is a bake plugin, that allows to create standard functionalities based on customizable templates. E.g. changing these templates according to my needs
1) for controller
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Controller/controller.ctp
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Element/Controller/index.ctp
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Element/Controller/add.ctp
2) for model file
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Model/table.ctp
3) for view files
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Template/index.ctp
https://github.com/cakephp/bake/blob/master/src/Template/Bake/Element/form.ctp
I could run a command from CLI and get full functional validation, controller files with actions and view files - based on the existing tables' structures and relations between them. The plugin will create actual php files in corresponding directories with content according to template files. Having pre-customized bake templates allows to generate the CRUD or any other custom functionality in a few minutes.
Is there a similar functionality in asp.net mvc (v5 or above)? The desired features are to be able to fully customize the templates, which will be used to create controllers, cshtml files and model files - assuming that we already have the tables with foreign key associations in the database. (Preferably free, but not necessarily)
Thanks
I think this link might help you with templates in visual studio. If you want to use command line, maybe yeoman can help you. See this link to see if it'll work for you.

MVC editor templates in different assembly

I'd like to create a common assembly that I can use in several MVC projects (MVC 4 preferred). This assembly has to provide editor templates for primitive types. For example, a date picker. How can I do this?
I know of two ways to achieve similar goals, but I don't like those. One way is to forget about MVC's templating system and provide custom HtmlHelper extensions, like #Html.MyOwnDatePickerFor(x=>x.Field). I know of some UI frameworks that do this. I don't like it because it is not transparent (#Html.EditorFor() won't pick it up automatically) and it feels weird to have an editor template system in MVC and not use it. The other way is the actual MVC template system, by creating partial views named like EditorTemplates/datatype.cshtml (or .ascx), but it doesn't work because they have to be in the MVC project, I don't know how I can share these between multiple projects.
Any suggestions?
We have a few classes that provide the equivalent of editorfor but surrounded by different HTML. We have one for #Html.CMSEditorFor(m => m.Name) that uses the same HTML as our content management system and one for #Html.BootstrapEditorFor(m => m.Name) that churns out HTML in a nice Bootstrap compatible way.
I can't claim any credit for the idea though it comes directly from here.
ASP.NET MVC 3 Custom HTML Helpers- Best Practices/Uses
You're looking for RazorGenerator. It's made by the Razor team to allow you to compile Razor views just for this purpose: reusing the views by including the assembly in other projects.

Where do you put non-controller, non-model code in a ASP.Net MVC project?

Where do you put non-controller, non-model code, like util classes, extension methods and so on in a ASP.Net MVC project? Maybe there's not a specific place to put it, you just put it anywhere, if so, any recommendation? Any best practices?
if it's a single class i put them in a "Library" folder on the project root. If it's a bit bigger I use a specific folder and if it's something more complex i create a new project in the same solution.
According to the Kigg Sample MVC web project (You can get it from the official ASP.net), they put extension utility classes with a subfolder under root.
Good references for ASP.NET MVC Best Practice
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx
http://weblogs.asp.net/rashid/archive/2009/04/03/asp-net-mvc-best-practices-part-2.aspx
App_Code is intended for such purpose if I'm not mistaken.
Anything stored here (including in subfolders) will be accessible throughout the application.
In VS2015 Community (probably others as well but I've not checked) it's even in the context menu under Add -> Add ASP.NET Folder -> App_Code along with a few others.
My recommendation is to put them where they are used most. So if it is the controller that uses them put it with the controller, and so on.

Embedding View files as resource inside Binary

I am trying to create a .Net Library with few Controllers, and i want to reuse them in Multiple web projects.
I'm half way through, But problem i'm getting is , Whenever i add the library to the new web project , i need to copy all corresponding view files separately to the new project. Whenever i update the library, i need to repeat the steps again.
Is there any way , i can embed View files inside dll as resource , and pass it to "View()" function as an embedded resource.
What i want to achieve is , I want to put controller and corresponding views inside single dll file, so that i can easily distribute/manage the library as a single dll file
( Oneway i already found , is creating custom view class with IView Interface and Render the output directly by writing to HTML Output Writer, But i prefer to use the View file.)
Phil Haack just posted a blog post a few days ago that would probably help you; He's using a database to store the views and ruby to process them, but I would think you could take his prototype and make it work for views stored in a separate assembly fairly easily.
Just a quick glance through the code and I think the magic sauce is going to be implementing VirtualPathProviderViewEngine (See the "RubyViewEngine" class for example) and inserting your ViewEngine into ViewEngines.Engines Collection (see Global.asax.cs).
You can probably use a VirtualPathProvider for this.
The WebFormView type eventually calls BuildManager.CreateInstanceFromVirtualPath. There is not an overload or other function in BuildManager to take input from a stream instead of from a virtual path. Therefore, if you do not want to implement IView yourself, you will need to actually unpack the files to disk so that they can be compiled by BuildManager. You could still distribute your DLL as a single file, but the aspx files need to be produced in order for BuildManager to compile them. See BuildManager help for details.
Check out the ASP.NET MVC View Engine using VB.NET XML Literals project on CodePlex http://vbmvc.codeplex.com
It is a custom view engine originally conceived of by Dmitry Robsman, who is a PUM for ASP.NET at Microsoft. Each view is a VB.NET class and the Namespace (instead of file path) is used to connect Views to Controllers. It's fairly straight forward to copy the content of your ASPX view files into the XML literals in these VB classes. And as classes, they are compiled into the assembly without any extra effort.
If your controllers are C#, then most likely you'd end up with 2 DLLs, but Scott Hanselman has a blog post on getting C# and VB to live together in the same assembly. http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx
Take a gander over to codeplex and have a look at the Managed Extensibility Framework
Once your done there...
See what Maarten Balliauw has to say about ASP.NET MVC and the Managed Extensibility Framework (MEF)

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