<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>fleximal</title><description>fleximal</description><link>https://www.fleximal.com.au/blog</link><item><title>HTML Manipulation - MSHTML vs HTML Agility Pack</title><description><![CDATA[Best HTML ParserWhen it comes to HTML page content manipulation, there are two main HTML parsers which goes well with .NET framework. MSHTML by Microsoft HTML Agility Pack Out of the two, according to my experience, Agility Pack outweigh MSHTML easily. Following are the main reasons. Proper documentation. Customer support. Support large HTML contents. More features/methods. MSHTML is a legacy Microsoft library and you have to add it to your project from your computer’s assembly location (Add]]></description><link>https://www.fleximal.com.au/single-post/2018/07/11/HTML-Manipulation---Mshtm-vs-HTML-Agility-Pack</link><guid>https://www.fleximal.com.au/single-post/2018/07/11/HTML-Manipulation---Mshtm-vs-HTML-Agility-Pack</guid><pubDate>Wed, 11 Jul 2018 07:06:08 +0000</pubDate><content:encoded><![CDATA[<div><div>Best HTML Parser</div><div>When it comes to HTML page content manipulation, there are two main HTML parsers which goes well with .NET framework.</div><div>MSHTML by MicrosoftHTML Agility Pack</div><div>Out of the two, according to my experience, Agility Pack outweigh MSHTML easily. Following are the main reasons.</div><div>Proper documentation.Customer support.Support large HTML contents.More features/methods.</div><div>MSHTML is a legacy Microsoft library and you have to add it to your project from your computer’s assembly location (Add Reference -&gt; Assemblies -&gt; Type “HTML”, you will see Microsoft.mshtml. Then add it to your project). Or you can try the Nuget package version as well.</div><div>To start manipulating HTML content, you have to,</div><div>Load the HTML content</div><div>MSHTML</div><div>If you pass your HTML content using a string parameter called “content”,</div><div>var htmlDoc = new HTMLDocument(); var ihtmlDoc = (IHTMLDocument2)htmlDoc; ihtmlDoc.open(); ihtmlDoc.write(content);</div><div>Agility Pack</div><div>HtmlWeb web = new HtmlWeb();</div><div>var uri = new Uri(FilePath)</div><div>var htmlDoc = web.Load(uri, &quot;POST&quot;);</div><div>If you are trying to manipulate a large page, we would recommend you to use HTML Agility Pack without a doubt. Our <a href="https://www.fleximal.com.au/net-solutions">.Net development</a> team has experienced limitations with MSHTML when it comes to handling large HTML content. It was with one of our <a href="https://www.fleximal.com.au/sharepoint-development">SharePoint Development</a> (with Azure) projects and the team had to struggle a lot to pinpoint the issue. Once we pushed the solution to one of our Azure App Services, MSHTML solution tends to break at “itmlDoc.write(content)” code line without even giving an error or stack trace. It could be either a memory leak or an unhandled exception with that library.</div><div>Following are some common parse commands that you can use to manipulate an HTML page.</div><div>Deleting a Node</div><div>MSHTML</div><div>var childNode = htmlDoc.getElementById(&quot;u_0_1i&quot;);</div><div>if (childNode!= null)</div><div>{</div><div>var parentNode = ((mshtml.HTMLDivElement)childNode).parentNode;parentNode.removeChild((IHTMLDOMNode)childNode);</div><div>}</div><div>HTML Agility Pack</div><div>var childNode = htmlDoc.GetElementbyId(&quot;u_0_1i&quot;);</div><div>if (childNode!= null)</div><div>{</div><div>childNode.ParentNode.RemoveChild(childNode, false);</div><div>}</div><div>In both the cases, we have to get the Child Element and then use its Parent Element to delete the child.</div><div>Set CSS of an Element</div><div>MSHTML</div><div>var postContentContainer = htmlDoc.getElementById(&quot;content_container&quot;);</div><div>if(postContentContainer!=null)</div><div>postContentContainer.style.cssText= &quot;width: 100%!important;&quot;;</div><div>HTML Agility Pack</div><div>var postContentContainer = htmlDoc.GetElementbyId(&quot;content_container&quot;); if (postContentContainer != null) { postContentContainer.GetAttributeValue(&quot;style&quot;,null); postContentContainer.SetAttributeValue(&quot;style&quot;, &quot;width: 100%!important;&quot;); }</div><div>Note: We had no luck with “postContentContainer.Attributes.Append(&quot;style&quot;);” when it comes to changing the style of an element with HTML Agility Pack. It has to be “GetAttributeValue” and then “SetAttributeValue” to overwrite the styles.</div><div>Set Attributes of an Element</div><div>MSHTML</div><div>var nodeSample= htmlDoc.getElementById(&quot;content_container&quot;); nodeSample.setAttribute(&quot;width&quot;,&quot;100%&quot;);</div><div>HTML Agility Pack</div><div>var globalContainer = htmlDoc.GetElementbyId(&quot;globalContainer&quot;); if (globalContainer != null) { globalContainer.Attributes.Append(&quot;width&quot;); globalContainer.SetAttributeValue(&quot;width&quot;, &quot;100%!important;&quot;); }</div><div>Change CSS Class Name</div><div>MSHTML</div><div>nodeSample= htmlDoc.getElementById(&quot;content_container&quot;);</div><div>nodeSample.className= &quot;_2pie _14i5 _1qkx&quot;;</div><div>HTML Agility Pack</div><div>var videosElement = htmlDoc.GetElementbyId(&quot;videos&quot;); if (videosElement != null) { videosElement.ReplaceClass(&quot;newClass&quot;, &quot;oldClass&quot;); }</div><div>Overwrite CSS or Add New Classes</div><div>MSHTML</div><div>mshtml.IHTMLStyleSheet css = (mshtml.IHTMLStyleSheet)ihtmlDoc.createStyleSheet(&quot;&quot;, 0);</div><div>css.cssText = &quot;.uiScaledImageContainer { width: 100% !important; height: auto!important; } ._4-eo { width: 100% !important; }&quot;</div><div>HTML Agility Pack</div><div>var cssString = &quot;.uiScaledImageContainer { /*image container*/ width: 100% !important; height: auto!important; } ._4-eo { /*image a tag*/ width: 100% !important; }&quot; var styles = htmlDoc.CreateElement(&quot;style&quot;); var styleText = htmlDoc.CreateTextNode(cssString); styles.AppendChild(styleText); htmlDoc.DocumentNode.AppendChild(styles);</div><div>Select a Particular Nodes</div><div>HTML Agility Pack</div><div>var imgs = htmlDoc.DocumentNode.SelectNodes(&quot;//a&quot;);</div><div>Overwrite an Attribute</div><div>HTML Agility Pack</div><div>var imgs = htmlDoc.DocumentNode.SelectNodes(&quot;//a&quot;);</div><div> foreach (var node in imgs)</div><div> {</div><div> if (node.Attributes.Contains(&quot;target&quot;))</div><div> node.Attributes.Remove(&quot;target&quot;);</div><div> node.Attributes.Append(&quot;target&quot;);</div><div> node.SetAttributeValue(&quot;target&quot;, &quot;_blank&quot;);</div><div> }</div><div>Select Nodes with REGEX</div><div>HTML Agility Pack</div><div>var nodes = htmlDoc.DocumentNode.SelectNodes(&quot;//div[contains(@class, '_5va1 _427x')]&quot;);</div><div>This will get all the DIVs that contains the class</div><div>Save the document at the end to see the changes.</div><div>HTML Agility Pack</div><div>using (StreamWriter sw1 = new StreamWriter(filePath + &quot;/test.html&quot;)) { htmlDoc.Save(sw1); }</div><div>Summary</div><div>With the experience of handling all these libraries to a greater level, I would recommend to pick HTML Agility Pack over MSHTML Class Library without a doubt.</div><div>If you want more support, please <a href="https://www.fleximal.com.au/contact">contact us</a>.</div></div>]]></content:encoded></item><item><title>Azure Hosted App – Login Redirect Loop</title><description><![CDATA[Our Software Development team encountered a weird issue on one of the MVC web based projects. In some cases, if the App is hosted in Azure and authenticated by Azure AD, the user is redirected to Microsoft Online login page. This only happens when the solutions is publish to Azure(Not in the dev environment).This is a semi-famous bug(Katana Bug #197) in Microsoft Owin implementation. This bug is related to the Cookie handling algorithm and clearing out stored cookies might only be a temporary]]></description><link>https://www.fleximal.com.au/single-post/2018/03/11/Azure-Hosted-App-%E2%80%93-Login-Redirect-Loop</link><guid>https://www.fleximal.com.au/single-post/2018/03/11/Azure-Hosted-App-%E2%80%93-Login-Redirect-Loop</guid><pubDate>Sat, 10 Mar 2018 21:47:20 +0000</pubDate><content:encoded><![CDATA[<div><div>Our Software Development team encountered a weird issue on one of the MVC web based projects. In some cases, if the App is hosted in Azure and authenticated by Azure AD, the user is redirected to Microsoft Online login page. This only happens when the solutions is publish to Azure(Not in the dev environment).</div><div>This is a semi-famous bug(Katana Bug #197) in Microsoft Owin implementation. This bug is related to the Cookie handling algorithm and clearing out stored cookies might only be a temporary solution.</div><div>I would recommend to follow the bellow article first to check whether it fixes your problem.</div><div>https://www.laptopmag.com/articles/fix-stuck-login-office-365</div><div>If this doesn’t fix your problem, please get and install “Kentor.OwinCookieSaver” from the Nuget package manager in to your project. After installing, please do the following modification in “Startup.Auth.cs” file.</div><div>Go to “ConfigureAuth” method.</div><div>add;</div><div>app.UseKentorOwinCookieSaver();</div><div>just before;</div><div>app.UseCookieAuthentication(new CookieAuthenticationOptions());</div><div>Make sure that you install the latest package as the old package did not fix my problem. According to the latest package you might be required to change the .NET framework of your project. The latest “Kentor.OwinCookieSaver” Works with .Net Framework 4.6 or higher.</div></div>]]></content:encoded></item><item><title>Some jQuery functions only works in Edit Page mode, not when the page is published</title><description><![CDATA[This is a known issue for publishing pages has become a common problem in SharePoint Development. Some Javascript libraries are not loaded in SharePoint page Publishing mode. For an example, as a part of Minimal Download Strategy(MDS), “sp.js” may not be loaded at every page load, unless it is explicitly loaded.Thus, some jQuery features may not work in the following code in Publishing pages,$(document).ready(function() { // My custom functionality});Use the following code block]]></description><dc:creator>Admin</dc:creator><link>https://www.fleximal.com.au/single-post/2017/08/12/jQuery-not-working-sharepoint-publishing-pages</link><guid>https://www.fleximal.com.au/single-post/2017/08/12/jQuery-not-working-sharepoint-publishing-pages</guid><pubDate>Sat, 12 Aug 2017 05:13:01 +0000</pubDate><content:encoded><![CDATA[<div><div>This is a known issue for publishing pages has become a common problem in SharePoint Development. Some Javascript libraries are not loaded in SharePoint page Publishing mode. For an example, as a part of Minimal Download Strategy(MDS), “sp.js” may not be loaded at every page load, unless it is explicitly loaded.</div><div>Thus, some jQuery features may not work in the following code in Publishing pages,</div><div>$(document).ready(function() {</div><div> // My custom functionality</div><div>});</div><div>Use the following code block instead;</div><div>$(document).ready(function ()</div><div>{</div><div> SP.SOD.executeFunc('sp.js', 'SP.ClientContext', myFunction);</div><div>});</div><div>function myFunction ()</div><div>{</div><div> // My custom code</div><div>};</div><div>“SOD.executeFunc” loads the “sp.js” file first and then execute the custom functions.</div><div>The problem we have with exectueFunc is, if the script associated with the script key is already loaded, then executeFunc does absolutely NOTHING. In our case, if “sp.js” is already loaded, “myFunction” will not be executed. Thus, if you use your code in a button click function, button click code will only be executed once.</div><div>To get our function executed all the time, we have to use both methods in conjunction with one another as follows:</div><div>executeOrDelayUntilScriptLoaded(function() {</div><div> ..My Code..</div><div> },&quot;custScript.js&quot;);</div><div> executeFunc(&quot;custScript.js&quot;, null, null);</div><div>Above code will queue “My Code”, until “custScript.js” is loaded. If “custScript.js” is already loaded, it will execute “My Code” straight away.</div><div>Different between document.ready vs spBodyOnLoadFunctions</div><div>SharePoint uses its own body onload function called, _spBodyOnLoadFunctionNames. It is recommended to use this as it allows the things to load in their proper order.</div><div>In some cases, you might need to execute your jQuery code after the page is completely loaded. For example; if you want to re-write / overwrite page elements/tags, use the following code segment;</div><div>_spBodyOnLoadFunctions.push(function(){</div><div>ExecuteOrDelayUntilScriptLoaded(myFunction, &quot;sp.js&quot;);</div><div>});</div><div>function myFunction ()</div><div>{</div><div>};</div></div>]]></content:encoded></item><item><title>Introducing Fleximal</title><description><![CDATA[We are an Australian software development company specializing in SharePoint and .NET Applications. We already have a ground breaking, self developed tools to help our customers connect to the future of business. For example, our SharePoint Migration Tool SW1SH, is one of the first migration tools that have been developed in Australia. Why us? The benefit in choosing us is the understanding of business demands due to competing priorities of business operations. The team has previous grass roots]]></description><dc:creator>Admin</dc:creator><link>https://www.fleximal.com.au/single-post/2017/08/06/Introducing-Fleximal</link><guid>https://www.fleximal.com.au/single-post/2017/08/06/Introducing-Fleximal</guid><pubDate>Sun, 06 Aug 2017 02:14:10 +0000</pubDate><content:encoded><![CDATA[<div><div>We are an Australian software development company specializing in SharePoint and .NET Applications. We already have a ground breaking, self developed tools to help our customers connect to the future of business. For example, our SharePoint Migration Tool SW1SH, is one of the first migration tools that have been developed in Australia.  Why us?  The benefit in choosing us is the understanding of business demands due to competing priorities of business operations. The team has previous grass roots business and management experience through to highly complex business situations. Combine this with business training and Information Technology systems training. This is leading to a high quality of workmanship, analysis and implementation of situationally appropriate software systems. (No two systems will be alike, because no two businesses are alike)  Our blog will discuss  In this blog thread, we will attempt to demystify the issues in business and information technology that face business today. The aim is to provide “You”, our business customers with the confidence and inspiration to move forward with our company and your business.  As we go along, we will be discussing several management theories and practices that can be transformed by Information Technology. We will explain jargon terms of what the business owner needs to know to achieve the next level of productivity. We will also discuss the pitfalls and benefits of small business. </div></div>]]></content:encoded></item></channel></rss>