/// <summary>
        /// This method is used to send an Element through any registered ControlConverter adapters and get back
        /// the migrated text from the AdapterHost.
        /// </summary>
        /// <param name="elementToProcess"></param>
        /// <returns>String</returns>
        private async Task <string> ProcessSourceElement(string elementToProcess, AdapterHost host)
        {
            HtmlNode      processedElement = null;
            StringBuilder processedHTML    = new StringBuilder();
            var           htmlParser       = new HtmlDocument();

            htmlParser.LoadHtml(elementToProcess);
            var contentControlObj = htmlParser.DocumentNode.FirstChild;

            try
            {
                //If this is an ASP:* control then call the migration code, append the *entire* migrated node, and return to the calling method.
                if (contentControlObj.Name.ToLower().Contains("asp:"))
                {
                    var newNodeText = await host.ConvertTag(contentControlObj.Name, contentControlObj.OuterHtml);

                    //We do *not* deal with any children of this element, as that is the responsibility of the MigratTagControl to deal with any children of the ASP control
                    return(newNodeText);
                }
                else
                {
                    //if the current element has children,
                    // - add it to the targetDocumentFragment without the children attached
                    // - recursively call this method to deal with the children, passing in the new appended as the parent element to append children too
                    if (contentControlObj.ChildNodes.Count > 0)
                    {
                        //shallow clone
                        processedElement = contentControlObj.CloneNode(false);

                        foreach (var item in contentControlObj.ChildNodes)
                        {
                            if (item.NodeType == HtmlNodeType.Element)
                            {
                                var migratedValue = await ProcessSourceElement(item.OuterHtml, host);

                                var migratedChild = HtmlNode.CreateNode(migratedValue.Length > 0 ? migratedValue : " ");
                                processedElement.AppendChild(migratedChild);
                            }
                        }
                        processedHTML.Append(processedElement.OuterHtml);
                    }
                    else
                    {
                        processedHTML.Append((contentControlObj.Clone()).OuterHtml);
                    }

                    return(processedHTML.ToString());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                htmlParser = null;
            }
        }
예제 #2
0
        /// <summary>
        /// This method is used to convert the asp:Content control to a Blazor equivalent.  In this particular
        /// case - there is no equivalent.  This control is the top-level asp:* container for a page and really just holds all other
        /// controls that are found in an *.aspx page definition.
        /// </summary>
        /// <param name="nodeContent"></param>
        /// <returns></returns>
        private async Task <string> ConvertContentControl(string nodeContent)
        {
            string   _result    = string.Empty;
            var      model      = new HtmlDocument();
            var      innerModel = new HtmlDocument();
            HtmlNode returnNode;

            try
            {
                model.LoadHtml(nodeContent);
                var contentControlObj = model.DocumentNode.FirstChild;
                returnNode = contentControlObj.CloneNode(false);
                innerModel.LoadHtml(contentControlObj.InnerHtml);  //<-- this is where we actually remove the asp:content control from the model

                //send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
                var             allchildren      = innerModel.DocumentNode.Descendants().Where(p => p.Name.ToLower().Contains("asp:"));
                List <HtmlNode> targetedChildren = new List <HtmlNode>();

                //filter out nested asp:* controls from the list (children are processed by the specific adapter converter method)
                //this way we don't end up double-calling a AdapterHost.ConvertTag on controls that have already been taken care of by their
                //parent asp:* control converter
                foreach (var control in allchildren)
                {
                    var anc1 = control.Ancestors().Where(c => c.Name.Contains("asp:"));

                    if (!anc1.Any())
                    {
                        targetedChildren.Add(control);
                    }
                }

                foreach (var nodeObj in targetedChildren)
                {
                    var migratedControlText = await AdapterHost.ConvertTag(nodeObj.Name, nodeObj.OuterHtml);

                    var tempNode = HtmlNode.CreateNode(migratedControlText);
                    nodeObj.ParentNode.ReplaceChild(tempNode, nodeObj);
                }

                return(innerModel.DocumentNode.OuterHtml);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                model = null;
            }
        }
예제 #3
0
        /// <summary>
        /// This method understands now to convert an asp:FormView control into a blazor equivalent.
        /// </summary>
        /// <param name="nodeContent"></param>
        /// <returns></returns>
        private async Task <string> ConvertListViewControl(string nodeContent)
        {
            //var model = await _angleSharpContext.OpenAsync(req => req.Content(nodeContent));
            var currentModel = new HtmlDocument();
            var newModel     = new HtmlDocument();

            currentModel.LoadHtml(nodeContent);


            try
            {
                var listViewNode = currentModel.DocumentNode.FirstChild;// ("//asp:listview");// model.All.Where(p => p.LocalName.ToLower().Equals("asp:formview")).FirstOrDefault();

                newModel.LoadHtml($"<ListView Model={listViewNode.GetAttributeValue("ItemType", "")} OnValidSubmit={listViewNode.GetAttributeValue("SelectMethod", "")}></ListView>");
                var newNode = newModel.DocumentNode.SelectSingleNode("//listview");
                //this is now a live list having substituted the EditForm control for the old FormView one
                newNode.AppendChildren(listViewNode.ChildNodes);

                //send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
                var aspFormTags = newModel.DocumentNode.FirstChild.Descendants().Where(p => p.Name.ToLower().Contains("asp:")).ToList();
                foreach (var formObj in aspFormTags)
                {
                    var migratedControlText = await AdapterHost.ConvertTag(formObj.Name, formObj.OuterHtml);

                    var tempNode = HtmlNode.CreateNode(migratedControlText);

                    formObj.ParentNode.ReplaceChild(tempNode, formObj);
                }

                return(newModel.DocumentNode.OuterHtml);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                currentModel = null;
                newModel     = null;
            }
        }
예제 #4
0
        /// <summary>
        /// This method understands now to convert an asp:FormView control into a blazor equivalent.
        /// </summary>
        /// <param name="nodeContent"></param>
        /// <returns></returns>
        private async Task <string> ConvertFormViewControl(string nodeContent)
        {
            var currentModel = new HtmlDocument();
            var newModel     = new HtmlDocument();

            currentModel.LoadHtml(nodeContent);

            try
            {
                var editFormNode = currentModel.DocumentNode.FirstChild;// ("//asp:listview");// model.All.Where(p => p.LocalName.ToLower().Equals("asp:formview")).FirstOrDefault();

                newModel.LoadHtml($"<EditForm Model={editFormNode.GetAttributeValue("ItemType", "")} OnValidSubmit={editFormNode.GetAttributeValue("SelectMethod", "")}></EditForm>");
                var newNode = newModel.DocumentNode.SelectSingleNode("//editform");
                //this is now a live list having substituted the EditForm control for the old FormView one
                newNode.AppendChildren(editFormNode.ChildNodes);

                //deal with itemtemplates... ??

                //send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
                var aspFormTags = newModel.DocumentNode.FirstChild.Descendants().Where(p => p.Name.ToLower().Contains("asp:")).ToList();
                foreach (var formObj in aspFormTags)
                {
                    var migratedControlText = await AdapterHost.ConvertTag(formObj.Name, formObj.OuterHtml);

                    var tempNode = HtmlNode.CreateNode(migratedControlText);

                    formObj.ParentNode.ReplaceChild(tempNode, formObj);
                }

                return(newModel.DocumentNode.OuterHtml);

                //var editFormNode = model.All.Where(p => p.LocalName.ToLower().Equals("asp:formview")).FirstOrDefault();
                //var newNode = parser.ParseFragment($"<EditForm Model={editFormNode.GetAttribute("ItemType")} OnValidSubmit={editFormNode.GetAttribute("SelectMethod")}></EditForm>", editFormNode);

                ////this is now a live list having substituted the EditForm control for the old FormView one
                //newNode.First().AppendNodes(editFormNode.ChildNodes.ToArray());

                //if (model.All.Any(p => p.TagName.ToLower().Equals("itemtemplate")))
                //{
                //    //deal with itemtemplates... ??
                //}

                ////send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
                //var aspFormTags = newNode.First().Descendents<IElement>().Where(p => p.NodeName.ToLower().Contains("asp:")).ToList();
                //foreach (var formObj in aspFormTags)
                //{
                //    var migratedControlText = await _adapterHost.MigrateTagControl(formObj.NodeName, formObj.OuterHtml);
                //    var tempNode = parser.ParseFragment(migratedControlText, null);

                //    //ParseFragment always adds on a HTML & BODY tags, at least with this call setup.  We need to pull out *just* the element that we have migrated.
                //    var appendElement = tempNode.GetElementsByTagName("BODY").First().ChildNodes;

                //    formObj.Replace(appendElement.ToArray());
                //}

                //return newNode.First().ToHtml();//.OuterHTML; // .ToString();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                currentModel = null;
                newModel     = null;
            }
        }
예제 #5
0
        /// <summary>
        /// This method is used to generically convert an asp control by removing the 'asp:'
        /// prefix from the control name and then returning the resultant content back to the caller.
        /// </summary>
        /// <param name="nodeContent"></param>
        /// <returns>converted control content</returns>
        private async Task <string> ConvertGenericControl(string nodeContent)
        {
            var model = new HtmlDocument();

            model.LoadHtml(nodeContent);
            HtmlNode rootNode = null;

            try
            {
                rootNode = model.DocumentNode.FirstChild;

                if (rootNode.Name.Contains("asp:"))
                {
                    rootNode.Name = rootNode.Name.Replace("asp:", string.Empty);
                }

                //send any child asp:* controls to be converted by the a call back out to the adapterHosting class.
                var             allchildren      = rootNode.Descendants().Where(p => p.Name.ToLower().Contains("asp:"));
                List <HtmlNode> targetedChildren = new List <HtmlNode>();

                //filter out nested asp:* controls from the list (children are processed by the specific adapter converter method)
                //this way we don't end up double-calling a AdapterHost.ConvertTag on controls that have already been taken care of by their
                //parent asp:* control converter
                foreach (var control in allchildren)
                {
                    var anc1 = control.Ancestors().Where(c => c.Name.Contains("asp:"));

                    if (!anc1.Any())
                    {
                        targetedChildren.Add(control);
                    }
                }
                foreach (var nodeObj in targetedChildren)
                {
                    var migratedControlText = await AdapterHost.ConvertTag(nodeObj.Name, nodeObj.OuterHtml);

                    var tempNode = HtmlNode.CreateNode(migratedControlText);
                    nodeObj.ParentNode.ReplaceChild(tempNode, nodeObj);
                }

                //var aspFormTags = rootNode.Descendants().Where(p => p.Name.ToLower().Contains("asp:"));//.ToList();
                //foreach (var control in aspFormTags)
                //{
                //    var migratedControlText = await AdapterHost.ConvertTag(control.Name, control.OuterHtml);

                //    var tempNode = HtmlNode.CreateNode(migratedControlText);

                //    control.ParentNode.ReplaceChild(tempNode, control);
                //}

                return(rootNode.OuterHtml);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                model = null;
            }
        }
        private async Task <Dictionary <string, string> > ReplaceAspControls(string sourceAspCode)
        {
            Dictionary <string, string> result = new Dictionary <string, string>();
            StringBuilder migratedSource       = new StringBuilder();
            var           docFrag = new HtmlAgilityPack.HtmlDocument();

            docFrag.LoadHtml(sourceAspCode);
            var converterAdapterHost = new AdapterHost();

            converterAdapterHost.RegisterAdapter(x => new AspxToBlazorControlConverter(converterAdapterHost));

            try
            {
                //Deal with HTML, HEAD and BODY tags (most *.aspx pages won't have these - but we still have to manage those that do)
                //Look through the incoming sourceAspCode parameter and see if we have any of those three tags present.
                var htmlTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<HTML.*?>(.|\n)*?<\/HTML>", RegexOptions.IgnoreCase);
                var headTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<HEAD.*?>(.|\n)*?<\/HEAD>", RegexOptions.IgnoreCase);
                var bodyTag = System.Text.RegularExpressions.Regex.Match(sourceAspCode, @"<BODY>(.|\n)*?<\/BODY>", RegexOptions.IgnoreCase);

                foreach (var child in docFrag.DocumentNode.ChildNodes)
                {
                    //New HtmlAgilityPack parsing which does *not* add HTML/HEAD/BODY etc tags to the source
                    if (child.Name.ToLower().Equals("html"))
                    {
                        //migratedSource.Append(await ProcessSourceElement(child.OuterHtml, converterAdapterHost));
                        continue;
                    }

                    if (child.Name.ToLower().Equals("head"))
                    {
                        //just take the value of the headTag Regex match from earlier in this method (there are no asp:* controls of any kind that live in the
                        //HEAD tag - so we can just copy it down to here)
                        migratedSource.Append(await ProcessSourceElement(child.OuterHtml, converterAdapterHost));
                        continue;
                    }
                    if (child.Name.ToLower().Equals("body"))
                    {
                        //We go ahead and process this element.  Any children of the tag are actually handled by the ProcessSourceElement() method
                        var migratedBodyElement = await ProcessSourceElement(child.OuterHtml, converterAdapterHost);

                        if (!bodyTag.Success)
                        {
                            var matches = Regex.Match(migratedBodyElement, @"<body>([\S\s]*)<\/body>", RegexOptions.IgnoreCase);
                            migratedSource.Append(matches.Groups[1].Value);
                        }
                        else
                        {
                            migratedSource.Append(migratedBodyElement);
                        }
                        continue;
                    }

                    //Its just a vanilla text sitting outside of a elementNode, append it.
                    if (!child.NodeType.Equals(HtmlNodeType.Element))
                    {
                        migratedSource.Append(child.OuterHtml);
                        continue;
                    }

                    //Its an element Node - process it.
                    if (child.NodeType.Equals(HtmlNodeType.Element))
                    {
                        migratedSource.Append(await ProcessSourceElement(child.OuterHtml, converterAdapterHost));
                        continue;
                    }
                }

                result.Add("source", sourceAspCode);
                result.Add("alteredSource", migratedSource.ToString());
            }
            catch (Exception ex)
            {
                throw;
            }

            return(result);
        }