This is experimental but maybe some devs are willing too look into this.
This is experimental but maybe some devs are willing too look into this.
Hi Remi,
I have a working solution. I like your idea of tapping into Dynamicweb.Notifications.Standard.Application.Start, but by then the URL has already been mapped, so you'll need to tap in earlier. I'll make a disclaimer that 'this works on my machine' which doesn't promise it will work in every situation. From what I can tell, it should work for you.
At a high level, the solution is to override global.asax and add the MVC routes. Then in Application_AuthenticateRequest only call the Dynamicweb AuthenticateRequest for URLs that aren't handled by MVC.
To override global.asax first download the Visual Studio templates.
Info: http://developer.dynamicweb-cms.com/documentation/for-developers/visual-studio-templates.aspx
Download: http://developer.dynamicweb-cms.com/documentation/for-developers.aspx
Create a new Visual Studio project with File | New Project, and select Dynamicweb Custom Modules. This will create an example project, which you can delete most everything except for global.asax / global.asax.cs. Make sure that you have a reference to Dynamicweb.dll.
In global.asax.cs, add your MVC routes to Application_Start.
Then, still in global.asax.cs set Application_AuthenticateRequest to:
public void Application_AuthenticateRequest(object sender, EventArgs e) { //exclude all paths already entered by RouteTable.Routes (except the catchall) var httpContextBase = new HttpContextWrapper(HttpContext.Current); foreach (var routeBase in RouteTable.Routes) { var routeData = routeBase.GetRouteData(httpContextBase); if ((routeData != null) && ((Route)(routeData.Route)).Url != "{*catchall}") { //exit and don't load Dynamicweb functionality for this page return; } } Dynamicweb.Frontend.GlobalAsaxHandler.Application_AuthenticateRequest(sender, e); }
What this will do is check for the routes that you created and exit Application_AuthenticateRequest early if the route is already created. That prevents it from being handled by Dynamicweb. This provided a DRY solution so that you only need to create the MVC routes once, and it will work for you.
Note that in your example you called the route name "Default". That may clash with other routes so just make sure that you have a unique name.
Also, styles, scripts and other dependencies need to be handled the same way. If you want them handled by Dynamicweb then don't create a route. If you want them handled by MVC then create a route for them. You can also call other MVC features like BundleConfig.RegisterBundles if you so desire.
Once you have this created, copy over your new compiled DLL to the Dynamicweb's /bin folder, and replace global.asax with your new global.asax file.
Here's an example of the global.asax.cs file that I used:
using System; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace TestMvcApplication1 { public class TestMvcApplication : System.Web.HttpApplication { public void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapRoute( name: "Default", url: "CustomModules/mvcapp1/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); RouteTable.Routes.MapRoute( name: "OtherTestPage", url: "othertestpage", defaults: new { controller = "Home", action = "OtherTestPage" } ); // Fires when the application is started Dynamicweb.Frontend.GlobalAsaxHandler.Application_Start(sender, e); } public void Session_Start(object sender, EventArgs e) { // Fires when the session is started Dynamicweb.Frontend.GlobalAsaxHandler.Session_Start(sender, e); } public void Application_BeginRequest(object sender, EventArgs e) { // Fires at the beginning of each request //GlobalAsax.Application_BeginRequest(sender, e); } public void Application_AuthenticateRequest(object sender, EventArgs e) { //exclude all paths already entered by RouteTable.Routes (except the catchall) var httpContextBase = new HttpContextWrapper(HttpContext.Current); foreach (var routeBase in RouteTable.Routes) { var routeData = routeBase.GetRouteData(httpContextBase); if ((routeData != null) && ((Route)(routeData.Route)).Url != "{*catchall}") { //exit and don't load Dynamicweb functionality for this page return; } } Dynamicweb.Frontend.GlobalAsaxHandler.Application_AuthenticateRequest(sender, e); } public void Application_Error(object sender, EventArgs e) { // Fires when an error occurs Dynamicweb.Frontend.GlobalAsaxHandler.Application_Error(sender, e); } public void Session_End(object sender, EventArgs e) { // Fires when the session ends Dynamicweb.Frontend.GlobalAsaxHandler.Session_End(sender, e); } public void Application_End(object sender, EventArgs e) { // Fires when the application ends Dynamicweb.Frontend.GlobalAsaxHandler.Application_End(sender, e); } public void Application_OnPreRequestHandlerExecute(object sender, EventArgs e) { //Dynamicweb.Frontend.GlobalAsaxHandler.Application_OnPreRequestHandlerExecute(sender, e); } } }
Hi Remi,
Have you had a chance to try this yet? I'm curious to know how it worked for you.
Scott
I have a working prototype. The dw application needs some references to mvc and the web config needs some additions for mvc etc.
I tried using the filemanager control and binding it to a model property. I can load the control but i could not set the value. I think i need to make my own filemanager control.
I have updated the global asax code. The version above disabled dw authentication completely.
See the code:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.SessionState; using System.Web.Routing; using System.Web.Mvc; namespace dwMVCRoutes { public class Global : System.Web.HttpApplication { public void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapRoute( name: "mvcapp1", url: "CustomModules/mvcapp1/{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); /* RouteTable.Routes.MapRoute( name: "OtherTestPage", url: "othertestpage", defaults: new { controller = "Home", action = "OtherTestPage" } ); */ // Fires when the application is started Dynamicweb.Frontend.GlobalAsaxHandler.Application_Start(sender, e); } public void Session_Start(object sender, EventArgs e) { // Fires when the session is started Dynamicweb.Frontend.GlobalAsaxHandler.Session_Start(sender, e); } public void Application_BeginRequest(object sender, EventArgs e) { // Fires at the beginning of each request //GlobalAsax.Application_BeginRequest(sender, e); Dynamicweb.Frontend.GlobalAsaxHandler.Application_BeginRequest(sender, e); } public void Application_AuthenticateRequest(object sender, EventArgs e) { if (IsMvcRequest()) return; Dynamicweb.Frontend.GlobalAsaxHandler.Application_AuthenticateRequest(sender, e); } private static bool IsMvcRequest() { //exclude all paths already entered by RouteTable.Routes (except the catchall) var httpContextBase = new HttpContextWrapper(HttpContext.Current); foreach (var routeBase in RouteTable.Routes) { var routeData = routeBase.GetRouteData(httpContextBase); if ((routeData != null) && ((Route)(routeData.Route)).Url != "{*catchall}") { //exit and don't load Dynamicweb functionality for this page return true; } } return false; } public void Application_Error(object sender, EventArgs e) { // Fires when an error occurs Dynamicweb.Frontend.GlobalAsaxHandler.Application_Error(sender, e); } public void Session_End(object sender, EventArgs e) { // Fires when the session ends Dynamicweb.Frontend.GlobalAsaxHandler.Session_End(sender, e); } public void Application_End(object sender, EventArgs e) { // Fires when the application ends Dynamicweb.Frontend.GlobalAsaxHandler.Application_End(sender, e); } public void Application_OnPreRequestHandlerExecute(object sender, EventArgs e) { if (IsMvcRequest()) return; Dynamicweb.Frontend.GlobalAsaxHandler.Application_OnPreRequestHandlerExecute(sender, e); } } }
Also when using views i have to copy them into the dw application then it works.
The following code is called from a editor template. Can you pinpoint the problem of initializing the value on the Filemanager control?
see code:
public static class DynamicwebControls { public static HtmlString DwTestControl(string value) { var ctrl = new Dynamicweb.Controls.FileManager(); ctrl.ID = "txtDwFile"; StringWriter sw = new StringWriter(); var htmlwriter = new HtmlTextWriter(sw); ctrl.RenderControl(htmlwriter); ctrl.Value = value; ctrl.File = value; ctrl.Folder = "/Files/Images"; return new HtmlString(sw.ToString()); } }
Hi Remi
Interesting! Thanks for sharing, and please post if you find more interesting stuff.
BR Nicolai
Hi Remi,
Thanks for the update. I'll get an answer for you on this. I setup a repro so that I can see what you see and the control is loaded but it's disabled. Is that what you see too? I ran out of time though and now I'm travelling for two weeks. Are you ok if I get the answer when I get back or is it holding up a release?
Thanks,
Scott
Hi,
I can load the filemanager control and use the file selector. Only problem is binding a value from the model.
I have been very busy lately. So let's have a look at it when your back. No rush :)
Hi Remi,
That sounds good. I'll follow up when I get back.
Scott
Hi Remi,
I wanted to follow-up and say that I haven't forgotten about you and the MVC integration. I keep snoozing my reminder to get back to you due to not having enough time yet. It's going to take me a while to get the full testing environment setup where I can debug this and I haven't been able to do that yet, but I haven't forgotten.
Scott
Hi Scott, i have been snoozing the project as well. It is still on my radar.
We'll get it figured then. I worked for a while on it a ways back but I had something off in the merged winforms and MVC project and it didn't work, so I just need to start again. Once it's figured it should be an easy answer.
Hi Remi,
Is this still something that you are interested in? There is a lot of focus on MVC in future versions of Dynamicweb and there is some support today with some effort, but I apologize that I haven't sat down to provide you with an answer yet. Can you wait for the functionality to be a first-class citizen in Dynamicweb, or are you still working to accomplish this now?
Thanks,
Scott
I am still interested but is did not have my attention recently. Not sure if it will on the short term.
What are your plans regarding mvc for future versions 8.4, 8.5 etc?
Hi Remi,
I received your reply by email but the post is missing now so I'll reply to the ghost post. The details are being worked out, but I believe that you'll see exactly what you're looking for in the 8.4 (or maybe 8.5 but hopefully earlier) time frame. There's a lot of discussion and planning going on to make this as natural feeling and exciting for MVC developers as possible.
Scott
Thanks for answering. Good to hear there are developments towards mvc developers.
(The post was not missing by the way. It is on page 2 ;)
Hi Remi,
Indeed, here's the thread on page 2!
Scott
You must be logged in to post in the forum