ASP.NET MVC 3 Cannot find _viewstart.cshtml when using plugin/embedded views - asp.net-mvc-3

I'm trying out a plugin mechanism for ASP.NET MVC 3 (razor) using embedded views as described here, I changed the view engine to inherit from the RazorViewEngine, but otherwise didn't really change anything. Now I'm calling a controller action in the plugin assembly, which renders a view, this works ok. But the view cannot find the _viewstart.cshtml, and thus no layout. Ideally I'd like to let the host application define the viewstart and layout. Possibly I shouldn't directly call a plugin controller action though, but rather only render partials from the plugin and let the host application handle the main controllers/views.
These are the viewstart locations that are tried in my own VirtualPathProvider:
"~/Plugins/MyMvcApplication.dll/_ViewStart.cshtml"
"~/Plugins/MyMvcApplication.dll/_ViewStart.vbhtml"
"~/Plugins/_ViewStart.cshtml"
"~/Plugins/_ViewStart.vbhtml"
"~/_ViewStart.cshtml"
"~/_ViewStart.vbhtml"
I'm also considering just forgetting about embedding views as it seems a bit fiddly, so I might just opt for copying views to the host application, which could make debugging easier for future users. The risk is that the users will make changes to these views, making updates of the plugin harder. One of the reasons I have doubts about the plugin mechanism is because of possible performance implications, though I haven't done any measurements yet.

Related

Angularjs and MDI SPA application with many tabs

We have to implement multiple-document-interface web application. Each document has to live in a separate tab (but on the same page, it has to be SPA). There may be up to 50 opened tabs simultaneously and application should give ability to group tab panes by modules.
One of our options were to use AngularJS for this task. We like the way Angular handles partial views, structures application by using modules/controllers and performs dependency injection.
After digging in for couple of days, we've figured out that there may be some problems with the way bindings work: there is no easy way to prevent angular from watching tabs, which contents are not currently displayed to the user. You can imagine situation when user will have around 20 opened tabs and this whole thing becomes slow as hell! Also our application is very grid-heavy, so for grids I think we should avoid ng bindings at all.
We were thinking about ng-view and the way it recreates DOM on each activation ... this looks overkill and will force us to put all UI state into the view-models, even for scroll-bars :)
Can you suggest some possible ways to improve performance with Angular and MDI? Maybe we should even consider using some other ui-framework/set of tools to achieve same results?
What's important:
modularity (AMD)
dependency injection
declarative bindings (we do like how angular and knockout solved those problems)
MVVM/MVC
ability to create multiple instances of the same controller (open multiple "details" tabs for each specific item from the grid, for example)
modularity - Angular has it's own modularity rules/patterns which are good if you want to conform to them, but if you want to make something modular in a different way, eg... allow forms to be self contained so that multiple instances of them can dynamically be opened concurrently it's quite difficult
dependency injection - Angular allows you to write code that you can inject other into, but you cannot inject Angular, it seems an oversight that you cannot test your code isolated from Angulars?
declarative bindings - yep, the way Angular binds literals within HTML with the JS code makes it really hard to create MDIs with multiple concurrent instances of a single form. You really need to dynamically create your form instances with their own identifiers (in addition to Angulars) then scope your own identifiers within the bounds of a shared set of JS files (which is what you want), however then Angular's binding will get in the way of each instance if you continue to use Angular's bindings - alternatively you can try modify the HTML dynamically get Angular to refresh it's bindings.
Basically anything to do with MDI is harder than it needs to be with Angular and it's worth looking at alternatives for such projects before hand.
AngularJS can indeed be heavy on a big application, but only when you make a change inside the $scope. The bigger part of this time is spent looking for modification by dirty checking.
If you keep an AngularJS application inside a non active tab, a dirty checking can only happen after a outside event (like a WebSocket message). You can optimize your application to remove those listener when the tab is not focused.
If you follow the best practice of AngularJS, performance issues with a lot of pages opened should not be a problem. The bigger performance problem of AngularJS come with very big amount of data inside its $scope, but there is a lot of solutions proposed all over the internet.

what is the correct approach in order to host / integrate / show my existing MVC3 project inside orchard?

I've an existing MVC3 project that implements a certain functionality, this project has it's own views, and a separate Database.
now I'm required to use the same functionality inside one of my orchard project,so I thought that I can host this solution in somewhere and view it inside an iframe or something.
Am I thinking right?,
is this the correct step to take in order to achieve this requirement inside Orchard?
to make it more clear, all I need to do is to view this solution and interact with it's controls and views from a hosting page inside orchard, and the subsequent requests should be handled by my solution in order to hit it's own data store and get back with the requested data in order to be displayed to the user.
any help would be appreciated.
Update:
thanks for Bertrand Le Roy for his answer, I can now view my solution inside my
orchard website.
I came in to one more HUGE problem, which is that my application can no longer connect to my external database.
I've a DB that is hosted in some where else, and I'm using EntityFramework to deal with it.
the problem is that if I put the connection string inside my module web.config, or main orchard web.config, I run into several types of errors like:
"System.Reflection.TargetException: Object does not match target type."
or
"System.Data.MetadataException: Unable to load the specified metadata resource."
My question is: How could I pass my connectionstring correctly to my solution, assuming that I'm using Entity framework as my ORM.
Many thanks.
You will need to put it into a module.
You will have to move route definitions to a Routes.cs file (look at any existing such file for examples).
You will also need, in order to access your data store, to opt out of the ambient Orchard transaction around the data access code (using (var scope = new TransactionScope(TransactionScopeOption.Suppress))).
If you are using dependency injection, you may have some work to move that to the Autofac-based way of doing things in Orchard.
If you want your work to appear seamlessly in the Orchard admin, you may want to decorate your admin controllers with the Admin attribute. If you want your front-end to use the current theme, you'll have to add Themed attributes and maybe refactor your views so that they only emit HTML for the content zone instead of for the whole page.
Add a manifest (module.txt) to your module folder and you should be good to go.

MVC modular GUI components

I am trying to find the way to build complex web pages with MVC3 and AJAX.
I would like to use components to achieve this.
Each component is consisted of it's own model, view and controller.
Multiple components are then placed on some complex view and should act together to
provide desired behaviors.
In some situations, when user performs some action (interaction) with one of the components,
I must update other portions of the page via AJAX.
Component on which action (interaction) occurred, in it's implementation, does not assume anything about view on which it will be used and what portions of the pages should be updated and how.
So when some interaction occurs in some component, I need a mechanism (outside component itself) which will handle this situation and update appropriate parts of the page.
How would you, generally, implement such mechanism?
I would use the Mediator Pattern, also sometimes mistakenly referred to as the manager pattern.
This class would mediate the communication of your components.

Is there a better way to implement forms than using RenderAction?

I am working on a .Net MVC2 project where I am trying to modularize functionality as much as possible. One aspect of this would be to place a form in a partial views which is then called using RenderAction. This is so that the form's GET, POST, validation and redirection can be handled independently of the parent view.
I have read blogs and forums etc that suggest that this is not ideal behaviour for MVC, however I cannot think of a way round it. The main issue I am having is redirecting from the rendered action and I understand why I cannot do this.
What I need to know is this: if I can't and shouldn't code my modules in this way, how should I code them so they are independent of the parent view?

Coldfusion, whats the advantage of front controller design over page controller?

I'm from a non-computing background and I'm struggling to getting my head around MVC design approaches and frameworks in general. I "get" code re-use, and separation of logic from display, and I "get" encapsulation and decoupling, but I don't get this.
At the moment I simply put everything in root, a separate subfolders for images, cfcs, and _includes, all database interaction via cfcs. I do all my processing at the top of the page, then a comment line then display/page layout below that.
Most of the frameworks I have looked at seem to favour a front controller, so my simplistic version of a top controller MVC design would be a subfolder for cfcs, controllers, and views and a big switch statement in index.cfm
<cfif not IsDefined("URL.event")>
<cflocation url="index.cfm?event=home" addtoken="No">
</cfif>
<cfswitch expression="#url.event#">
<cfcase value="home">
<cfinclude template="controllers/home.cfm"/>
<cfinclude template="views/home.cfm"/>
</cfcase>
<cfcase value="about">
<cfinclude template="controllers/about.cfm"/>
<cfinclude template="views/about.cfm"/>
</cfcase>
</cfswitch>
.. but what real advantage does that give me over a page controller design? Unless it's just the kind of sites I write, I always seem to find that the controller logic is specific to a view, its not like one controller could fit several views or several controllers could output to one view, so what would be the point of separating them?
The light hasn't come on for me yet, any pointers?
By "top" controller, I think you mean "front" controller, a single point of entry for requests into an application. As #bpanulla wrote, most ColdFusion frameworks use this design pattern. This becomes particularly interesting with URL rewriting, where it becomes easy to have search engine safe URLs by intercepting the a URL (e.g. domain.ext/i/am/friendly.ext) and routing it to some standard file such as index.cfm while making the requested URL a parameter (often as a request header). This also makes site redesigns where URLs change easier because it lends itself well to aliasing or redirects.
As far as controllers are concerned, they are usually tightly coupled to a particular URL or URL pattern. It's possible be more loosely coupled with controllers, but in practice I find that's an emergent property after multiple refactorings. What should be underlying the controller is one or more calls to a service layer that talks to the database, executes business process, creates stateful entities, etc... Then the controller receives the service layer's outputs and places them into whatever mechanism (e.g. an event object) is used to pass data to the view(s).
It's the service layer that's meant to be reusuable not the controllers. The controllers are merely an extension of whatever framework an application works within. The idea being that you should be able to switch frameworks with very little impact to the views and service layer. The piece that needs to be touched are the controllers.
So a given service object in a service layer should be able to service multiple controllers. For example, consider showing a logged in users' information as a widget on a site. There might be different pages served by different controllers, but each would call the same service object to get logged in user data that presumably might be given to the same view that renders the widget.
Update: Front Controller Advantages
Security: centralized authentication and authorization.
i18n & l10n: inject the right language pack into the request globally
Process Orchestration: think multi step checkout process for a shopping cart where you don't want the back and forward buttons to work - by routing everything through the front controller you're able to enforce what step (i.e. the state)
Logging & Tracking: easily add Google Analytics or other request tracking to a site by making the addition in just one place
Error Handling: centralized behavior
Now many of these items can also be done using <cferror> and Appplication.cfc, but I find it easier to have one centralized point.
Useful Links
http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
http://msdn.microsoft.com/en-us/library/ff648617.aspx
You actually implemented the crux of Fusebox (http://www.fusebox.org/) with what you wrote. There's nothing wrong with that, and most of the ColdFusion community used something similar to that for many years - Fusebox was the most-used CF framework (in my experience) until just a few years ago when ModelGlue, Mach-II and the other second generation CF frameworks came about.
One thing I can point out is that your approach to controllers (as .cfm files) actually does not enforce encapsulation in the typical OOD fashion, with specific arguments going to an object method call. Unless you are extremely dilligent, over time your .cfm controllers may wind up accumulated a large number of undocumented parameters that alter behavior to solve one problem or another.
With the various frameworks you also get nice features like Application, Session, and Request specific code (onApplicationStart, onRequestEnd, etc). But you can always get those through a simple Application.cfc.

Resources