Friday, August 17, 2012

Splitting key-value string using LINQ

Time has come to get down-and-dirty with LINQ! For an app i'm building, i need to store an array of key/value pairs in a single string. It consists of an ID and a folder path, which are separated by use of a semicolon delimiter. The actual pairs are then separated using a pipe. Here is an example:



string folders = @"32;c:\|48;c:\code|52;c:\program files|";

I created the following method that returns a Dictionary object:



        public static Dictionary<int, string> GetFolders(string folders)
        {
            string[] x = folders.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); // first retrieve a string array of all the pairs

            return x.ToDictionary(y => Convert.ToInt32(y.Split(';')[0]), y => y.Split(';')[1]); // second stage of splitting
        }

Here's a full working console example:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string folders = @"30;c:\|48;c:\code|99;c:\Program Files";
            Dictionary<int, string> KeyValuePairs = GetFolders(folders);
            foreach (KeyValuePair<int, string> pair in KeyValuePairs)
            {
                Console.WriteLine("Key: '" + pair.Key + "', Value: '" + pair.Value + "'");
            }
            Console.ReadKey();

            /* Results:
             * 
             * Key: '30', Value: 'c:\'
             * Key: '48', Value: 'c:\code'
             * Key: '99', Value: 'c:\Program Files'
            */
        }

        public static Dictionary<int, string> GetFolders(string folders)
        {
            string[] x = folders.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); // first retrieve a string array of all the pairs

            return x.ToDictionary(y => Convert.ToInt32(y.Split(';')[0]), y => y.Split(';')[1]); // second stage of splitting
        }
    }
}

Wednesday, August 8, 2012

Convert enum to string and vice versa



            Vehicle myPreference = Vehicle.Bicycle;
            string vehicle = myPreference.ToString(); // returns string with value: "Bicycle"

            Vehicle secondChoice = (Vehicle)Enum.Parse(typeof(Vehicle), "Spaceship", true); // returns enum: Vehicle.Spaceship

Wednesday, June 20, 2012

Securing SharePoint lists by code

Rather than stuffing configuration keys into *.CONFIG files, it's more convenient to use SharePoint lists instead. This makes it easier to alter configuration settings, as for each change we would need to deploy a new .CONFIG file and involve SysAdmins, get approval from the management, et cetera.

But obviously, you do not want all users to have access to these, if you will, configuration lists. Manually setting all permissions per list and user group would be a nag. Therefore, I'm doing this by code, using the feature event receiver. I basically fetch the SPLists required, break the inheritance and re-set the permissions. The 'userGroup' variable holds the name of the user group associated with the feature. Same goes for the 'prefixList' variable.



public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            const string userGroup = "TeamGary";
            const string prefixList = "config.";

            using (SPSite site = (SPSite)properties.Feature.Parent)
            {
                using (SPWeb web = site.OpenWeb())
                {
                    List<string> fdtListTitles = new List<string>();

                    // get all feature-related SPList titles
                    foreach (SPList list in web.Lists)
                    {
                        if (list.Title.Substring(0, 7) == prefixList)
                        {
                            web.AllowUnsafeUpdates = true;

                            // break inheritance from parent
                            list.BreakRoleInheritance(false);

                            // remove all permissions from list, except for userGroup
                            SPGroupCollection groupCollection = list.ParentWeb.SiteGroups;
                            SPGroup group = groupCollection[userGroup];
                            SPRoleDefinitionCollection roleDefCollection = list.ParentWeb.RoleDefinitions;
                            SPRoleDefinition roleDefinition = roleDefCollection["Read"]; // set access level here
                            SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)group);

                            roleAssignment.RoleDefinitionBindings.Add(roleDefinition);

                            list.RoleAssignments.Add(roleAssignment);

                            list.Update();
                        }
                    }
                }
            }
        }

Friday, May 11, 2012

How to block the execution thread using RadConfirm

Finally found a way to use the RadConfirm popup, which is invoked from client side, in combination with server side events. Following example will display the confirmation window and only continues to call the button click event IF the OK button is clicked by the user.


ASPX:


<telerik:RadWindowManager ID="RadWindowManager1" runat="server" EnableShadow="true">
</telerik:RadWindowManager>

<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
    <script type="text/javascript">

        var lastClickedItem = null;
        var clickCalledAfterRadprompt = false;
        var clickCalledAfterRadconfirm = false;

        function onClientButtonClicking(sender, args) {
            if (args.get_item().get_text() == "Order another beer") {
                if (!clickCalledAfterRadconfirm) {
                    args.set_cancel(true);
                    lastClickedItem = args.get_item();
                    radconfirm("Are you sure? You order it, you finish it!", confirmCallbackFunction);
                }
            }
        }

        function confirmCallbackFunction(args) {
            if (args) {
                clickCalledAfterRadconfirm = true;
                lastClickedItem.click();
            }
            else
            clickCalledAfterRadconfirm = false;
            lastClickedItem = null;
        }  

    </script>
</telerik:RadCodeBlock>

<CommandItemTemplate>
    <telerik:RadToolBar ID="RadToolBar1" runat="server" OnClientButtonClicking="onClientButtonClicking" OnButtonClick="RadToolBar1_ButtonClick" Width="100%">
        <CollapseAnimation Duration="200" Type="OutQuint" /> 
            <Items> 
                <telerik:RadToolBarButton CommandName="OrderBeer" runat="server" Text="Order another beer"></telerik:RadToolBarButton> 
            </Items> 
    </telerik:RadToolBar>
</CommandItemTemplate>

The CommandItemTemplate part you obviously need to add to your MasterTableView element..



CS:



protected void RadToolBar1_ButtonClick(object sender, RadToolBarEventArgs e)
    {
        RadToolBarButton button = e.Item as RadToolBarButton;
        if (button.CommandName == "OrderBeer")
        {
            \\Do stuff, drink the beer
            \\DrinkBeer();
        }
    }

Have a nice weekend folks!!!


Tuesday, April 10, 2012

Serverside RowClick event handling for RadGrid

Here are a few steps to handle an event on the server side for Telerik's RadGrid

1. Add attribute OnItemCommand to <Telerik:RadGrid>, for example "OnItemCommand="radGrid1_ItemCommand" if your grid name is radGrad1
2. Add attribute EnablePostBackOnRowClick="true" to <ClientSettings>
3. To your code behind, add the following, which will assign a specific cell value to a string:

protected void radGrid1_ItemCommand
{
    // this block will take the value of the column "ContactName" from the grid and assign it to a string
    if (e.CommandName == "RowClick")
    {
        int index = e.Item.ItemIndex;
        GridDataItem item = (GridDataItem)radGrid1.Items[index];
        string contactName = item["ContactName"].Text;
    }
}

Friday, March 9, 2012

Registering Telerik.Web.UI when used in a webpart

Quick post about another problem I stumbled across. My team decided to proceed using Telerik controls for our webparts. I ran the .msi and installing went just fine.

Also in VS, I immediately noticed the extended Toolbox with all the awesome new controls so I wanted to horse around with the RadGrid to see how it works.

So I created a new webpart in my project and drag-n-dropped the RadGrid control onto the web user controls. It added the following two lines of code:



And added the related assembly to the bin folder of my project and a reference.



But then BOOM! Big fat ass exception thrown; complaining that it cannot find the Telerik.Web.UI assembly



This is how to solve it.

First, go to your Package\Packge.package file, open it and go to Advanced (at the bottom). Next, click 'Add'->'Add existing assembly...'. Find the dll and then add a new item to the Safe Controls section, where you fill out the Namespace and the Assembly Name. Make sure that the Deployment Target is set to the GlobalAssemblyCache



Then, open the VS Command Prompt, and execute the following command line:

sn -T fullpathtoyourassembly



This wil give you the PublicKeyToken which you will use in a minute. Close the prompt and go to the folder where your dll is residing. Right-click it, choose properties -> Details and take note of the File version:


Finally, go back to the .ascx file and in the Register element, extend the Assembly attribute with the following:

<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI, Version=2011.3.1115.35, Culture=neutral, PublickKeyToken=121fae78165ba3d4" %>


That should make it work!

Enjoy ur weekend!

Namespaces and class declarations in a webpart

How it relates and stuff



Also, check out my new H+SON Formation Face wheelset I bought yesterday. BLB track hubs and fyxation tires. Still need to change my gear ratio, currently running at a lame 42 - 16