Replace MVC Application Part and Razor File Providers in runtime - asp.net-mvc

I have a WebAPI/MVC app which loads separate plugin assemblies with embedded controllers and views and puts them into the MVC PartManager. This works fine but now I'd like to be able to swap these parts out in runtime without restarting the server. I can use PartManager.Remove on the old part and Add with a new part, but this does not seem to be enough. When calling the controller I still get a response from the old controller in the old part.
Apart from adding parts in the PartManager I also add a EmbeddedFileProvider into the RazorViewEngineOptions on Configure because just adding an AssemblyPart does not seem to be enough for the Razor engine to find the view (not sure I'm doing this right). But I don't know if I can replace this Razor-fileprovider in runtime? I have not found a way.
Anyway, what is the preferred way of doing all this, I mean loading/replacing dlls with controllers, views and static resources. Am I on the right track even?

i think that Razor view engines are configured once only, so you cannot change them later.
What you can do is to
have multiple view engines running,
choose between them based on the URL (as in your case - you want to use a different engine for the one controller).
This is described in CUSTOMMOBILEVIEWENGINE section of Scott Hanselsman's blog post. What he was doing was to use different view engines for different devices, but you can adapt the technique for your own purposes.

Related

MVC project structuring

I have been looking for an solution for structuring my MVC5 project, but have not found anything yet.
What i look for is. I have an Main Website, which off-course has it's own Views, Scripts and Controllers, but what is special is that i like to have sub Website projects which add an menu point in the main page, but the sub website also contains it's own Views, scripts and Controllers( I have tried to draw a picture of what i'm talking about ).
The point of this is to have an structured in a easy way. But also to reuse the same views in a framework way.
You should be able to define an area in another project, found an article that explains in detail how it is done in MVC3, it should not be very different in later versions since areas and routing haven't changed a lot.
http://nileshhirapra.blogspot.no/2012/02/aspnet-mvc-pluggable-application.html
Update: you do not actually need to set up the project in the Areas folder, but you need to copy all content like views and scripts/css into there before being able to use it in the main application.
If you want these sites to actually be separate websites but only look similar, then that is what you'd need to set up. You'd probably want to decide on a single-sign-on scheme for that.

ASP.NET MVC 3 Structure - Go to view in another project

I've got the following project setup
Project A (main)
Business
Data
View (asp.net mvc 3 project)
Project N
Business
Data
View (asp.net mvc 3 project)
How can I call from Project A the View in Project N and from N back to A. Essentially what I'm trying to do is package each Project N to have its own individual MVC as it comes from different sources and plug it in to the main project and then just have it navigate to the correct view.
Can this be done? Or is there a better way to do this?
You could write a custom virtual path provider. Here's a nice blog post which shows an example of such a virtual path provider allowing you to embed Razor views into assemblies as resources and reusing them in multiple applications.
Unfortunately without a custom virtual path provider, you cannot cross reference views between multiple ASP.NET MVC applications. This simply is not allowed by the default provider which looks for views only inside the current application.
I do sugest another approach if possible. if I understood correctly, those projects are somehow ike plugins but they are not standalone applications.Also they now about each others so they are coupled. It's, let's say tricky, but I would use only 1 asp.net mvc project (the web ui). All the UI bits which belong to other projects I'd make them helpers (pretty much widgets). This means, that each project contains only the helpers which will be used to construct a view.
I think it's a bit of an architectural problem if you only want to keep the views in each project just for the sake of hosting them in a different assembly. Going the widgets' way it might seem mkore work, but I think you gain the most control and the separation level you want. The only thing is you don't have full Views defined, but why you would want to have full Views (partials, layouts) in separate places if they will be used in one place only?!
Now, if each project is indeed a plugin, independent of other plugins, then going with compiled views is the best way. But if Project B knows about the view of Project N, then I think the above solution is more suitable. That or the whole app is too over engineered. Separation is good when it doesn't create a whole new jungle to navigate it.

Changing ASP.NET MVC default folder structure

Is it possible to change around the folder organization to the following and still have MVC work.
P1
Controllers
Models
Views
P2
Controllers
Models
Views
etc..
This looks a lot like the new feature area's which is available in MVC 2 though it is currently in preview and will be release with VS 2010.
If you want to do it yourself without using areas then check out this article on view engines
as said before, the Areas feature is what you are looking for.
If you are using vs2010, then although you have MVC2, you don't have the tools for creating the areas - these are only available on vs 2008, when you install the MVC2 rc
to make it happen follow the instructions at the following link: http://msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx
as you can see the menu options are missing so:
download the example project from there.
build the directory structure at your solution according to the example
change the AreaRegistration.cs to match your area name
add AreaRegistration.RegisterAllAreas(); at the RegisterRoutes function at the global.asax, right after the IgnoreRoute
NOTE: the namespaces shuold contain .Areas.
for More explanations search at stackoverflow for asp-net-mvc-2-beta-single-project-area-registration-getting-http-404 (since this is the first time i post an answer - SO doesn't let me append more then 1 link, go fugure..)
Hope this helps
Should be doable, I think the default folder structure is just a suggestion. I've seen before in some documentation that larger projects would likely be split up differently, possibly even among multiple assemblies.
The only thing I would think would cause some trouble would be the views. Since controller actions are mapped to them only by file name. I know there's some way to change them, but I have not had to do so yet.
You can create your own viewengine to solve the paths. That sounds like a very strange idea, but the ViewEngine class is actually responsible for 2 things: locating a view and rendering a view to the httpresponse. The thing you have to change is the locating part, you can just inherit the default aspxviewengine and change the view locating part.

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

ASP.NET MVC RC - Creating a MVC User Control with a codebehind

Trying to create a MVC User Control in the Release Candidate and I can't see to make one with a codebehind file. The same is true for MVC View pages.
Creating Views in the Beta would produce codebehinds...am I missing something?
Code behind kind of defeats the purpose of the MVC Framework. Functionality should be kept separate from the view, the MVC team felt that code behind pages went against this ideology and therefore removed them.
Your can create a custom helper method to create your control. Also I'm not sure if MVC has view components (Monorail/Castle) but that could be an option as well.
From ScottGu's Blog post:
*Views without Code-Behind Files
Based on feedback we’ve changed view-templates to not have a code-behind file by default. This change helps reinforce the purpose of views in a MVC application (which are intended to be purely about rendering and to not contain any non-rendering related code), and for most people eliminates unused files in the project.
The RC build now adds C# and VB syntax support for inheriting view templates from base classes that use generics. For example, below we are using this with the Edit.aspx view template – whose “inherits” attribute derives from the ViewPage type:
One nice benefit of not using a code-behind file is that you'll now get immediate intellisense within view template files when you add them to the project. With previous builds you had to do a build/compile immediately after creating a view in order to get code intellisense within it. The RC makes the workflow of adding and immediately editing a view compile-free and much more seamless.
Important: If you are upgrading a ASP.NET MVC project that was created with an earlier build make sure to follow the steps in the release notes – the web.config file under the \Views directory needs to be updated with some settings in order for the above generics based syntax to work.*
I answered this question here:
How to add a Code-behind page to a Partial View
Seems this wasn't particularly tricky, and is quite do-able
This answer worked for a Partial 'ViewUserControl' but the same should apply
Ok.
First: Add a Class file with the convention of .cs (i.e. view.ascx.cs)
Second: Add "using System.Web.Mvc;" to the class
Third: Change the Class to Inherit from "ViewUserControl<>"
Fourth: Add the following to the View's header:
CodeBehind="View.ascx.cs" Inherits="Project.Views.Shared.View"
Fifthly: Copy the files out of the solution and drag back in to reassociate the two together
Note: For this to work with a Normal MVC View you just need to inherit the class from "ViewPage"
The whole idea for ASP.Net-mvc was to get rid of the codebehind files...thats why asp web controls didnt matter that most didn't work.But with the changes of getting rid of the code behind comes with a different programming style..The idea is codebehind files are EVIL:
http://stevesmithblog.com/blog/codebehind-files-in-asp-net-mvc-are-evil/
the whole idea is to make sure people remember they are using asp.Net-mvc and not asp.et web pages. take alook at this link ,it explains it a little better:
http://blog.lozanotek.com/archive/2008/10/20/Visual_Studio_Templates_for_MVC_Views_without_Codebehind_Files.aspx
I think this tutorial is what you are asking.. but not really sure what you want..

Resources