Having multiple mvc widgets in one page - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Having multiple mvc widgets in one page

  • Having multiple mvc widgets in one page
  • Hi. I have several pages that needs to have 2 mvc widgets. When one of the page gets reference with a subpage, the mvc controller calls the action method name that matches the subpage. (for example: with url path - "home/default", controller "home" will call action method "default". The problem is with having another widget that is shared across pages since the other widget needs to have all the action method that the per page widget has in order to be accessed in all subpages. Can I assign the default controller action method ("Index") to be called always regardless of the subpage? What would be the best way to handle a single action method that will be called always regardless of the subpage? Is it also possible to create dynamic action method by over writing the controller factory? 
  • 3840be21-c3e8-4b81-a0d6-07248b9e7b3c_MvcExtended.rar
    Hi Andrew,

    Unfortunately, this cannot be done so simple, because by design every MVC control tries to resolve the url of the page where it stands. Because of this when you do not have an action with the name of the your page specific  control, the shared one does not render at all. 

    However, there is something you can do for your Shared control. You can change its type from type="Telerik.Sitefinity.Mvc.Proxy.MvcControllerProxy" to a custom one - type="SitefinityWebApp.MvcExtended.CustomMvcControllerProxy", that inherits MvcProxyBase.  

    In the toolbox config you can change the type of the control like this: 

    <add enabled="True" title="MvcWidgets" name="MvcWidgets">
                            <add enabled="True" type="SitefinityWebApp.MvcExtended.CustomMvcControllerProxy" controllerType="SitefinityWebApp.Mvc.Controllers.MySharedWidgetController"title="MySharedWidget"ControllerName="SitefinityWebApp.Mvc.Controllers.MySharedWidgetController"visibilityMode="None" name="MySharedWidget" />

    In the OnPreRender method of the MvcControllerProxy,  ExecuteController is called which gets the action that needs to be executed and executes it like this: 

    string actionName = this.Controller.RouteData.GetRequiredString("action");
    this.Controller.ActionInvoker.InvokeAction(this.Controller.ControllerContext, actionName)

    If the action is not executed this method returns false, and you can then execute the "Index" action.
    Please check the attached code of CustomMvcControllerProxy. 

    Note: two of the properties that are commented this.PageDescription and this.PageKeywords are internal and cannot be set. They are used for setting page description and page keyword from the controller to the page when working in Pure MVC mode. If you use this approach please consider this in mind. 
    ("The description of the page is set by setting the Description property of the ViewBag in the controller" and "The keywords of the page are set by setting the Keywords property of the ViewBag in the controller")

    Kristian Smilenov
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • I have this exact problem but your solution does not work for me.

    I then made my own class that pretty much is just your CustomMvcControllerProxy so I could set breakpoints but there were 2 issues:

    1. I can't resolve SitefinityActionInvoker. It looks like it's in the Telerik.Sitefinity.Mvc namespace but I can't see it there

    2. I just commented it out so I could at least step through and see how the method is working, but after assigning that class to my Mvc control, the breakpoints do not get hit at all.

    This really is a major problem that I MUST solve for the project I'm working on. All of my widgets are built with MVC and to think that because some pages needs a url name in the last segment will break the rest of the widgets on the page.....it's very concerning. If this solution of yours worked I figured I could just make different proxies for different widgets and handle the default actions, but I can't even get your initial one to work. Please help

  • I've got it using my proxy controllers, can you please tell me where I can reference SitefinityActionInvoker or give  me the class itself so I can use it?

  • Please.....anyone? I just need to resolve that one class so I can test this

  • Hi Ryan,

    If you are using Sitefinity 6.3 and above, you will not be able to resolve SitefinityActionInvoker. What I can suggest is to override the HandleUnknownAction() method in your controller as shown below:

    public class MyMVCWidgetController : Controller
            protected override void HandleUnknownAction(string actionName)
                this.ActionInvoker.InvokeAction(this.ControllerContext, "Index");

    This way when the action does not exists, the controller will call the HandleUnknownAction() method. In this method you can call another action or implement your own logic. here is also a short video for your reference.

    I hope this information helps.

    Sabrie Nedzhip
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
  • Something else that I noticed for anyone that may have this issue, and it regards using this in a regular MVC application as well:

    I usually use my actions with return View(model) and let MVC choose my view from my views folder, but using this, you need to specify the view name  ie. return View("Index", model) or else the action will try to look for the view using the previous incorrect route as the view name

  • Thank you very much. That did the trick.

     I suppose I could have just implemented that myself but I was under the impression you needed to run it through the custom Sitefinity Invoker. Glad to see it's just using the built in MVC handling and one less dependency.

     Thanks again