Ghost of Dead Sitefinity MVC Widget Controller Haunts Me - asp.net-mvc-3

We've recently adopted Sitefinity and have begun creating MVC widgets. Overall this has been working as advertised. Then, after having tested my new widget, I realized I named it wrong! I then changed my controller name from MyWidgletController to MyWidgetController. After making the change I began getting the exception "The controller with the name 'MySitefinityApp.Mvc.Controllers.MyWidgletController' cannot be resolved". Scratch my head. Build...again. Still same problem. Recycle App-Pool. Same problem.
Here is the controller I'm working with (Names have been changed to protect the identity of the widgets involved):
[ControllerToolboxItem(Name = "MyWidget", Title = "My Widget", SectionName = "My Custom Widget Section")]
public class MyWidgetController : Controller
{
public ActionResult Index()
{
return View("Default");
}
}
Question: Why is Sitefinity still looking for MyWidgletController when it no longer exists?

It turns our that Sitefinity persists the name of the controller to its DB. If you run into this problem you can find your undead controller here:
select top 10 * from sf_control_properties where name = 'ControllerName'
Ugh. This is horrific. Sitefinity, you should be ashamed.

LOL, I have been the same situation where i created custom widget with mvc.
another workaround is Goto >> /Sitefinity/Administration/Settings/Advanced
Then Below ToolBoxes>>PageControls>>Sections you will find out your Modules, then delete necessary dead widgets

Related

ASP.NET Core populate model only once for all views

I'm new with ASP.Net Core (3.0 in this case) and I´m trying to create a menu that is visible on all views of a WebApplication, is created dynamically and must be populated only once. Below i explain the steps and try outs i did to reach the goal needed (if required i can share the code I'm using).
This is what i did:
In a simple way, using the "_Layout.cshtml" page, i created a static HTML menu and made all other views simply inherit that layout. So far, so good;
Next challenge comes from the fact that the menu items are dynamically created after a User has logged-in, which i managed to overcome by setting a ModelView inside a controller (HomeController.cs with Index action in this case), and then delivering it to the view. For this case works OK, because the default page is ~\Home\Index\, problem is when i change to a different view with a different controller, the menu has to be rendered again, and so i have to replicate the code (a problem dealt create a BaseController and BaseModel based on this post along side the OnActionExecuted to host the menu generating code)
Now, the biggest problem is the fact that i can only populate the menu once, after the user logs-in. Each time there is a redirect between different controllers/views (post-back of same controller/view works fine), the model is null inside the OnActionExecuted, I tried using ViewData, ViewBag, TemData, but all are null.
So, my question is, how to keep that specific data alive and shared, basically across all the views, and only gets populated once (after each user login) between redirects from different views?
I have been reading around and found several solutions besides the one i did, but i did not found any that could keep data alive throughout the user session the way I need:
ViewBag, ViewData and TempData
Can the shared layout view have a controller in ASP.NET MVC?
Pass data to layout that are common to all pages
To sum up, my flow at this moment, is like this:
User Logged-in
Redirect to default: ~\Home\Index
MenuModelView.cs for the menu gets built and HomeController.cs returns to Index.cshtml with the model attached to it.
Index.cshtml receives the populated ModelView and it uses _Layout.cshtml
The _Layout.cshtml builds the HTML tags for the menu based on the MenuModelView.cs data
User navigates to a different view and steps 3 to 5 are repeated from a specific controller/view
If you want to create a control that can be accessible in all pages without changing every controller, I strongly suggest creating a view component. For a view component has no relationship with your controller, but can access dependencies like database and full HTTP context.
For example, you want to build a custom nav menu, you can just create a view component named NavHeader
using Microsoft.AspNetCore.Mvc;
namespace YourProject.Views.Shared.Components.NavHeader
{
public class NavHeader : ViewComponent
{
public NavHeader(YourDbContext context)
{
// you can access your dependencies, like database.
}
public IViewComponentResult Invoke()
{
// your own logic. You can access HTTPContext here.
var model = new YourOwnModel();
return View(model);
}
}
}
And just call it in any view or layout.
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
#*Render your component like this*#
<vc:nav-header></vc:nav-header>
</body>
For more details about view component, please reference:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1
https://anduin.aiursoft.com/post/2020/1/4/share-view-component-between-different-aspnet-core-web-project

matrix component association issue

Background:
I have a running magnto application. I have created a new module inside app/code/locale. Inside this folder I have controller called SyncController.
Inside this controller I am calling a method in model Like below;
<?php
class Connect_SyncController extends Mage_Core_Controller_Front_Action {
function IndexAction() {
}
function ProductAction() {
Mage::getModel('connect/product')->sync();
}
}
?>
Product action in model receives a json input and the json input will contain matrix item and matrix component item.
Problem:
So for it was working fine. Whenever I sent matrix item and component items, those all were added and associated properly. Suddenly there is an problem in associating components to its matrix item. Matrix items and components are being saved successfully no issues with that. But, components are not associating to its parent. Even there is no error throwing. Surprise is, once in a while it works.
I referred below suggestion also;
Cannot associate Simple Products in a Configurable
But there is no up gradation or change in configuration exists in recent past.
Can anyone suggest what may be the issue?
Try to increase max_input_time from php.ini. And restart the apache server.

How does ASP.NET MVC arbitrate between two identically named views (aspx and razor)?

Using ASP.NET MVC3 I created a new Razor view and gave it the same name as the existing .aspx view that I had been using. I noticed that controller continued to pick up the .aspx view (which has the same name as the action) which is pretty much what I expected. I then renamed the .aspx view and action picked up the razor .cshtml view.
So if I have two views called myview.aspx and myview.cshtml and an Action called MyView() that does a return View(), it will pick up the myview.aspx view and return that.
How does MVC3 decided which view-type to default to?
Is there a way to change this default behavior to prefer a razor view over an .aspx view?
Everything stems down to the order of view engines in the ViewEngines.Engines collection. Here's how the ViewEngines static constructor looks like (as seen with Reflector in ASP.NET MVC 3 RTM):
static ViewEngines()
{
ViewEngineCollection engines = new ViewEngineCollection();
engines.Add(new WebFormViewEngine());
engines.Add(new RazorViewEngine());
_engines = engines;
}
which explains why WebForms is the preferred view engine.
So you could perform the following grotesque hack in Application_Start to inverse the preference towards Razor :-)
var aspxVe = ViewEngines.Engines[0];
var razorVe = ViewEngines.Engines[1];
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(razorVe);
ViewEngines.Engines.Add(aspxVe);
I would imagine its down to the order in which view engines are registered. Earlier registered view engines will be queried first. If you want to change the order:
ViewEngines.Engines.Insert(0, ...);

Eclipse RCP: How can I update a view when the selected editor changes?

This should be quite a common problem, but I couldn't find anything helpful on the topic.
We are developing an application with Eclipse RCP. The application shows data in an editor of which usually multiple instances are open. In an additional view you can edit the editor-values. When the values are changed in the view they are updated in the editor and it's dirty flag is set.
So far it works fine. What we're missing is: When another editor instance gets the focus, our view should show the data of this editor.
I managed to do that for two views. The second view is sucessfully updated using a TableViewer as selection Provider and registering a SelectionListener in the other view. I tried the same thing for the editor using a Viewer I subclassed from ContentViewer, but it didn't work.
Can this approach be working?
Or do I need a different approach on the problem?
May be you can subclass your view from PageBookView and then provide special adapter for your editor. Outline View is implemented using this approach.
Thank you cerealk, that was exactly what I needed. :-)
Update the View when another Editor is selected
public class myView {
// Create an IPartListener2
IPartListener2 pl = new IPartListener2() {
// If the Editor I'm interested in was updated ...
public void partActivated(IWorkbenchPartReference ref) {
IWorkbenchPart part = ref.getPart(true);
if (part instanceof DetailEditor) {
// ... update the view
Contact contactFromSelectedEditor = ((DetailEditor) part).detailComposite.contact;
detailComposite.update(contactFromSelectedEditor);
}
}
...
}
// Add the IPartListener2 to the page
IWorkbenchPage page = this.getSite().getPage();
page.addPartListener(pl);
}
Why use an IPartListener2 instead of an IPartListener
The IPartListener2 replaces IPartListener with 3.5.
As explained in this this answer:
You should always use IPartListener2 as it can handle part-change events on parts that have not yet been
created because they are hidden in a stack behind another part.
This
listener will also tell you when a part is made visible or hidden or
when an editor's input is changed.

MVC using ASP.NET webforms

I've inherited an ASP.NET application built on top of webforms, and the application suffers from having all of its business logic embedded in the codebehind. As a result, this application can't be unit tested.
I want to break out the functionality of every form into an MVC style, but I've found that ASP.NET resists every effort on my part to refactor it. In general, I like to seperate my MVC classes as follows:
public class LoginModel
{
public string Username, Password;
public bool IsAuthenticated;
}
public interface ILoginView
{
event Action UserLoggedIn;
void SetMode(bool isAuthenticated);
}
public class LoginController
{
ILoginView View;
LoginModel Model;
public LoginController(ILoginView view, LoginModel model)
{
this.View = view;
this.Model = model;
// hook onto view events
}
}
Once I've got my classes set up and nicely unit tested, I can implement the ILoginView interface on my usercontrol or page:
public class LoginView : UserControl, ILoginView
{
public LoginView() : base()
{
new LoginController(this); // registers view with the controller
}
}
If this were a winform application, it would work beautifullly. But the ASP.NET lifecycle causes this style to break down.
ASP.NET creates and destroys the view on every page load. Since my Controller is held by the View, the Model is held by the Controller, every postback causes my page to lose its state.
I can remedy the problem above by holding my Controller in the users session, but that introduces a world of problems. In particular, putting Controllers in the session causes memory issues because Models and Controllersaren't reclaimed by garbage collection until the session expires. Navigating from page to page creates dozens of controllers, but the controllers don't dispose of themselves when the user navigates away from a page.
Since a view is destroyed/recreated on every postback, then I have to re-register the view with the controller on every postback. This is harder to do than it sounds, because the state of the Model needs to be copied back to the View on every postback, but simultaneously we don't want to overwrite a users changes to the View which were made in the previous postback. You have no idea what kind of additional nightmare this turns into when dealing with dynamically created or AJAXed controls using this MVC style.
I know I'm overthinking this and there is an easier way to get the results I want, but how do I implement an MVC style properly using webforms?
Is it not easier to re-write this using asp.net mvc?
As it seems you'll have to re-write. Either completely to MVC (and stop using DNN), or to a better WebForms implementation (meaning, separate logic from display and take into account the page life-cycle issues). There's a third option - combining MVC and ASP.NET WebForms, but you should look at it carefully taking into account all the variables in your platform.
Well the nature of the POSTback is dictating your state changes, so you should react on that. Any framework you use would work pretty much the same way, it'll rebuild/bind the state with each request. You should look into savind the state (read data) into your user's session.
ViewState should be used to store all the loaded data in WebForms, so the Controller would be instancied only when the page is created, eliminating the need to store any object in the user session.

Resources