<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Santosh Achanta</title> <link>https://world.optimizely.com/blogs/Santosh-Achanta/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>Correction to no wrappers content area renderer</title>            <link>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2018/5/correction-to-no-wrappers-content-area-renderer/</link>            <description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;line number21 index20 alt2&quot;&gt;&lt;br /&gt;Referring to &lt;a href=&quot;https://krzysztofmorcinek.wordpress.com/2013/09/10/custom-contentarea-without-wrapper-tags/&quot;&gt;Krzysztof Morcinek&#39;s blog post&lt;/a&gt;&amp;nbsp;which is used quite a lot in the epi world, thought to share a small correction to it.&lt;br /&gt;&lt;br /&gt;The below piece of code from the blog post renders all the items while you&#39;re in edit mode which doesn&#39;t allow users to test personalized content.&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:csharp;auto-links:false;toolbar:false&quot; contenteditable=&quot;false&quot;&gt;_contentRequestContext.IsInEditMode(helper.ViewContext.HttpContext)
? contentArea.Contents
: contentArea.FilteredContents&lt;/pre&gt;
&lt;br /&gt;So, this piece of code can be safely replaced with the below&amp;nbsp;which will just render the same items rendered by the out of the box content area renderer which allows users to test how personalized content looks like.
&lt;pre class=&quot;brush:csharp;auto-links:false;toolbar:false&quot; contenteditable=&quot;false&quot;&gt;contentArea.FilteredItems&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;line number23 index22 alt2&quot;&gt;&lt;code class=&quot;csharp plain&quot;&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;line number23 index22 alt2&quot;&gt;&lt;code class=&quot;csharp plain&quot;&gt;&lt;img src=&quot;/link/72b51e627e96447388e24d60b159d25b.aspx&quot; alt=&quot;Image Untitled.png&quot; /&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</description>            <guid>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2018/5/correction-to-no-wrappers-content-area-renderer/</guid>            <pubDate>Thu, 24 May 2018 05:30:30 GMT</pubDate>           <category>Blog post</category></item><item> <title>FormattingJsonAttribute for camel case formatting of variable names and converting enums to strings</title>            <link>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2016/10/formattingjsonattribute-for-camel-case-formatting-of-variable-names-and-converting-enums-to-strings/</link>            <description>&lt;p&gt;I am tired of using JsonProperty decorator for each class member so decided to do something that will automatically take care of camel case conversion of variable names for Json response.&lt;/p&gt;
&lt;p&gt;&quot;FormattingJson&quot; is a decorator for a class or a method to convert property names to camel case and enum values to strings whle serializing response object.&lt;/p&gt;
&lt;p&gt;Usage: Decorate a class(eg. a API controller) or a method with the below&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[FormattingJson(FormatterTypes.CamelCase, FormatterTypes.EnumToString)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Underlying functions those are respinsible for this utility are CamelCasePropertyNamesContractResolver and StringEnumConverter from Newtonsoft.Json library.&lt;/p&gt;
&lt;p&gt;Below&amp;nbsp;is the code for implementation.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Filters;
using Episerver.Web.Site.Attributes.Formatting.Formatters;

namespace Episerver.Web.Site.Attributes.Formatting
{
    /// &amp;lt;summary&amp;gt;
    /// Apply required formatting on the response content
    /// &amp;lt;/summary&amp;gt;
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class FormattingJsonAttribute : ActionFilterAttribute
    {
        private readonly FormatterTypes[] _formatterTypes;

        /// &amp;lt;summary&amp;gt;
        /// Initializes a new instance of the &amp;lt;see cref=&quot;FormattingJsonAttribute&quot;/&amp;gt; class.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;formatterTypes&quot;&amp;gt;The formatter types.&amp;lt;/param&amp;gt;
        /// &amp;lt;exception cref=&quot;System.ArgumentException&quot;&amp;gt;At least one formatter type must be provided;formatterTypes&amp;lt;/exception&amp;gt;
        public FormattingJsonAttribute(params FormatterTypes[] formatterTypes)
        {
            if (formatterTypes == null || !formatterTypes.Any())
            {
                throw new ArgumentException(&quot;At least one formatter type must be provided&quot;);
            }

            _formatterTypes = formatterTypes;
        }

        /// &amp;lt;summary&amp;gt;
        /// Occurs after the action method is invoked.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;actionExecutedContext&quot;&amp;gt;The action executed context.&amp;lt;/param&amp;gt;
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext == null || actionExecutedContext.Response == null)
            {
                return;
            }

            var content = actionExecutedContext.Response.Content as ObjectContent;

            if (content != null)
            {
                var jsonFormatter = new JsonMediaTypeFormatter();
                if (content.Formatter is JsonMediaTypeFormatter)
                {
                    var factory = new FormatterFactory();

                    foreach (var formatter in _formatterTypes)
                    {
                        factory.Create(formatter)
                            .Apply(jsonFormatter);
                    }

                    actionExecutedContext.Response.Content = new ObjectContent(content.ObjectType, content.Value, jsonFormatter);
                }
            }
        }
    }
}

namespace Episerver.Web.Site.Attributes.Formatting
{
    public enum FormatterTypes
    {
        /// &amp;lt;summary&amp;gt;
        /// Changes it from &#39;CamelCase&#39; to &#39;camelCase&#39;.
        /// &amp;lt;/summary&amp;gt;
        CamelCase = 1,

        /// &amp;lt;summary&amp;gt;
        /// Returns the &#39;string&#39; version of the enum. The default parsing is &#39;int&#39;. Example: BalancePosition.Credit will be &#39;Credit&#39; not &#39;0&#39;
        /// &amp;lt;/summary&amp;gt;
        EnumToString = 2
    }
}

using System.Net.Http.Formatting;
using Newtonsoft.Json.Serialization;

namespace Episerver.Web.Site.Attributes.Formatting.Formatters
{
    /// &amp;lt;summary&amp;gt;
    /// Converts output to camel case
    /// &amp;lt;/summary&amp;gt;
    public class CamelCaseFormatterApplier : IFormatterApplier
    {
        /// &amp;lt;summary&amp;gt;
        /// Applies the specified formatter.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;formatter&quot;&amp;gt;The formatter.&amp;lt;/param&amp;gt;
        public void Apply(JsonMediaTypeFormatter formatter)
        {
            formatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        }
    }
}

using System.Net.Http.Formatting;
using Newtonsoft.Json.Converters;

namespace Episerver.Web.Site.Attributes.Formatting.Formatters
{
    /// &amp;lt;summary&amp;gt;
    /// Converts enums from int to string
    /// &amp;lt;/summary&amp;gt;
    public class EnumStringFormatterApplier : IFormatterApplier
    {
        /// &amp;lt;summary&amp;gt;
        /// Applies the specified formatter.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;formatter&quot;&amp;gt;The formatter.&amp;lt;/param&amp;gt;
        public void Apply(JsonMediaTypeFormatter formatter)
        {
            formatter.SerializerSettings.Converters.Add(new StringEnumConverter());
        }
    }
}

using System.Net.Http.Formatting;

namespace Episerver.Web.Site.Attributes.Formatting.Formatters
{
    /// &amp;lt;summary&amp;gt;
    /// Applies formatting to the response output
    /// &amp;lt;/summary&amp;gt;
    public interface IFormatterApplier
    {
        /// &amp;lt;summary&amp;gt;
        /// Applies the specified formatter.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;formatter&quot;&amp;gt;The formatter.&amp;lt;/param&amp;gt;
        void Apply(JsonMediaTypeFormatter formatter);
    }
}

using System;

namespace Episerver.Web.Site.Attributes.Formatting.Formatters
{
    /// &amp;lt;summary&amp;gt;
    /// Creates formatters
    /// &amp;lt;/summary&amp;gt;
    public class FormatterFactory
    {
        /// &amp;lt;summary&amp;gt;
        /// Creates the approriate formatter
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&quot;formatterType&quot;&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        public IFormatterApplier Create(FormatterTypes formatterType)
        {
            switch (formatterType)
            {
                case FormatterTypes.CamelCase:
                    return new CamelCaseFormatterApplier();

                case FormatterTypes.EnumToString:
                    return new EnumStringFormatterApplier();

                default:
                    throw new ArgumentOutOfRangeException(&quot;formatterType&quot;, formatterType, &quot;Invalid formatter type&quot;);
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>            <guid>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2016/10/formattingjsonattribute-for-camel-case-formatting-of-variable-names-and-converting-enums-to-strings/</guid>            <pubDate>Wed, 05 Oct 2016 00:02:05 GMT</pubDate>           <category>Blog post</category></item><item> <title>Only find pages those hold data with no shortcut link to other pages, etc.</title>            <link>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2014/6/Only-find-pages-those-hold-data-with-no-shortcut-link-to-other-pages-etc/</link>            <description>  &lt;p&gt;I had a requirement to find only pages those doesn&#39;t have shortcut link to another page or fetch data from another page etc means those pages holding the actual property data that needs to be manipulated.&lt;/p&gt;      &lt;p&gt;When I couldn’t find quickly on how that can be done using property criteria using the FindPagesWithCriteria method, I stumbled on digging little bit into EPiServer.Core and found that the PageShourtcutType is of type enum which has the first option ‘Normal = 0’ which I need to look for.&lt;/p&gt;    &lt;p&gt;When I debug the PageDataCollection before filtering with criteria, I noticed that the value stored is a number.&lt;/p&gt;  &lt;p&gt;So my code snippet as below and it worked like a charm in the first instance.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;new PropertyCriteria {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Condition = CompareCondition.Equal,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Type = PropertyDataType.Number,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Name = &amp;quot;PageShortcutType&amp;quot;,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Value = &amp;quot;0&amp;quot;,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Required = true​     &lt;br /&gt;}&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2014/6/Only-find-pages-those-hold-data-with-no-shortcut-link-to-other-pages-etc/</guid>            <pubDate>Thu, 26 Jun 2014 13:05:27 GMT</pubDate>           <category>Blog post</category></item><item> <title>Tailoring workflows for EPiServer 5, 6 and 7</title>            <link>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2013/1/Tailoring-workflows-for-EPiServer-5-6-and-7/</link>            <description>&lt;p&gt;We have enabled out of the box Sequential workflow for one of our customers, the workflow starts when an editor modify or create a page and push &#39;Ready to Publish&#39; button. Then an approver receives the workflow email and by default the email is from &#39;task@&amp;lt;hosturl&amp;gt;&#39; if from address is not set up in web.config SMTP settings. So, I have digged into EPiServer.WorkflowFoundation.dll to see why it is happening and found that when a workflow is triggered, it creates a task and use the method SendMail(string fromUser, string toUser, string mailSubject) in EPiServer.Personalization.Task in EPiServer.dll to send email to approvers and by default it look for current user&#39;s email id which is not valid in this case as the workflows executes in own threads separate from the thread serving the request and hence the from email address is the fallback one which is &#39;task@&amp;lt;hosturl&amp;gt;&#39; all the time. Our customer wants the from email address to be the editor’s email address so that the approver knows from the email who actually the editor of the page is.&lt;/p&gt;  &lt;p&gt;Solution for this is, get the code for the sequential approval workflow. In there they should locate the activities named “initializeApprovalState” and “InitializeUpdateState”. Inside these there is an activity called “createApprovalTask” and “createOwnerTask” respectively, if these activities are marked and select view properties, a property “NotifyByEmail” can be set to false. Then the builtin email will not be sent.&lt;/p&gt;  &lt;p&gt;Then before or after the “createApprovalTask” and “createOwnerTask” activities you can drag in one “SendEmailActivity” in that activity where you can then control how the outgoing email should look like.&lt;/p&gt;  &lt;p&gt;See this post for downloading workflow code &lt;a title=&quot;http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2011/8/Source-code-for-the-CMS6R2-built-in-workflows/&quot; href=&quot;http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2011/8/Source-code-for-the-CMS6R2-built-in-workflows/&quot;&gt;http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2011/8/Source-code-for-the-CMS6R2-built-in-workflows/&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;See this post for the steps to get the workflows loaded properly &lt;a title=&quot;http://geekswithblogs.net/SoftwareDoneRight/archive/2008/01/19/howto-set-up-your-project-for-windows-workflow-c-style.aspx&quot; href=&quot;http://geekswithblogs.net/SoftwareDoneRight/archive/2008/01/19/howto-set-up-your-project-for-windows-workflow-c-style.aspx&quot;&gt;http://geekswithblogs.net/SoftwareDoneRight/archive/2008/01/19/howto-set-up-your-project-for-windows-workflow-c-style.aspx&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This blog post applies for workflows in EPiServer 5, 6 and 7 versions and hopefully workflows in the product will be modified and implement this in mere future.&lt;/p&gt;  &lt;p&gt;Let me know if someone is after the same requirement and code for this implementation as I did this already.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2013/1/Tailoring-workflows-for-EPiServer-5-6-and-7/</guid>            <pubDate>Sun, 27 Jan 2013 20:47:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Issue with browsing files in browser having special characters in file name and fix</title>            <link>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2012/11/Issue-with-browsing-files-in-browser-having-special-characters-in-file-name-and-fix/</link>            <description>&lt;p&gt;After upgrading one of our very old customer’s website from EPiServer 4.62 to CMS 6 R2, it was reported that documents with special characters in file name (for e.g. ‘S&amp;amp;R12.pdf’) throwing &lt;strong&gt;‘System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (&amp;amp;).’&lt;/strong&gt; when they are being opened up in browser.&lt;/p&gt;  &lt;p&gt;Fix for this is issue is to just add &lt;strong&gt;requestPathInvalidCharacters=&amp;quot;&amp;quot;&lt;/strong&gt; if you want to allow all special characters. &lt;/p&gt;  &lt;p&gt;The above attribute must be added to the element &amp;lt;httpRuntime&amp;gt; in your website’s web.config so that it will look as follows:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;lt;configuration&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;system.web&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;httpRuntime requestValidationMode=&amp;quot;2.0&amp;quot; requestPathInvalidCharacters=&amp;quot;&amp;quot; /&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/system.web&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; .&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;lt;/configuration&amp;gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you want to restrict certain special characters then make sure you specify them as &lt;strong&gt;requestPathInvalidCharacters=&amp;quot;&amp;amp;lt;,&amp;amp;gt;,*,%,:,&amp;amp;amp;,\&amp;quot;&lt;/strong&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Santosh-Achanta/Dates/2012/11/Issue-with-browsing-files-in-browser-having-special-characters-in-file-name-and-fix/</guid>            <pubDate>Thu, 22 Nov 2012 02:33:07 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>