Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, March 17, 2016

WCF Services : System.ServiceModel(serviceBehaviors and bindings) settings for Http and Https.

Goal

When a WCF service is converted from HTTP to HTTPS the service stops working. Here are the web.config settings. Which can fix the issue.
<!-- SERVICE MODEL -->
  <system.serviceModel>
    <behaviors>

      <serviceBehaviors>
        <!-- HTTP :  Behavior : Start -->
        <behavior name="httpBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <!-- HTTP :  Behavior : END -->
        <!-- HTTPS :  Behavior : Start -->
        <behavior name="httpsBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <useRequestHeadersForMetadataAddress />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <!-- HTTPS :  Behavior : END -->
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="httpsBinding" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"
                               minFreeMemoryPercentageToActivateService="5" />
    <bindings>
      <basicHttpBinding>
        <!-- HTTP :  Binding : Start -->
        <binding name="httpBinding" allowCookies="true" bypassProxyOnLocal="true" textEncoding="utf-8"
                 messageEncoding="Text" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None" />
        </binding>
        <!-- HTTP :  Binding : End -->

        <!-- HTTPS :  Binding : Start -->
        <binding name="httpsBinding" allowCookies="true" bypassProxyOnLocal="true" textEncoding="utf-8"
                 messageEncoding="Text" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
                 maxBufferPoolSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
        <!-- HTTPS :  Binding : End -->

      </basicHttpBinding>
    </bindings>
    <services>

      <!-- HTTP :  Service : Start -->
      <service name="Sample.Service.HttpService" behaviorConfiguration="">
        <endpoint binding="basicHttpBinding" bindingName="" bindingConfiguration="httpBinding"
                  contract="Sample.Service.Interface.IHttpService" address="" name="" />
      </service>
      <!-- HTTP :  Service : End -->

      <!-- HTTPS :  Service : Start -->
      <service name="Sample.Service.HttpsService" behaviorConfiguration="">
        <endpoint binding="basicHttpBinding" bindingName="" bindingConfiguration="httpsBinding"
                  contract="Sample.Service.Interface.IHttpsService" address="" name="" />
      </service>
      <!-- HTTPS :  Service : End -->
    </services>
  </system.serviceModel>
  <!-- SERVICE MODEL -->

Thursday, May 29, 2014

Sharepoint 2010 - Strange blog URL issue with site using Variations(Multilingual site). - REALLY WEIRD ISSUE!

Scenario/Symptoms

  • We have a site with variations. English/Spanish
  • Structure
    • Main Site > en > English Blog(Add 1 or 2 sample blogs)
    • Main Site > es > Spanish Blog(Add 1 or 2 sample blogs)
  • On the "Main Site" we added a "Content Query Web Part". Apply the below given setting.
  • Click on the link of any English blog. IT WORKS FINE!!!
  • Now click on the Spanish blog link. IT SAYS "PAGE NOT FOUND"!!!
  • Another way to get this is.
    • Go to the URL of Spanish blog site.
    • You can find the blogs on the page.
    • Click on the blog link IT SAYS "PAGE NOT FOUND"!!!.
    • Or navigate to "Administrar entradas de blog"(AllPosts.aspx). This page will show all the blogs in the list. Click on the blog link IT SAYS "PAGE NOT FOUND"!!!


Cause

We added a column to the list "Post". Now this small thing was causing the whole havoc.


Solution

There are 3 ways to
  1. Either don't add any column to list "Post". => BAD ONE
  2. Copy SharePoint Designer > Lists > Estrada De Blog and paste it there with name "Post". Don't delete the folder. Just need to duplicate and rename the folder.
  3. Read the blog => Sharepoint 2010 - Solution to blog URL issue with site using Variations(Multilingual site) to see the feature stapler solution for this issue.


Hope this helps. If you have any questions or a better solution, I am all open for it. Thanks for reading the blog.

Sharepoint 2010 - Solution to blog URL issue with site using Variations(Multilingual site).

Issue

Read this blog -> Sharepoint 2010 - Strange blog URL issue with site using Variations(Multilingual site). - REALLY WEIRD ISSUE!

Solution

  • Create a Feature Stapler.
  • Set the event scope as Scope="Site" as the feature.
  • Stapler > Element.xml.
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
        <FeatureSiteTemplateAssociation Id="edf698b1-30db-4d19-b46b-5efbb5dae9a5" TemplateName="Blog" />
    </Elements>
  • Please use the below given code as a solution for the problem.
#region System
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.Administration;
using System.IO;
using System.Linq;
#endregion

namespace FeatureStapler.VariationBlogSiteEvent
{
    /// <summary>
    /// Web Events
    /// </summary>
    public class VariationBlogSiteEvent : SPWebEventReceiver
    {
        #region Properties

        /// <summary>
        /// The site templates
        /// </summary>
        enum EnmSiteTemplate
        {
            BLOG,    //Blog Site
        }

        /// <summary>
        /// English Language
        /// </summary>
        enum EnmLangugeCode
        {
            English = 1033
        }

        #endregion

        #region Events

        /// <summary>
        /// A site was provisioned.
        /// </summary>
        public override void WebProvisioned(SPWebEventProperties properties)
        {
            base.WebProvisioned(properties);

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    //Create a web object
                    SPWeb _web = properties.Web;

                    //Check and apply the settings
                    if (_web.WebTemplate == EnmSiteTemplate.BLOG.ToString() // If the site is a blog site
                        && _web.Language != (int)EnmLangugeCode.English) // Language Selected is not english
                    {
                        // Get the Library with correct folder
                        SPFolderCollection _folderInList = _web.Folders["Lists"].SubFolders;

                        //Find a folder with "post.aspx" & "newpost.aspx"
                        SPFolder _folderBlogNonEnglish = (from _folderX in _folderInList.Cast<SPFolder>()
                                                          let _fName = _folderX.Name
                                                          let _fCount = (from _fileX in _folderX.Files.Cast<SPFile>()
                                                                 where string.Compare( _fileX.Name , "post.aspx" , true ) == 0
                                                                select _fileX).Count()
                                                          where _fCount > 0
                                                          select _folderX).FirstOrDefault();

                        //So if any folder this properties exists
                        if (_folderBlogNonEnglish != null)
                        {
                            //The folder where file is going to come
                            SPFolder _folderBlogInEnglish = _folderBlogNonEnglish.ParentFolder.SubFolders.Add("Posts");
                            _folderBlogInEnglish.SubFolders.Add("Attachments");
                            _folderBlogInEnglish.SubFolders.Add("Post");

                            //Copy the files to new folder
                            foreach (SPFile _file in _folderBlogNonEnglish.Files)
                            {
                                _file.CopyTo(string.Format("{0}/{1}/{2}", _web.Url, _folderBlogInEnglish.Url, _file.Name), true);
                                ////Add a file
                                //_folderBlogInEnglish.Files.Add(_file.Name, File.OpenRead(_file), true);

                                // Commit 
                                _folderBlogInEnglish.Update();
                            }
                        }                       
                    }

                });
            }
            catch (Exception Exc)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("VariationBlogSiteEvent", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, Exc.Message, Exc.StackTrace);
            }
        }

        #endregion

    }
}



Hope this helps. If you have any questions or a better solution, I am all open for it. Thanks for reading the blog.

Thursday, September 20, 2012

Override Content Query Webpart to do on the run filteration.

Problem

In one of my recent project I had a challenge of filtering the data with localization.
The project contained 2 languages, English and Spanish. I was trying to find out the out of the box way to get this done, but no help was available.


Solution

  1. Create a new empty project in Visual Studio 2010.
  2. Add a webpart to the project. "Webpart" not "Visual Web Part".
  3. Replace the Webpart class inherited and make it "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart".
  4. Please have a look at the code below. It will have on the fly list settings and field settings applied to the webpart.
  5. Build your code and deploy it. It should work.



Source Code


#region System
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
#endregion

// Create the Toolbar
namespace ToolBar.ToolBar
{
    [ToolboxItemAttribute(false)]
    public class ToolBar : Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart
    {
        #region Properties

        /// <summary>
        /// Root Site Name
        /// </summary>
        private string SiteUrl { get { return SPContext.Current.Site.RootWeb.Url; } }

        /// <summary>
        /// List Name
        /// </summary>
        private string ListName { get { return "ToolBar"; } }

        /// <summary>
        /// List of Url
        /// </summary>
        private string ListUrl
        {
            get
            {
                return string.Format("{0}/Lists/{1}/AllItems.aspx", SiteUrl, ListName);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// On Page Load
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            //On Load
            base.OnLoad(e);

            //General Settings
            this.AllowConnect = true;
            this.ShowUntargetedItems = false;
            this.AllowEdit = true;
            
            //this.FrameType = "NONE"; // TODO
            this.ChromeType = PartChromeType.None;
            this.ExportMode = WebPartExportMode.All;
            this.GroupByDirection = SortDirection.Desc;
            this.SortByDirection = SortDirection.Desc;
            
            this.ConnectionID = System.Guid.Empty;
            this.ListId = System.Guid.Empty;

            this.ViewFlag = "0";
            this.GroupingText = "GP Web Parts";
            this.Title = " Tool Bar";
            this.ContentTypeName = "Item";
            this.ItemStyle = "ToolBar";
            this.ServerTemplate = "100";
            this.GroupStyle = "DefaultHeader";
            this.WebUrl = "~sitecollection";
            this.Description = "Displays a dynamic view of content from your site.";
            this.Xsl = "<xsl:stylesheet xmlns:x=\"http://www.w3.org/2001/XMLSchema\" version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:cmswrt=\"http://schemas.microsoft.com/WebPart/v3/Publishing/runtime\" exclude-result-prefixes=\"xsl cmswrt x\" > <xsl:import href=\"/Style Library/XSL Style Sheets/Header.xsl\" /> <xsl:import href=\"/Style Library/XSL Style Sheets/ItemStyle.xsl\" /> <xsl:import href=\"/Style Library/XSL Style Sheets/ContentQueryMain.xsl\" /> </xsl:stylesheet>";
            this.SampleData = "<dsQueryResponse><Rows><Row Title=\"Item 1\" LinkUrl=\"http://Item1\" Group=\"Group Header\" __begincolumn=\"True\" __begingroup=\"True\" /><Row Title=\"Item 2\" LinkUrl=\"http://Item2\" __begincolumn=\"False\" __begingroup=\"False\" /><Row Title=\"Item 3\" LinkUrl=\"http://Item3\" __begincolumn=\"False\" __begingroup=\"False\" /></Rows></dsQueryResponse>";
            this.ParameterBindings = string.Empty;

            //Root Web
            using (SPWeb _web = SPContext.Current.Site.RootWeb)
            {
                //Assign the list to the CQWP
                SPList _listYCLToolBar = _web.GetListFromUrl(ListUrl);

                //Data mapping
                this.DataMappings = string.Format("Description:|LinkUrl:{2},TargetUrl,URL;|Title:{4},Title,Text;|NumComments:|PublishedDate:|PostCategory:|ImageUrlAltText:{0},Title,Text;|Author:|Language:{3},Language,Lookup;|ImageUrl:{1},Icon,URL;|Body:|"
                    , _listYCLToolBar.Fields["Title"].Id.ToString()
                    , "{" + _listYCLToolBar.Fields["Icon"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["TargetUrl"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Language"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Title"].Id.ToString() + "}"
                    );

                this.ListGuid = _listYCLToolBar.ID.ToString();

                this.DataMappingViewFields = string.Format("{0},URL;{1},URL;{2},Text;{3},Lookup;"
                    , "{" + _listYCLToolBar.Fields["TargetUrl"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Icon"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Title"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Language"].Id.ToString() + "}"
                    );
                
                //Filter One
                this.FilterField1 = "Language";//Custom Field to get the variation work.
                this.FilterOperator1 = FilterFieldQueryOperator.Eq;
                this.FilterValue1 = System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag;
                this.FilterType1 = "Lookup";
                this.Filter1ChainingOperator = FilterChainingOperator.Or;

                this.Filter2ChainingOperator = FilterChainingOperator.Or;

                //Sorting
                this.SortByFieldType = "DateTime";
                this.SortBy = "Created";
            }            
        }

        /// <summary>
        /// Create Child Controls
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
        }

        #endregion
    }
}



Please let me know if there is any issue with this code or you can also correct me if I am wrong.

Tuesday, June 19, 2012

WCF Services : Simplest way to create a WCF REST(Representational State Transfer) service.

Goal

To create a WCF REST(Representational State Transfer) service. The main goal is to show it in the most simplest way.

Follow the below given steps

  1. Open Visual Studio 2010.
  2. File >> New Project >> WCF >> WCF Service Application. I named it SimpleWCFService.
  3. I removed the default "IService1.cs" and "Service1.svc". Added a new "Sample.svc". This will automatically create an interface in file "ISample.cs". The structure will look like the image given below.

ISample.cs

#region System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
#endregion

namespace SimpleWCFService
{
    [ServiceContract]
    public interface ISample
    {
        /// <summary>
        /// The parameters are passed in URL expression.
        /// </summary>
        /// <param name="Param1"></param>
        /// <param name="Param2"></param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "SampleCheck/{Param1}/{Param2}")]
        string SampleCheckUrl(string Param1, string Param2);

        /// <summary>
        /// The parameters are passed as QueryString.
        /// </summary>
        /// <param name="Param1">{Param1}</param>
        /// <param name="Param2">{Param2}</param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "SampleCheck?Param1={Param1}&Param2={Param2}")]
        string SampleCheckQueryString(string Param1, string Param2);
    }
}

Sample.svc.cs

#region System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Web.Script.Serialization;
#endregion

namespace SimpleWCFService
{

    /// <summary>
    /// Simple Class
    /// </summary>
    [DataContract]
    public class SimpleClass
    {
        [DataMember]
        public string CParam1 { get; set; }

        [DataMember]
        public string CParam2 { get; set; }

        [DataMember]
        public string CMessage { get; set; }
    }


    /// <summary>
    /// The simplest way to use a WCF REST(Representational State Transfer) service
    /// </summary>
    public class Sample : ISample
    {

        /// <summary>
        /// The parameters are passed in URL expression.
        /// </summary>
        /// <param name="Param1"></param>
        /// <param name="Param2"></param>
        /// <returns></returns>
        public string SampleCheckUrl(string Param1, string Param2)
        {
            JavaScriptSerializer _jScript = new JavaScriptSerializer();
            SimpleClass _simple = new SimpleClass()
            {
                CParam1 = Param1,
                CParam2 = Param2,
                CMessage = "Success with SampleCheckUrl(int Param1, string Param2)!"
            };
            return _jScript.Serialize(_simple);            
        }

        /// <summary>
        /// The parameters are passed as QueryString.
        /// </summary>
        /// <param name="Param1"></param>
        /// <param name="Param2"></param>
        /// <returns></returns>
        public string SampleCheckQueryString(string Param1, string Param2)
        {
            JavaScriptSerializer _jScript = new JavaScriptSerializer();
            SimpleClass _simple = new SimpleClass()
            {
                CParam1 = Param1,
                CParam2 = Param2,
                CMessage = "Success with SampleCheckQueryString(int Param1, string Param2)!"
            };
            return _jScript.Serialize(_simple);
        }
    }
}

Web.config - MOST IMPORTANT

<?xml version="1.0"?>
<configuration> 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SimpleWCFServiceBC">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restBehaviour">
          <webHttp automaticFormatSelectionEnabled="true" helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="RestBinding" />
      </webHttpBinding>
      <basicHttpBinding>

      </basicHttpBinding>
    </bindings>
    <services>
      <service name="SimpleWCFService.Sample" behaviorConfiguration="SimpleWCFServiceBC">
        <endpoint address="" binding="basicHttpBinding" contract="SimpleWCFService.ISample"></endpoint>
        <endpoint address="rest" binding="webHttpBinding" behaviorConfiguration="restBehaviour" bindingConfiguration="RestBinding" contract="SimpleWCFService.ISample"></endpoint>
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>
  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

Checking REST Service - URL FORMAT

Navigate to the below given url(Note:Replace the port number.).
"http://{LOCALHOST:PORTNUMBER}/Sample.svc/rest/SampleCheck/Args1/Args2".
This should give the result in below given format.
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"CParam1":"Args1","CParam2":"Args2","CMessage":"Success with SampleCheckUrl(int Param1, string Param2)!"}</string> 

Checking REST Service - QueryString

Navigate to the below given url(Note:Replace the port number.).
"http://{LOCALHOST:PORTNUMBER/Sample.svc/rest/SampleCheck?Param1=Args1&Param2=Args2".
This should give the result in below given format.
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"CParam1":"Args1","CParam2":"Args2","CMessage":"Success with SampleCheckQueryString(int Param1, string Param2)!"}</string> 


I spent a lot of time trying to figure this out so writing this up for the ones who just want solutions. Let me know if this helped.

Friday, May 18, 2012

Apply "Multiple" column Group By on DataTable in C#

Goal

A few days ago a reader asked for Multiple column group by on DataTable. This blos is in reply of that question. This was my old blog Apply group by clause on Datatable in C#.

Solution

#region System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
#endregion

namespace SampleApplication
{
    #region Enums

    /// <summary>
    /// The functions which can be used for aggreation
    /// </summary>
    public enum AggregateFunction
    {
        Sum,
        Avg,
        Count,
        Max,
        Min
    }

    #endregion

    #region Entity

    /// <summary>
    /// The class which will have properties of function to be performed and on which field
    /// </summary>
    public class DataTableAggregateFunction
    {
        /// <summary>
        /// The function to be performed
        /// </summary>
        public AggregateFunction enmFunction { get; set; }

        /// <summary>
        /// Performed for which column
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// What should be the name after output
        /// </summary>
        public string OutPutColumnName { get; set; }
    }

    #endregion
    

    public class Helper
    {
        /// <summary>
        /// Demo for Group By
        /// </summary>
        public void DemoGroupBy()
        { 
            //Gets the mock data table
            DataTable _dt = GetDataTable();

            //Add columns which you want to group by
            IList<string> _groupByColumnNames = new List<string>();
            _groupByColumnNames.Add("State");
            _groupByColumnNames.Add("City");

            //Functions you want to perform on which fields
            IList<DataTableAggregateFunction> _fieldsForCalculation = new List<DataTableAggregateFunction>();
            _fieldsForCalculation.Add(new DataTableAggregateFunction() { enmFunction = AggregateFunction.Avg, ColumnName = "Population", OutPutColumnName = "PopulationAvg" });
            _fieldsForCalculation.Add(new DataTableAggregateFunction() { enmFunction = AggregateFunction.Sum, ColumnName = "Population", OutPutColumnName = "PopulationSum" });
            _fieldsForCalculation.Add(new DataTableAggregateFunction() { enmFunction = AggregateFunction.Count, ColumnName = "Population", OutPutColumnName = "PopulationCount" });
            _fieldsForCalculation.Add(new DataTableAggregateFunction() { enmFunction = AggregateFunction.Max, ColumnName = "Year", OutPutColumnName = "YearMax" });
            _fieldsForCalculation.Add(new DataTableAggregateFunction() { enmFunction = AggregateFunction.Min, ColumnName = "Year", OutPutColumnName = "YearMin" });

            //Gets the result after grouping by
            DataTable dtGroupedBy = GetGroupedBy(_dt, _groupByColumnNames, _fieldsForCalculation);
        }


        /// <summary>
        /// Returns a mock data table
        /// </summary>
        /// <returns></returns>
        private DataTable GetDataTable()
        {
            //Declarations
            DataTable _dt = new DataTable();
            DataRow _dr;
            
            //Create columns
            _dt.Columns.Add(new DataColumn() { ColumnName = "State" });
            _dt.Columns.Add(new DataColumn() { ColumnName = "City" });
            _dt.Columns.Add(new DataColumn() { ColumnName = "Year", DataType = typeof(System.Int32) });
            _dt.Columns.Add(new DataColumn() { ColumnName = "Population", DataType = typeof(System.Int32) });

            //Add mock data
            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Ahmedabad"; _dr["Year"] = 2009; _dr["Population"] = 6000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Surat"; _dr["Year"] = 2009; _dr["Population"] = 2000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Rajkot"; _dr["Year"] = 2009; _dr["Population"] = 1000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Maharastra"; _dr["City"] = "Mumbai"; _dr["Year"] = 2009; _dr["Population"] = 3000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Maharastra"; _dr["City"] = "Pune"; _dr["Year"] = 2009; _dr["Population"] = 3000000; _dt.Rows.Add(_dr);

            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Ahmedabad"; _dr["Year"] = 2010; _dr["Population"] = 8000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Maharastra"; _dr["City"] = "Mumbai"; _dr["Year"] = 2010; _dr["Population"] = 8000000; _dt.Rows.Add(_dr);

            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Ahmedabad"; _dr["Year"] = 2011; _dr["Population"] = 6000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Surat"; _dr["Year"] = 2011; _dr["Population"] = 2000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Gujarat"; _dr["City"] = "Rajkot"; _dr["Year"] = 2011; _dr["Population"] = 1000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Maharastra"; _dr["City"] = "Mumbai"; _dr["Year"] = 2011; _dr["Population"] = 3000000; _dt.Rows.Add(_dr);
            _dr = _dt.NewRow(); _dr["State"] = "Maharastra"; _dr["City"] = "Pune"; _dr["Year"] = 2011; _dr["Population"] = 3000000; _dt.Rows.Add(_dr);

            //Return table
            return _dt;
        }

        /// <summary>
        /// Group by DataTable
        /// </summary>
        /// <param name="_dtSource"></param>
        /// <param name="_groupByColumnNames"></param>
        /// <param name="_fieldsForCalculation"></param>
        /// <returns></returns>
        private DataTable GetGroupedBy(DataTable _dtSource, IList<string> _groupByColumnNames, IList<DataTableAggregateFunction> _fieldsForCalculation)
        {
            
            //Once the columns are added find the distinct rows and group it bu the numbet
            DataTable _dtReturn = _dtSource.DefaultView.ToTable(true, _groupByColumnNames.ToArray());

            //The column names in data table
            foreach (DataTableAggregateFunction _calculatedField in _fieldsForCalculation)
            {
                _dtReturn.Columns.Add(_calculatedField.OutPutColumnName);
            }

            //Gets the collection and send it back
            for (int i = 0; i < _dtReturn.Rows.Count; i = i + 1)
            {
                #region Gets the filter string
                string _filterString = string.Empty;
                for (int j = 0; j < _groupByColumnNames.Count; j = j + 1)
                {
                    if (j > 0)
                    {
                        _filterString += " AND ";
                    }
                    if (_dtReturn.Columns[_groupByColumnNames[j]].DataType == typeof(System.Int32))
                    {
                        _filterString += _groupByColumnNames[j] + " = " + _dtReturn.Rows[i][_groupByColumnNames[j]].ToString() + "";
                    }
                    else
                    {
                        _filterString += _groupByColumnNames[j] + " = '" + _dtReturn.Rows[i][_groupByColumnNames[j]].ToString() + "'";
                    }
                }
                #endregion

                #region Compute the aggregate command

                foreach (DataTableAggregateFunction _calculatedField in _fieldsForCalculation)
                {
                    _dtReturn.Rows[i][_calculatedField.OutPutColumnName] = _dtSource.Compute(_calculatedField.enmFunction.ToString() + "(" + _calculatedField.ColumnName + ")", _filterString);
                }
                
                #endregion
            }

            return _dtReturn;
        }
    }
}


How to Use?

Call the function from somewhere.
(new SampleApplication.Helper()).DemoGroupBy();


Screenshot

Before Group By :
After Group By :


Please let me know if this helped.

Thursday, May 17, 2012

SharePoint 2010 : Placing the SharePoint:PeopleEditor icons on right instead of bottom.

Goal

The SharePoint:PeopleEditor show the icons on the right side instead of bottom.

Sample Page : ASPX

<style type="text/css">
        .ppimg{border: 0px;vertical-align: middle !important;}
    </style>
    <br /><br /><br /><br />
    <table border="0" cellpadding="10" cellspacing="5" style="border:1px solid #808080">
        <tr>
            <td colspan="2">People picker on right instead of bottom</td>
        </tr>
        <tr>
            <td>
                Default
            </td>
            <td>
                <SharePoint:PeopleEditor AllowEmpty="false" ValidatorEnabled="true" ID="ppDefault"
                    runat="server" ShowCreateButtonInActiveDirectoryAccountCreationMode="false" SelectionSet="User,SPGroup"
                    Rows="1" Width="300px" />
            </td>
        </tr>
        <tr>
            <td nowrap="nowrap">
                Custom View
            </td>
            <td>
                <table>
                    <tr>
                        <td>
                            <SharePoint:PeopleEditor AllowEmpty="false" ValidatorEnabled="true" ID="ppCustom"
                                runat="server" ShowCreateButtonInActiveDirectoryAccountCreationMode="false" SelectionSet="User,SPGroup"
                                Rows="1" Width="300px" ShowButtons="false" />
                        </td>
                        <td valign="top">
                            <a id="aPPChekNames" runat="server" title="Check Name" href="javascript:">
                                <img src="/_layouts/images/checknames.png" alt="Check Names" class="ppimg" /></a>
                        </td>
                        <td valign="top">
                            <a id="aPPBrowse" runat="server" title="Browse" href="javascript:">
                                <img src="/_layouts/images/addressbook.gif" alt="Browse" class="ppimg" /></a>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>


Sample Page : Code

//Apply the Javascript to the Icons
aPPChekNames.Attributes.Add("onclick", "if(!ValidatePickerControl('" + ppCustom.ClientID + "')){ ShowValidationError(); return false;} var arg=getUplevel('" + ppCustom.ClientID + "'); var ctx='" + ppCustom.ClientID + "';EntityEditorSetWaitCursor(ctx);WebForm_DoCallback('" + ppCustom.UniqueID + "',arg,EntityEditorHandleCheckNameResult,ctx,EntityEditorHandleCheckNameError,true);return false;");
aPPBrowse.Attributes.Add("onclick", "javascript:__Dialog__" + ppCustom.ClientID + "(); return false;");


Result



I am not sure if many know about this or this is normal, but just wanted to share. Let me know if this helped.

SharePoint 2010 : Call server side function from XSL.

Goal

To use a server side function from a XSL used in a web part.

Solution

It is simple to use a server side function. Just need to make sure the dll should be deployed in GAC. In this example I created a class with name "ClassName", the project name is "SampleApplication". Deployed the dll in GAC. Modify the XSL head and add xmlns:helper="SampleApplication.ClassName" on the head. "helper" is like an tag which will point to the class.

XSL
<xsl:stylesheet 
  version="1.0" 
  exclude-result-prefixes="x d xsl msxsl cmswrt helper"
  xmlns:x="http://www.w3.org/2001/XMLSchema" 
  xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" 
  xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
  xmlns:cmswrt="http://schemas.microsoft.com/WebParts/v3/Publishing/runtime"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:helper="SampleApplication.ClassName">


SampleApplication.ClassName
#region System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion

namespace SampleApplication
{
    public class ClassName
    {
        #region Properties
        
        /// <summary>
        /// Name 
        /// </summary>
        private static string Name = "Maulik Dhorajia";
        
        /// <summary>
        /// Today Date
        /// </summary>
        private static string TodayDate = System.DateTime.Now.ToString();

        #endregion

        /// <summary>
        /// Gets the property
        /// </summary>
        /// <param name="propertyKey"></param>
        /// <returns></returns>
        public static string GetProperty(string propertyKey)
        {
            if (propertyKey == "Name")
            {
                return Name;
            }
            else if (propertyKey == "TodayDate")
            {
                return TodayDate;
            }
            else 
            {
                return "";
            }
        }
    }
}


Calling the function from XSL
<xsl:value-of select="helper:GetLabel('Name')"/>
<xsl:value-of select="helper:GetLabel('TodayDate')"/>


This should be all to show the stuff on the page. Let me know if this helped.

Friday, April 6, 2012

SharePoint 2010 : Use Resouce(resx) file in a Multilingual site.

Goal

Our site is created using variations in both English and Spanish. Create a Visual Web Part which can use the resource file(.resx) to show different texts for different language.

Steps to achieve goal

  • Create a SharePoint project with name "Sample".
  • Add a web part with name "SampleWebPart".
  • Add a "Mapped Folder" to "Resources". 2 files needs to be added.
    1. SampleWebPart.en-US.resx - English version resource file. Add some text to the resource.
    2. SampleWebPart.es-ES.resx - Spanish version resource file. Add some text to the resource.
  • At this point the project "Solution Explorer" will look like
  • For applying the resource, Open the Feature1 properties. And make the 2 changes shown in the below given image.
  • Use the HTML and C# Code below.
  • Once the above given steps are done, deploy the web part and They will display as below given image.


HTML - SampleWebPartUserControl.ascx

<h1><asp:Literal ID="ltrlTitle" runat="server" /></h1>
<hr />
<h3>
    <asp:Literal ID="ltrlDescription" runat="server" />
</h3>


C# - SampleWebPartUserControl.ascx.cs

#region System
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
#endregion

namespace Sample.SampleWebPart
{
    /// <summary>
    /// Simple example to use Resouce file with English/Spanish language.
    /// </summary>
    public partial class SampleWebPartUserControl : UserControl
    {
        #region Events

        /// <summary>
        /// Page Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            ltrlTitle.Text = LoadResource( ResourceName.Title );
            ltrlDescription.Text = LoadResource(ResourceName.Description);
        }

        #endregion

        #region Resource Reader

        /// <summary>
        /// Name for the Version to be considered.
        /// NOTE :- Use exactly same "Name" as used in Resource(resx) file.
        /// </summary>
        public enum ResourceName
        { 
            Title,
            Description
        }

        /// <summary>
        /// Gets the text on the basis of "Name" in Resource(resx).
        /// </summary>
        private string LoadResource(ResourceName _resName)
        {
            return Microsoft.SharePoint.Utilities.SPUtility.GetLocalizedString("$Resources:" + _resName.ToString(),
                "SampleWebPart"
            , (uint)System.Globalization.CultureInfo.CurrentUICulture.LCID); 
        }

        #endregion
    }
}


Happy Coding

Saturday, March 3, 2012

SharePoint 2010 Error Solution : A Web Part or Web Form Control on this Page cannot be displayed or imported. The type could not be found or it is not registered as safe.

Introduction

An occours when a user tries to add a webpart on the page. The description of the error is "A Web Part or Web Form Control on this Page cannot be displayed or imported. The type could not be found or it is not registered as safe.".


Test Cases

Here, I am creating a small solution to show why I got this issue.
  1. Open Visual Studio 2010. Create a project with name "Sample".
  2. Add a WebPart to the project with name "SomeWebPart"(Note : Mind it WebPart not VisualWebPart).
  3. Add a class library to the solution with name "Helper".
  4. Add a "Helper.snk" to the project by Right Clicking "Helper" > Properties > Signing > Choose a strong name...
  5. Once that is done the structure will look like image given below
  6. Helper.Enums Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Helper
    {
        public class Enums
        {
            public enum SomeType
            {
                A = 0,
                B = 1,
                C = 2
            }
        }
    }
    
  7. SomeWebPart.cs Code
    using System;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    
    namespace Sample.SomeWebPart
    {
        [ToolboxItemAttribute(false)]
        public class SomeWebPart : WebPart
        {
            /// <summary>
            /// The enum which resides in enum
            /// </summary>
            public Helper.Enums.SomeType SomeTypeEnum { get; set; }
    
            /// <summary>
            /// Create child control
            /// </summary>
            protected override void CreateChildControls()
            {
    
            }       
            
        }
    }
  8. Deploy to the site. Try adding the WebPart and it will give the above mentioned error.


Problem

The problem is "Sample.dll" created for the WebPart gets added to the wsp and gets added to GAC automatically but the "Helper.dll" is not considered as a safe one and it stays out of GAC and so while adding the WebPart, it blows and the error shows on the alert window.

Solution

  1. Sample > Package > Open "Package.package"
  2. At the bottom you will find an option title "Advanced".
  3. As shown in the image select "Add Assembly from Project Output...".
  4. In the dialog select "Helper" will auto populate the Helper details.
  5. Safe Controls section add a new item.
  6. Fill the Namespace and Assembly with name "Helper".
  7. Click "OK" and exit the dialog. You can see the settings of Helper added on the Advanced screen.
  8. Deploy the WebPart and try adding it again. It should work.


Hope this helped!

SharePoint 2010 : Remove a WebPart from Page programmatically using C#.

Goal

To remove webparts from a page programmatically using C#.

Code

/// <summary>
/// This function will remove web parts with title passed
/// </summary>
/// <param name="_web">Web object</param>
/// <param name="_pageUrl">The url of the page on which the web part exists.</param>
/// <param name="_title">The title of the Web part</param>
private void RemoveWebPart(SPWeb _web, string _pageUrl, string _webPartTitle)
{
    //Remove the control once the page is copied
    Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager _webPartCollection = _web.GetLimitedWebPartManager(_pageUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    //Retrive the webpart and remove
    IList<Microsoft.SharePoint.WebPartPages.WebPart> _listFormWebParts = (from _wp in _webPartCollection.WebParts.Cast<Microsoft.SharePoint.WebPartPages.WebPart>()
                                                                            where string.Compare( _wp.Title , _webPartTitle  , true ) == 0
                                                                            select _wp).ToList();

    //Check if there are any web parts found
    if (_listFormWebParts != null)
    {
        foreach (Microsoft.SharePoint.WebPartPages.WebPart _listFormWebPart in _listFormWebParts)
        {
            //Remove the webpart
            _webPartCollection.DeleteWebPart(_listFormWebPart);

            //Update
            _web.Update();
        }
    }
}


Tip

Suppose we dont want to remove the webpart using "Title" we want to remove the webpart with type.
//Retrive the webpart and remove
IList<Microsoft.SharePoint.WebPartPages.WebPart> _listFormWebParts = (from _wp in _webPartCollection.WebParts.Cast<Microsoft.SharePoint.WebPartPages.WebPart>()
                                                                        where _wp.GetType() == typeof(Microsoft.SharePoint.WebPartPages.ListFormWebPart)
                                                                        select _wp).ToList();

Thursday, January 19, 2012

SharePoint 2010 - Update user's infomation using UserProfileManager programmatically.

Goal

To update a user's information using C#. In the below given sample i am changing the Email(WorkEmail) of a user.

Important facts

  • User trying to update a profile should be updating own record or should be an "Admin in User Profile Service". If the user is not an Admin in User Profile Service the error will come "You must have manage user profiles administrator rights to use administrator mode.".
  • In below given code I am using true for IgnoreUserPrivacy. Default it should be false but i also wanted to make this work.
    UserProfileManager(SPServiceContext.Current , true)
  • Most Important : The user i am using to run this is an Admin in User Profile Service. So the code is working fine.

Code

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite _site = new SPSite(SPContext.Current.Site.Url))
    {
        using (SPWeb _web = _site.OpenWeb())
        {
            //Gets the profile manager object
            UserProfileManager _profileManager = new UserProfileManager(SPServiceContext.Current , true);
                           
            //UserName
            string _userName = @"MyMachine\User";

            //Gets the profile of a User
            UserProfile _userProfile = _profileManager.GetUserProfile(_userName);
            if (_userProfile != null)
            {
                //Change the Email value
                ((UserProfileValueCollection)_userProfile["WorkEmail"]).Value = "sample@someDomain.com";
                               
                //Save the record
                _userProfile.Commit();
                               
            }
        }
    }
});

This code works absolutely fine. For the developers who are getting issue like "You must have manage user profiles administrator rights to use administrator mode." please click the error to visit the solution.

Friday, January 13, 2012

SharePoint 2010 - Custom Toolpart properties for CQWP.

Goal

Adding custom fields in the tool pane of Content Query Web Part and using them. A few days ago I was working on a project with a similar requirement. I figured out that we can extend ToolPane and add custom controls to it.

How to achieve?

  1. Create a blank SharePoint project in Microsoft Visual Studio 2010 with name "CustomContentQueryWebPart".
  2. Add a "Web Part" to the project with name "ExtendedCQWP" and not to be mistaken with "Visual Web Part".

  3. Added a class "ExtendedCQWPToolPart" for the ToolPane in a folder name "CustomToolPart". Once the classes are added the structure of the project will look like the picture given below.

  4. Use the code for "ExtendedCQWPToolPart".
    #region System
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.UI.WebControls;
    
    #endregion
    
    namespace CustomContentQueryWebPart.CustomToolPart
    {
        /// <summary>
        /// The extended tool part of Extended Content Query Web Part.
        /// Will have a DropdownList, RadioButtonList and TextBox
        /// Will use the values added in the controls as applied.
        /// </summary>
        public class ExtendedCQWPToolPart : Microsoft.SharePoint.WebPartPages.ToolPart
        {
            #region Properties
    
            /// <summary>
            /// Literal
            /// </summary>
            protected Literal Ltrl { get; set; }
    
            /// <summary>
            /// Text Box
            /// </summary>
            protected TextBox Txt { get; set; }
    
            /// <summary>
            /// Dropdownlist
            /// </summary>
            protected DropDownList Ddl { get; set; }
    
            /// <summary>
            /// Radiobutton
            /// </summary>
            protected RadioButtonList Rbtnl { get; set; }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// Constructor
            /// Applies the settings
            /// </summary>
            public ExtendedCQWPToolPart(string _ddlValue, string _rbtnValue, string _txtValue)
            {
                //Bind the ddl
                Ddl = new DropDownList();
                Ddl.Items.Insert(0, new ListItem("--- Select ---", ""));
                Ddl.Items.Insert(1, new ListItem("DDL 1"));
                Ddl.Items.Insert(2, new ListItem("DDL 2"));
                Ddl.Items.Insert(3, new ListItem("DDL 3"));
               
                //Radio Button the ddl
                Rbtnl = new RadioButtonList();
                Rbtnl.Items.Insert(0, new ListItem("RBTN 1"));
                Rbtnl.Items.Insert(1, new ListItem("RBTN 2"));
                Rbtnl.Items.Insert(2, new ListItem("RBTN 3"));
                Rbtnl.SelectedIndex = 0;
                
                //Text box
                Txt = new TextBox();
    
                //Refill the settings
                if (!string.IsNullOrEmpty(_ddlValue))
                {
                    Ddl.SelectedValue = _ddlValue;
                }
                if (!string.IsNullOrEmpty(_rbtnValue))
                {
                    Rbtnl.SelectedValue = _rbtnValue;
                }
                if (!string.IsNullOrEmpty(_txtValue))
                {
                    Txt.Text = _txtValue;
                }            
            }
    
            /// <summary>
            /// Applies the child controls
            /// </summary>
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
    
                #region Add the controls to the section
    
                //Title to the web part
                this.Title = "Extended Settings";
    
                //Add the contorls so that they show up on the screen
                Ltrl = new Literal();
                Ltrl.Text = "<b>Dropdown Selection</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Ddl);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br /><b>Radiobutton Selection</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Rbtnl);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br /><b>Textbox</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Txt);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br />";
                this.Controls.Add(Ltrl);
    
                #endregion
            }
    
            /// <summary>
            /// Fires on the OK/Save is clicked in the tool part pane
            /// </summary>
            public override void ApplyChanges()
            {
                base.ApplyChanges();
    
                //Applies the custom settings to the content query web part
                ExtendedCQWP.ExtendedCQWP _parentWebPart = (ExtendedCQWP.ExtendedCQWP)this.ParentToolPane.SelectedWebPart;
                if (_parentWebPart != null)
                {
                    //Applies the control settings
                    _parentWebPart.DdlValue = Ddl.SelectedValue;
                    _parentWebPart.RbtnlValue = Rbtnl.SelectedValue;
                    _parentWebPart.TxtValue = Txt.Text;
    
                    //Applies the settings
                    _parentWebPart.ApplyChanges();
                }
                
            }
    
            #endregion
            
        }
    }
    
  5. For "ExtendedCQWP" add a reference of Microsoft.Sharepoint.Publishing and the code is given below.

    #region System
    
    using System;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using System.Collections.Generic;
    using Microsoft.SharePoint.WebPartPages;
    
    #endregion
    
    namespace CustomContentQueryWebPart.ExtendedCQWP
    {
        /// <summary>
        /// Sample extended Content Query Web Part
        /// </summary>
        [ToolboxItemAttribute(false)]
        public class ExtendedCQWP : Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart
        {
            #region Properties
    
            /// <summary>
            /// Txt Value
            /// </summary>
            public string TxtValue { get; set; }
    
            /// <summary>
            /// Radio button Value
            /// </summary>
            public string RbtnlValue { get; set; }
    
            /// <summary>
            /// Txt Value
            /// </summary>
            public string DdlValue { get; set; }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// Create Child Controls
            /// </summary>
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
            }
    
            /// <summary>
            /// Override the get tool part
            /// </summary>
            /// <returns></returns>
            public override ToolPart[] GetToolParts()
            {
                List<ToolPart> _toolParts = new List<ToolPart>(base.GetToolParts());
                _toolParts.Insert(0, new CustomToolPart.ExtendedCQWPToolPart(DdlValue, RbtnlValue, TxtValue));
                return _toolParts.ToArray();
            }
    
            /// <summary>
            /// Applies the changes
            /// </summary>
            public void ApplyChanges()
            {
                this.Title = string.Format("DDL : {0}, Rbtn : {1}, Txt : {2}", DdlValue, RbtnlValue, TxtValue);
            }
    
            #endregion
        }
    }
    
  6. I renamed the title in element.xml so the web part show with title "Custom Content Query Web Part".
  7. Edit the newly added webpart.

    /li>
  8. The right side of the tool pane will show like the below given picture. Make the modification as you want.



  9. On applying or saving the settings my code will set the title concatenating all the 3 values.


This was the simplest way of showing how to add the custom parameters in the tool pane. We can do many more things with it not just setting the title. You can also go through one of my old blog Override Content Query Webpart to do on the run filteration to get an idea of what else can be done with extending the classes.
Hope the blog helped you, please comment if you have any queries. I will be very much happy to answer them.