Monday, February 27, 2012

Using LINQ to order an ASP.NET DropDownList

How LINQ can you save you from writing many lines of code. Easy stuff:

protected void SortDropDownList(DropDownList ddlToSort)
{
    ddlToSort.DataSource = ddlToSort.Items.Cast<ListItem>()
                            .OrderBy(o => o.Text)
                            .ToList();
    ddlToSort.DataBind();
}

Wednesday, February 22, 2012

Passing on ViewState Items onto ObjectDataSource

Because the datasource instance does not run in your page instance, you will not be able to fetch your ViewState items. The only way to do this is to pass it on to the parameters. Suppose you've got a gridview, using an object data source instance called 'odsBand' and you would like to retrieve a DataSet from your db filtered by band name. In this case you need to define a electParameter which will hold the band name retrieved from your ViewState. See markup below

<asp:ObjectDataSource ID="odsBands" runat="server" 
    SelectMethod="SelectBands" 
    OnSelecting="odsBands_Selecting"
    OnSelected="odsBands_Selected"
    OnFiltering="odsBands_Filtering"
    &lt;SelectParameters>
        <asp:Parameter Name="BandName" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>

Here I set up the BandName property which will chuck the request band name string into the ViewState:

private string BandName
{
    get
    {
        return ViewState["BandName"] == null ? "" : ((string)ViewState["BandName"]);
    }
    set
    {
        ViewState["BandName"] = value;
    }
}

In the Page_Load method, I'm putting the QueryString into the Viewstate, using the BandName property:

protected void Page_Load(object sender, EventArgs e)
{
    odsBands.TypeName = this.GetType().AssemblyQualifiedName;
    
    if (!Page.IsPostBack)
    {
        BandName = Request.QueryString["bandName"];
        // This is my SPGridView instance which will display the data
        grdBand.DataSourceID = "odsBands";
    }
}

Ok cool. From here I use the property to set the input parameter 'BandName' like this:

protected void odsBands_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["BandName"] = BandName;
}

Finally, I define the SelectMethod 'SelectBands' with one string argument which is the input parameter. In this particular case I'm using a DataSet from which I then create a DataView to filter on the parameter value:

public DataView SelectBands(string bandName)
{
    // The method below fetches the data from a db, replace this with your own source
    DataSet dsBands = BandsResourceManagement.Instance.GetBands();
    
    // BandName is also the field name in the table and I'm sorting the records by the field BandId
    DataView dvBand = new DataView(dsBands.Tables[0],"BandName = '" + bandName + "', "BandId", DataViewRowState.CurrentRows);
}

Tuesday, January 10, 2012

Connecting VS2008 to TFS2010

What a hassle. My virtual machine crashed today and it got reset to the last snapshot, which had been taken like somewhere in 1957. So I've practically wasted all day on reconfiguring all the crap that I had installed after the snapshot was taken.

One of the things I spent a fuck load of time on was getting VS2008 connecting to TFS2010. Finally, got it to work. This is how:

1. I installed VS2008
2. Then downloaded and installed Microsoft Visual Studio 2008 Service Pack 1 (Installer), get it here
3. Then, downloaded and installed Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010 (Installer), get it here
4. Checked in VS2008 if it installed correctly

Finally, I drilled down into the registry, to "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\TeamFoundation\Servers" (you should be able to find it, if not make sure you installed the earlier mentioned stuff in the correct order).

In here, I added a string value where the value name can be anything and the value data field should contain the full address of your server.

From here, you should be able to go to the Team Explorer window in VS and add the team project. That's it.

Friday, January 6, 2012

Note2Self: Configuring web service for web application usage

Entries to web.config in WSS/VirtualDirectories/80 to configure webservices
Steps:

1 Add 'endpoint' element to 'client':
<client>
   <endpoint address="http://localhost/YourService/ServicesYou.asmx"
             binding="basicHttpBinding"
             bindingConfiguration="###MyCustomBindingName1###"
             contract="###DefinedConfigurationName###"
             name="###stringEndPointConfigurationName###" />
</client>
###MyCustomBindingName1### -- is a reference to what will be added to the system.serviceModel/bindings/basicHttpBinding/ element. Preferably, prefix it with the binding type (i.e. in this case: "basicHttpBinding_MyCustomBindingName1")

###DefinedConfigurationName### -- should be the value that you defined in the Reference.CS file. To be more specific in the attribute before the interface definition:
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://WebServices/", ConfigurationName = "###DefinedConfigurationName###")]    
2 Create binding element
        <binding name="###MyCustomBindingName1###" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
I changed the maxReceivedMessageSize and maxBufferSize to the max. allowed size since I had trouble retrieving large DataTables.

Monday, December 12, 2011

Binding an ASP.NET dropdown list to a SharePoint list

Quick code snippet to populate an ASP.NET dropdown list from a SharePoint list. Also note that there is no need to use a foreach loop to iterate through the items collection, adding the items to the list blablabla. I simply create an SPList instance, retrieve the data from the appropriate list and then tie those two bastards down. That's how I do stuff, yo.
using (SPWeb web = SPContext.Current.Site.OpenWeb())
            {
                SPList list = web.Lists["TestConnectionList"];
                ddlConnections.DataSource = list.Items;
                ddlConnections.DataValueField = "Title";
                ddlConnections.DataTextField = "Title";
                ddlConnections.DataBind();
            }
In this case, the name of the resource SharePoint list is called 'TestConnectionList' and the name of the dropdown list 'ddlConnections'. Make sure that you also specify the exact same column names in the list in the DataValueField and DataTextField or otherwise you'll get an exception thrown at you. As you can see, I am also using a scope so that the SPWeb object gets destroyed after usage. This is because I am explicitly calling the site.OpenWeb();

Friday, November 18, 2011

Serialization & deserialization in C#

Hi guys, Been pretty busy lately with developing a web part that allows our data specialists to deploy workflow data feeds from test environments to (pre)production environments. Not going into details, but I would like to show you a simple example on how to (de)serialize objects so these can be passed on to WCF services / ASP.NET web services. Consider the following class:
    [Serializable]
    public class MetalBand
    {
        private string _bandName;
        private int _intMembers;
        private string _genre;

        public MetalBand()
        {
        }

        public string BandName
        {
            get { return _bandName; }
            set { _bandName = value; }
        }

        public int NumberOfMembers
        {
            get { return _intMembers; }
            set { _intMembers = value; }
        }

        public string Genre
        {
            get { return _genre; }
            set { _genre = value; }
        }

    }
Suppose you’ve got an instance of this object like so:
            MetalBand myBandObject = new MetalBand();
            myBandObject.BandName = "Skeletonwitch";
            myBandObject.Genre = "Blackened Thrash";
            myBandObject.NumberOfMembers = 5;
And you would need to pass this data on to a web service, you would need to serialize it first. This means that you convert an object state into a format which can be transported and/or stored. Here is how to:
            XmlSerializer serializer = new XmlSerializer(typeof(MetalBand));
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.OmitXmlDeclaration = true;
            StringWriter stringWriter = new StringWriter();
            using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, writerSettings))
            {
                serializer.Serialize(xmlWriter, myBandObject);
            }

            
            XmlDocument doc = new XmlDocument();

            // here is your serialized object
            doc.LoadXml(stringWriter.ToString());
The XmlSerializer class will do the actual magic of conversion, the MetalBand object type is passed on to the constructor of the class The instance of the XLMWriterSettings holds a supporting set of features on the XmlWriter object, which is created by the XmlWriter.Create. With the OmitXmlDeclaration property set to true, we state that we do not want to write an XML declaration in our document. We are then serializing the object instance into the XmlWriter stream with the chosen Xml declaration settings. Then we simply create a new instance of an XmlDocument and blast the xml stream right into it. As for deserialization, you can instantiate another object of XmlSerializer or use the same one created earlier. Then use the XmlNodeReader, which is also a stream reader, to stream that puppy into the Deserialize method.
            XmlSerializer xSerializer = new XmlSerializer(typeof(MetalBand));
            XmlNodeReader reader = new XmlNodeReader(doc);
            MetalBand mySecondBandObject = (MetalBand)xSerializer.Deserialize(reader);
That is all there is to it

Tuesday, September 20, 2011

Setting up Business Connectivity Services in SharePoint 2010

The Business Connectivity Services (BCS) are a set of services which are used to connect to external data such as a SQL Server database. In combination with SharePoint designer, it is fairly easy to create external content types and lists (creating it in Visual Studio is also a possibility but more difficult to do). Personally, I had a little bit of difficulty setting it up the whole thing. The first thing I tried to do was to create an external content type for an arbitrary table in SQL Server, but I got the following error in SharePoint Designer: "The Business Data Connectivity Metadata Store is currently unavailable."

Other SP peers seemed to have the same problem and many could solve it by installing a WCF hotfix (KB976462), however this did not work for me. I will show you three checks I did in order to have stuff working. 1. Check if the Business Data Connectivity Service is running. You can find it by going to "Central Administration" -> "Manage services on server". If it has stopped, start it again.

2. Make sure you've got a Business Data Connectivity Service Application set up in "Application Management" ->"Service Applications"->"Manage service applications"

3. The next one is what I overlooked and made me waste hours of my life. Go to "Application Management"->"Service Applications"->"Configure service applications associations". In here you need to check whether your BCS Application Proxy is checked, otherwise it won't work.