ASP Classic Connection String Romance

New job and brand new works is giving me new things to learn. Currently I am staying with ASP again! This time it is not ASP.net but ASP classic.


New job and brand new works is giving me new things to learn. Currently I am staying with ASP again! This time it is not ASP.net but ASP classic. Continue reading “ASP Classic Connection String Romance”

Sitecore – Shortening URL (for Your SEO Sake)


Hello, all! Tonight seems like the time for me to unleash what I have discovered during my time of blogging-hibernation. Earlier, I talked about WURFL and sitecore’s default way to detect device, now I talk about the way to shorten URL in Sitecore. This way bug me off and I left my question in stackoverflow left unanswered.

I am really aware that there is a default way for Sitecore to perform such task. What I found is my URL is really long and my boss is quite angry for it mess the SEO. Below is the default way.

UrlOptions opt = (UrlOptions)UrlOptions.DefaultOptions.Clone();
opt.SiteResolving = Sitecore.Configuration.Settings.Rendering.SiteResolving;
linkToResep.NavigateUrl = LinkManager.GetItemUrl(citem, opt);

Now, as you see, you need to configure the config too. So that it will shorten the URL as you wish. You can look on my question for detail.

I got various answers from kind people in my question, but, I still having trouble in it. So I am enlightened when my boss said that in PHP we can regex match something. Well, yeah! I will use regex to remove those long link!

As default we know that Sitecore LinkManager will produce a long link that contains /sitecore/content/sites/yoursite/ to access your items. Well, it seem so suck to the SEO. Then we should remove it. Below is how.

  1. Create a link using Sitecore.Links.LinkManager.GetItemURL(myItem). The output will be used as a parameter to my method that will shorten the url.
  2. Create a method that will receive a link and will shorten it for sure. I suggest you to create a helper class that will contain all functions and helpful methods that you need in many classes.
    public static string ShortenURL(string URLToShorten)
    {
        return Regex.Replace(URLToShorten,@"sitecore/content/sites/[\w]{1,}/","");
    }
    
  3. The call will be like below.
    yourHyperLinkObject.NavigateUrl = your.helper.ShortenURL(Sitecore.Links.LinkManager.GetItemURL(myItem));
    

Well, I tested it already, and thank you to the regexpal that ease my testing.

Wait, wait, wait, wait. Hold on! That easy? Yes. Why I didn’t find it out so quickly? Well, people, I didn’t think out of the box. I was when I found this out through my boss’ words about PHP. Okay, problem solved? Not yet! Look on the title, for your SEO sake. We just shorten the URL and not finished optimizing the SEO.

If you are Sitecore developer, then you must have known that you can access your site using both yourdomain.com/sitecore/content/sites/yoursitename/youritemname and yourdomain.com/youritemname. Okay, you knew it already, then what about it. As soon as I can shorten the URL, my boss feel relieved, and he asked whether the old long link still accessible or not. I said, yes. He panicked!

What must I do, first, you need to add canonical to your site tag. The canonical will contains the long link. Second, if you must, you need to put a redirection whenever someone is trying to access the long link to the correct short link.

Using this, well, your SEO is getting better and not screwed up a lot. I hope this is useful to you all folks! Please feel free to comment 🙂

Sitecore – WURFL or Sitecore Device Default Detection


Hi all! I return from my long blogging-hibernation. Lately, I encounter a little problem with mobile detection in Sitecore. Before that, yes, I am still working on the website of my company’s client and yes, though I really tired of this Sitecore stuffs, I still feel so curious about it. I hope through this post, you can find the best way to choose for your Sitecore site in detecting device.

As we know, WURFL is a powerful tool that makes your web page suit the device that opens it. We also know that Sitecore is powerful enough to let the developers set a different look and feel for a different device. I thanked so much to my client for they have provided us, the developers a good-customized-WURFL-system. Our client, that is mainly based in the continent far away customized the 51Degree to suit their needs. I don’t want to write how to do such because greater people than me have written about it in their blog (example: the great mentor – at least for me – Alex’s blog.)

Then using the module that our client have made, we can differentiate the site look and feel on various devices. Well, for now, we just differ between mobile, tablet, and our beloved big screen computer. Well, it works just great. Our client make a fine module and I like it! Well, somehow there is a problem, what if the device have a different user agent and that user agent is not registered, yet? Also the update can be automatically done.

In contrast, you know that most of the devices have a common thing in their user agent. Really? What is it? For example, there will be words like “mobile”, “Blackberry”, “Android”, “iP”, etc. You can add the devices and don’t have to write a module like what my client have done. It can detect automatically, and easily. Really? Yes. So, I tried this, too! The result is just great! Fine and really nice. The goodness is that you can detect most of devices easily because they “must have something in common” on their user agent. What’s the disadvantage? If you add a new device, well, be sure to update all of the items in your Sitecore, which can be so many even though you only update the default value of the template.

In the last two paragraphs, it shows like I am telling you that Sitecore default device detection using user agent is a classic way that cost us more effort than using the WURFL way to detect device. Well, I’m afraid I have to say that is true. Since 51Degree offers a free lite package to use, we can just create a module that will need to be updated once or twice for a long time. We don’t have to really create a new device and trouble us with all the task to assign the layouts and sub-layouts to our Sitecore items.

Well, it is up to you to choose. But I am sure there are more things to consider than just what I wrote in here. Be free to comment.

May, 29 2013 update:
For some reason, the device detection system on my local is having problem. Sometimes it works out, sometimes it don’t. I tried to check the values of IsMobile and width (these two rules are those who are used in detecting mobile device in my project). It shows values that match the rule, but somehow it keeps showing the default layout setting from Sitecore. Will update on the way to prevent it.

Orchard – Piedone Avatar Double Extension Threat


So, I was still developing for a site that using Orchard CMS. I finally get into security testing. Well, that’s a lot of effort to do. 😀

But what I got is that there is double extension threat to my application. At first, I manage to fix it through Media module on Orchard. Then I think it was already safe and clear. I am patiently waiting for the result. What I got is the opposite. The threat still shows up. And it brings me to one conclusion: the problem is in the Piedone Avatar (the current module that I use for avatars in my site).

As usual, I debug the application first, put breakpoints here and there. Searching for the suitable location and looking for the steps. I got the way and I put some modification. The modification that I made is on the IAvatarsService interface , AvatarsServiceExtension class, and AvatarsService (for I have made a modification on the interface).

Here is the added code:

IAvatarsService

...

/// <summary>
/// Saves an avatar file
/// </summary>
/// <param name="id">Id of the content item (user) to attach the file to</param>
/// <param name="stream">The content of the file</param>
/// <param name="extension">The extension of the file</param>
/// <param name="filename">The name of the file (for double extension checking)</param>
/// <returns>True or false indicating success or failure</returns>
bool SaveAvatarFile(int id, Stream stream, string extension, string filename);

...

AvatarsServiceExtension

...

/// <summary>
/// Saves an avatar file
/// </summary>
/// <param name="id">Id of the content item (user) to attach the file to</param>
/// <param name="postedFile">A posted image file</param>
/// <returns>True or false indicating success or failure</returns>
public static bool SaveAvatarFile(this IAvatarsService service, int id, HttpPostedFileBase postedFile)
{
    return service.SaveAvatarFile(id, postedFile.InputStream, Path.GetExtension(postedFile.FileName), postedFile.FileName);
    // I add postedFile.FileName so that it will check the extension first.
}

...

AvatarService

        ...

        public bool SaveAvatarFile(int id, Stream stream, string extension, string filename)
        {
            ...

            if (containsHarmfulDoubleExtension(filename) || !IsFileAllowed(filePath))
            {
                ValidationDictionary.AddError(AvatarsServiceValidationKey.NotAllowedFileType, T("This file type is not allowed as an avatar."));

                return false;
            }

            ...
        }

        /// <summary>
        /// To check whether it have a double extension (and harmful) or not.
        /// Leave the file be like it is if there is a double extension if not harmful
        /// </summary>
        /// <param name="filename">name of the file</param>
        /// <returns>true if contains</returns>
        public bool containsHarmfulDoubleExtension(string filename)
        {
            string harmfulExtensions = "exe php cs ascx cshtml html obj class java bat deb vb vbe reg php3 php4 php5";

            bool hasil = false;
            List<string> splittedFileName = filename.Split('.').ToList<string>();
            if (splittedFileName.Count == 2)
                return false;
            else
            {
                // more dots are found.
                splittedFileName.RemoveAt(0); // remove the first element (considered as a name)
                foreach (string singleBlast in splittedFileName)
                {
                    hasil = harmfulExtensions.ToUpperInvariant().Contains(singleBlast.ToUpperInvariant());
                    if (hasil == true)
                        break;
                }
            }

            return hasil;
        }

        ...

If there is any suggestion you may add or repair on my code, well, please be kind 🙂

.NET – Linq, foreach, and eyesore


Hello all!

I was building an asp site. So, I got into a feature that I can use either linq and foreach. What is about the eyesore? You’ll get it later.

Well, the feature that I wanted to make is to filter a list based on a criteria. Let’s just say that I had a big list of products. The filter would be “include item”, “exclude item”, and “I don’t care if that exist”. The filter was based on the product’s category.

First, I created a function that would receive all of the products. From that list, I created a smaller list that only contained all included items. I used linq to include them all! Simple and cost me a small amount of LOC. Then from that all included products, I removed all those that doesn’t included inside it.

Well, for once or twice it works fine. All sorted well. Then I met a process when I tested my small function. I tried to exclude all. What I got when I’m using linq is error. Error, error everywhere! Exceptions, exceptions everywhere! Of course I didn’t manage to catch it through. Why should I? I was testing, I wanted to know the location of possible exceptions first.

Well, that error confused me. Why? Even though I wrote linq in multiple lines, it treated as one error. Plus, I had to read a long linq statement – yes, it was so damn long about three lines with full width on screen. It gives me sore eyes! Hell! I read through out the error message, then linq, and repeat, and poof! I surrender.

Then I decided to take the linq that exclude the products into a foreach. Pheeew! I feel so glad when I can track the bug easily. What I got is the list got emptied by the time is still searching on the list. Or, some index were skipped just like that because I remove the element. Whoa! I realized that I was making a huge mistake there.

So, in the end, I created a temporary list that contains the same element as the included items list. But I was not just assign it and done. First I instantiate an empty temporary list, then I add all included items into it. Later on, I use foreach to search on the included items, but I delete the item on the temporary list.

It sounds so complex, why do I have to use foreach then a temporary list for such simple job? Why not includedList.RemoveAll(criteria)?

Because I need a good way to track things down. Also, I consider a good way to extend it in the future, so the method may be used by other class. Simple and easy to manage, debug, but cost more LOC, that’s using foreach. Well, you may say even more memories and more time. But using linq, it is hard to track things down.

I still recommend you to use linq anyway, it is a great way to get things done, but when you stuck up, use my suggestion and way then 🙂

I’ll post the code at about 12.00(GMT+7) so you could see the difference. Happy coding!

LINQ:

productList.RemoveAll(o => o.Fields["Category"].Value.Contains(criteria));
// it's just a short code, yes, but that criteria went so long and contains private data, I can't post it here.

using foreach:

productList = RemoveFromList(filter, productList);

private List<Item> RemoveFromList(string filter, List<Item> list)
{
    List<Item> temp = new List<Item>();
    temp.AddRange(list); // the temporary list
    foreach (Item single in list) // I loop on the main list
    {
        foreach (Item child in single.Children)
        {
            if (!child.Name.StartsWith("xxx") && !child.Name.StartsWith("yyy")) // sorting criteria
            {
                temp.Remove(single);
            }
        }
    }
    return temp;
}