1 / 39

Umzug ASP.NET- WebForms -Elemente in MVC weiterverwenden

Umzug ASP.NET- WebForms -Elemente in MVC weiterverwenden. Dr. Malte Clasen adesso AG. Über uns. Malte Clasen Softwareentwickler http://malteclasen.de adesso AG IT-Dienstleister http://adesso.de. Rezeptefuchs.de. Rezeptefuchs.de. Gegeben: WebForms -Anwendung. Controls (Code)

Download Presentation

Umzug ASP.NET- WebForms -Elemente in MVC weiterverwenden

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. UmzugASP.NET-WebForms-Elemente in MVC weiterverwenden Dr. Malte Clasen adesso AG

  2. Über uns • Malte ClasenSoftwareentwicklerhttp://malteclasen.de • adesso AGIT-Dienstleisterhttp://adesso.de

  3. Rezeptefuchs.de

  4. Rezeptefuchs.de

  5. Gegeben: WebForms-Anwendung • Controls (Code) • Controls (ASCX) • Pages (ASPX)

  6. LifecycleWebForms / MVC

  7. WebForms in MVC einbetten • Lifecycle von WebForms und MVC praktisch nicht vereinbar • Komplexität in WebForms-Anwendungen in Controls gebündelt • Controls in MVC einbetten • sinnvoll für Elemente, die für sich stehen können • ungeeignet bei Interaktion mit dem Rest der Seite

  8. Ansatz • Eingabe: HttpRequest • Ausgabe: HttpResponse • WebForms-Aufruf simulieren • HttpRequest direkt übergeben, wird nicht verändert • HttpResponse neu erstellen und die erzeugte Ausgabe in die MVC-Ausgabe integrieren

  9. Vereinfachungen • nur ein Control pro HTML-Seite • sonst gesonderte Behandlung des form-Tags notwendig • nur Controls, keine Pages • Pages entweder in den folgenden Code einflechten, oder • Pages in ASCX-Controls umwandeln • nur Form, kein Head • kann analog aus dem HTML-Code übertragen werden

  10. Quellcode • https://github.com/malteclasen/MvcMigration.git

  11. Controller private ControlCreateItem(Page page); publicvirtualActionResult Index() { varitem =WebFormsHelper.RenderLegacyItem(CreateItem, HttpContext, PageUrl); ViewBag.ControlHtml= item.ControlHtml; returnView("LegacyItem"); } • Controller.Index()

  12. Code-Control privateControlCreateItem(Pagepage) { returnnewWebForms.MyControl(); } • CreateItem() • Controller.Index()

  13. ASCX-Control • ascx als Embedded Resource privateControlCreateItem(Pagepage) { returnpage.LoadControl( "~/bin/WebForms.dll/" + "WebForms.MyWebUserControl.ascx"); } • CreateItem() • Controller.Index()

  14. Global.asax protectedvoidApplication_Start() { … HostingEnvironment. RegisterVirtualPathProvider( newEmbeddedResourcePathProvider()); … } • Application_Start()

  15. Controller publicvirtualActionResult Index() { varitem =WebFormsHelper.RenderLegacyItem(CreateItem, HttpContext, PageUrl); ViewBag.ControlHtml= item.ControlHtml; returnView("LegacyItem"); } • Controller.Index()

  16. WebFormsHelper.RenderLegacyItem() publicstaticItemContentRenderLegacyItem( Func<Page, Control> contentCreator) { varpage = CreatePage(); varcontent = contentCreator(page); page.AddControl(content); varwriter= newStringWriter(); varresponse = ProcessRequest(page, writer); … • WFH.RenderLegacyItem()Controller.Index()

  17. WebFormsHelper.RenderLegacyItem() … TransferCookies(response, HttpContext.Current.Response); varform = GetForm( Clean(stringWriter.ToString())); returnnewItemContent { ControlHtml= form, }; } • WFH.RenderLegacyItem()Controller.Index()

  18. WebFormsHelper.CreatePage() privatestaticContainerPageCreatePage() { varpage = newContainerPage{ RenderingCompatibility=newVersion(3, 5), ClientIDMode=ClientIDMode.AutoID, }; varscriptManager = newScriptManager { … } AddDefaultScripts(scriptManager); page.AddControl(scriptManager); page.AddHead(newContentPlaceHolder{ ID = "HeadContent"}); returnpage; } • WFH.CreatePage()WFH.RenderLegacyItem()Controller.Index()

  19. ContainerPage privateclassContainerPage : Page { privateHtmlForm_form = newHtmlForm(); privateHtmlHead_head = newHtmlHead(); protectedoverridevoidOnInit(EventArgs e) … publicvoidAddHead(Controlcontrol) … publicvoidAddControl(Controlcontrol) … privateHttpSessionState _session; publicoverrideHttpSessionStateSession … } • WFH.CreatePage()WFH.RenderLegacyItem()Controller.Index()

  20. ContainerPage.OnInit() protectedoverridevoidOnInit(EventArgs e) { base.OnInit(e); varhtml = newHtmlGenericControl("html"); Controls.Add(html); html.Controls.Add(_head); varbody = newHtmlGenericControl("body"); html.Controls.Add(body); _form.Enctype = "multipart/form-data"; body.Controls.Add(_form); } • CP.OnInit()WFH.CreatePage()WFH.RenderLegacyItem()Controller.Index()

  21. WebFormsHelper.CreatePage() privatestaticContainerPageCreatePage() { varpage = newContainerPage{ RenderingCompatibility=newVersion(3, 5), ClientIDMode=ClientIDMode.AutoID, }; varscriptManager = newScriptManager { … } AddDefaultScripts(scriptManager); page.AddControl(scriptManager); page.AddHead(newContentPlaceHolder{ ID = "HeadContent"}); returnpage; } • WFH.CreatePage()WFH.RenderLegacyItem()Controller.Index()

  22. WebFormsHelper.AddDefaultScripts() privatestaticvoidAddDefaultScripts( ScriptManagerscriptManager) { scriptManager.Scripts.Add(newScriptReference {Name = "MsAjaxBundle"}); scriptManager.Scripts.Add(newScriptReference {Name = "WebForms.js", Assembly = "System.Web", Path = "~/Scripts/WebForms/WebForms.js" }); … } • WFH.AddDefaultScripts()WFH.CreatePage()WFH.RenderLegacyItem()Controller.Index()

  23. App_Start\BundleConfig publicclassBundleConfig { publicstaticvoidRegisterBundles( BundleCollectionbundles) { bundles.Add( newScriptBundle("~/bundles/MsAjaxJs") .Include( "~/Scripts/WebForms/MsAjax/MicrosoftAjax.js", … )); } • BC.RegisterBundles()

  24. WebFormsHelper.RenderLegacyItem() publicstaticItemContentRenderLegacyItem( Func<Page, Control> contentCreator) { varpage = CreatePage(); varcontent = contentCreator(page); page.AddControl(content); varwriter= newStringWriter(); varresponse = ProcessRequest(page, writer); … • WFH.RenderLegacyItem()Controller.Index()

  25. WebFormsHelper.ProcessRequest() privatestaticHttpResponseProcessRequest( IHttpHandlerpage, TextWriterwriter) { varresponse = newHttpResponse(writer); varcontext = newHttpContext( HttpContext.Current.Request, response); context.SetSessionStateBehavior( SessionStateBehavior.Required); page.ProcessRequest(context); returnresponse; } • WFH.ProcessRequest()WFH.RenderLegacyItem()Controller.Index()

  26. ContainerPage.Session publicoverrideHttpSessionState Session { get { return_session ?? (_session = GetMockHttpSessionState()); } } • CP.Session • WFH.ProcessRequest()WFH.RenderLegacyItem()Controller.Index()

  27. ContainerPage.GetMockHttpSessionState privatestaticHttpSessionState GetMockHttpSessionState() { varstaticObjects = newHttpStaticObjectsCollection(); varitemCollection = newSessionStateItemCollection(); IHttpSessionStatesessionStateContainer = newHttpSessionStateContainer(…); … • CP.GetMockHttpSessionState() • CP.SessionWFH.ProcessRequest()WFH.RenderLegacyItem()Controller.Index()

  28. ContainerPage.GetMockHttpSessionState varstate = (HttpSessionState) Activator.CreateInstance( typeof(HttpSessionState), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance| BindingFlags.CreateInstance, null, newobject[] { sessionStateContainer }, CultureInfo.CurrentCulture); returnstate; } • CP.GetMockHttpSessionState() • CP.SessionWFH.ProcessRequest()WFH.RenderLegacyItem()Controller.Index()

  29. WebFormsHelper.RenderLegacyItem() … TransferCookies(response, HttpContext.Current.Response); varform = GetForm( Clean(stringWriter.ToString())); returnnewItemContent { ControlHtml= form, }; } • WFH.RenderLegacyItem()Controller.Index()

  30. WebFormsHelper.TransferCookies() privatestaticvoidTransferCookies( HttpResponsesource, HttpResponse target) { foreach(var cookie in source.Cookies.Cast<string>() .Select(key => source.Cookies[key]) .Where(cookie => cookie != null)) { target.Cookies.Add(cookie); } } • WFH.TransferCookies()WFH.RenderLegacyItem()Controller.Index()

  31. WebFormsHelper.RenderLegacyItem() … TransferCookies(response, HttpContext.Current.Response); varform = GetForm( Clean(stringWriter.ToString())); returnnewItemContent { ControlHtml= form, }; } • WFH.RenderLegacyItem()Controller.Index()

  32. WebFormsHelper.Clean() privatestaticstring Clean(string source) { returnsource.Replace( "&nbsp;", "&#160;"); } • WFH.Clean()WFH.RenderLegacyItem()Controller.Index()

  33. WebFormsHelper.RenderLegacyItem() … TransferCookies(response, HttpContext.Current.Response); varform = GetForm( Clean(stringWriter.ToString())); returnnewItemContent { ControlHtml= form, }; } • WFH.RenderLegacyItem()Controller.Index()

  34. WebFormsHelper.GetForm() privatestaticstringGetForm(stringrendered) { conststringformStartTag = "<form"; conststringformEndTag = "</form>"; varformStart= rendered.IndexOf(formStartTag); varformEnd = rendered.LastIndexOf(formEndTag); varform = rendered.Substring(formStart, formEnd-formStart+formEndTag.Length); returnform; } • WFH.GetForm()WFH.RenderLegacyItem()Controller.Index()

  35. Controller publicvirtualActionResult Index() { varitem =WebFormsHelper.RenderLegacyItem(CreateItem, HttpContext, PageUrl); ViewBag.ControlHtml= item.ControlHtml; returnView("LegacyItem"); } • Controller.Index()

  36. View @Html.Raw(ViewBag.ControlHtml)

  37. Zusammenfassung • Control laden, ASCX aus Embedded Resource • HttpContext und Page erzeugen • Page.ProcessRequest aufrufen • Cookies transferieren • HTML-Code an View übergeben • Quellcode auf https://github.com/malteclasen/MvcMigration.git

  38. Vielen Dank! Dr. Malte Clasen adesso AG

  39. Firma • mein Blog: http://malteclasen.de/blog • mein Arbeitgeber: http://adesso.de • Stellenangebote: http://www.aaajobs.de/

More Related