ASP.NET MVC, plugin architecture and identity collisions

So, I drew lyrics about ASP.NET MVC to a friend who is about to start developing a new user interface ....

He asked me if you can solve the following problem with ASP.NET MVC:

Introduce a web application that supports plugins. In the current ASP.NET WebForms application, the pluggin developer provides user control and some jQuery. The identifiers of the controls are unique, so that jQuery can always select the right DOM elements and so that the code behind can process the correct control collections.

I suggested that in MVC, since we can have any number of forms ... each plugin can be implemented as a partialView.

Each partialView will be wrapped in its own form, therefore the corresponding action of the Controller and, therefore, will receive only the form data defined in partialView, therefore from this point of view we do not care about DOM id collisions.

However, the HTML code would be invalid if there was a collision with an identifier, and therefore the jQuery written by the plugin developer could work!

I'm not sure how to get around this ...

I don’t like the idea of ​​parsing partialView for collisions when adding a plugin, and I don’t like the idea of ​​restricting identifiers that the plugin developer has access to.

Maybe identifiers can be prefixed with runtime, and model bindings can be prefixed?

+4
source share
1 answer

You can simply wrap the contents of the plugin in a DIV or FORM element and specify a unique identifier on the page. Then just use jQuery only to select the elements that are inside this "parent" DIV or FORM element.

You may have generated a GUID to use as a unique identifier at runtime, but it will take some work by the person who wrote the plugin. Although perhaps you could create one to automatically generate the “parent” DIV and ID, then you could just access the ID in the view as a plugin property.

Just some thoughts, I haven't built an ASP.NET MVC system with plugins yet, but that doesn't seem too complicated.

Here is an example of a PartialView that uses its own ViewUserControl class:

ViewUserControl1.ascx:

<%@ Control Language="C#" Inherits="MvcPluginPartialView.PluginViewUserControl" %> <input class="txtText" type="text" value="<%=this.ID %>" /> <input class="txtButton" type="button" value="Show Alert" /> <script type="text/javascript"> jQuery(function() { // This is the Unique ID of this Plugin on the Page var pluginID = "<%=this.ID %>"; // Attach the OnClick event of the Button $("#" + pluginID + " .txtButton").click(function() { // Display the content of the TextBox in an Alert dialog. alert($("#" + pluginID + " .txtText").val()); }); }); </script> 

MvcPluginPartialView.PluginViewUserControl:

 namespace MvcPluginPartialView { public class PluginViewUserControl : ViewUserControl { public PluginViewUserControl() { this.ID = "p" + Guid.NewGuid().ToString().Replace("-", ""); } public override void RenderView(ViewContext viewContext) { viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now); ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this); //this.ID = Guid.NewGuid().ToString(); RenderViewAndRestoreContentType(containerPage, viewContext); } internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) { string contentType = viewContext.HttpContext.Response.ContentType; containerPage.RenderView(viewContext); viewContext.HttpContext.Response.ContentType = contentType; } private sealed class ViewUserControlContainerPage : ViewPage { public ViewUserControlContainerPage(ViewUserControl userControl) { this.Controls.Add(userControl); } protected override void Render(System.Web.UI.HtmlTextWriter writer) { writer.Write("<div id='" + this.Controls[0].ID + "'>"); base.Render(writer); writer.Write("</div>"); } } } } 

Then, to place the view on the page, you can use the "Html.RenderPartial" method, as usual, plus you can place as many on them as you want, and they will all work as expected.

 <%Html.RenderPartial("ViewUserControl1"); %> <%Html.RenderPartial("ViewUserControl1"); %> <%Html.RenderPartial("ViewUserControl1"); %> 
+2
source

Source: https://habr.com/ru/post/1286303/


All Articles