Free IIS7 Beta Hosting!

Check it out! Free IIS7 Beta hosting for you to test your web applications on!

http://www.iis.net/default.aspx?tabid=7&subtabid=791

“0 The post could not be added” Error Occurs While Posting To Community Server

I was recently migrating an old blog to community server through the web services API. For some reasons while migrating over the posts, it would die after the 36th item every time while giving a generic "The post could not be added" error. I thought that it could be something to do with that specific post, so I removed it from the list to migrate. Same error. So I began to wonder if it was some spam post count limiter, and there was no blog posting limiter. Needless to say, I was pretty confused.

I Google'd around, and eventually found this (http://communityserver.org/forums/p/491235/595600.aspx#595600) talking about Windows Live Writer and a similar error. The error occurs when there is already a post containing the same title. Since both the 37th and the 38th (the two ones it was dying on) contained title's that had already occurred in the migration process it wasn't apparent to me immediately this was this issue.

Anyhow, just a quick FYI for anyone who hits this issue.

Accessing Sharepoint Data through Web Services

I've been developing a web application recently which needed to access a calendar in a sharepoint installation to retrieve events and display them. Under the covers in sharepoint, a calendar with events is more or less just a list. So we access the list. Here's how I did it:

Step 1

Add a reference to the lists sharepoint web service in Visual Studio:

Step 2

Next we want to initialize a new instance of the Lists class in the referenced web service, and set the credentials to access the sharepoint site:

sharepoint.lists.Lists l = new sharepoint.lists.Lists();

//Supply the credentials to access sharepoint

System.Net.NetworkCredential cred = new System.Net.NetworkCredential("your username here", "your password here");

l.Credentials = cred;

Step 3

In order to retrieve the calendar events, we must get a list of items that belong to the calendar's list. We do so using this piece of code:

XmlNode n = l.GetListItems("your calendar name here", null, null, null, null, null, null);

GetListItems takes a number of parameters, but the only needed one is the name of the calendar, the rest can be null unless you need them. This method returns an XML node with a collection of XML Child Nodes each one representing a list item, and in this case calendar items. An example of the XML it returns through the InnerXml property is this:

<rs:data ItemCount="2" xmlns:rs="urn:schemas-microsoft-com:rowset">

  <z:row ows_EventDate="2007-08-02 20:30:00" ows_EndDate="2007-08-03 00:30:00" ows_fRecurrence="0" ows_EventType="0" ows_Attachments="0" ows_WorkspaceLink="0" ows_Title="Consultants Night" ows_Location="ObjectSharp Training Room, 1 Yonge St., 19th Floor" ows_Description="<div></div>" ows_fAllDayEvent="0" ows__ModerationStatus="0" ows__Level="1" ows_ID="1" ows_owshiddenversion="1" ows_UniqueId="1;#{3912FED0-05B0-4B80-B452-2CF04C148FEC}" ows_FSObjType="1;#0" ows_Created="2007-07-29 21:24:47" ows_FileRef="1;#Lists/Calendar/1_.000" ows_MetaInfo="1;#" xmlns:z="#RowsetSchema" />

  <z:row ows_EventDate="2007-08-22 17:00:00" ows_EndDate="2007-08-22 17:00:00" ows_fRecurrence="0" ows_EventType="0" ows_Attachments="0" ows_WorkspaceLink="0" ows_Title="Test" ows_Description="<div></div>" ows_fAllDayEvent="0" ows__ModerationStatus="0" ows__Level="1" ows_ID="2" ows_owshiddenversion="1" ows_UniqueId="2;#{282B92B3-4B9B-4F78-B3CB-E8B9633793A1}" ows_FSObjType="2;#0" ows_Created="2007-08-22 16:29:59" ows_FileRef="2;#Lists/Calendar/2_.000" ows_MetaInfo="2;#" xmlns:z="#RowsetSchema" />

  </rs:data>

 

Step 4

We can extract the data of each individual event through iterating through each Xml child node, and outputting the requested values. An example of doing this is this:

for(int i = 0; i < n.ChildNodes[1].ChildNodes.Count;i++)

{

if(n.ChildNodes[1].ChildNodes[i].Attributes!=null)

Console.WriteLine("Event " + n.ChildNodes[1].ChildNodes[i].Attributes["ows_Title"].InnerText + " begins on " + n.ChildNodes[1].ChildNodes[i].Attributes["ows_EventDate"].InnerText);

}

 

This will produce the following output in the console window:

Event Consultants Night begins on 2007-08-02 20:30:00

Event Test begins on 2007-08-22 17:00:00

 

Thus we are done!

Ensure You Remember EnsureChildControls()!

I was recently writing a pretty simple ASP .net webpart, and its respective webpart editor. I was however, getting a unexpected error when the webpart editor was opened by the user:

I was initially confused as I wasn't doing anything that would throw this type of exception. The code is pretty straight forward with just setting the value of the textbox, and I had initialized all of the controls in the CreateChildControls() method. The exception was occurring when the SyncChages() method was being called by the editorzone, and the webpart editor was being populated with the current settings.

Eventually I realized that I had not called EnsureChildControls() before SyncChanges() was being executed. This method is required to initialize your controls. It checks to see if the CreateChildControls method has yet been called, and if it has not, calls it.

An example of using EnsureChildControls in the SyncChanges method is as follows:

public override void SyncChanges()

{

EnsureChildControls();

CustomWebPart part = (CustomWebPart)WebPartToEdit; ;

if ((part != null))

{

//Sync!

}

}

Blog API

So I was trying to configure Word 2007's blogging feature to post to my blog at GeeksWithBlogs, I noticed that it does so through a standard web server API called MetaBlogAPI, and it's pretty widely supported. I had no idea this existed (granted I may be out of the loop). It contains all of the functionality to add posts, view posts, and do everything blog related. Very handy.

Check out my blogs API (granted you can't do much without my account credentials!): http://geekswithblogs.net/mcassell/services/metablogapi.aspx

Displaying Rich Media using the ASP .net Future’s CTP

I've been playing around with the ASP .net Futures lately. They are a collection of (as the name implies) up and coming ASP .net technologies that installs ontop of your .net Framework 2.0 install. It's a really interesting package that builds ontop of the ASP .net AJAX framework featuring a wide collection of controls.

One of the coolest things included with it is the Media control. The Media control is used for leveraging the awesome media playing capabilities of Silverlight in a way which the developer does not have to focus on specific implementations and can focus simply on the end result (a video being played for instance).

The media control is automatically added to the toolbox when creating an ASP .net Future's project, if not, add the appropriate references, and manually browse for it.

The Media control on the toolbox, and on an instance of it in the web page designer.

Next, one plugs in the location of the media file they wish to play. An example of a Media control that plays an MP3 would be:

<asp:Media ID="Media1" runat="server" Height="240px" MediaSkin="Professional" MediaUrl="~/U2 - Miracle Drug.mp3"

Width="320px">

</asp:Media>

When you run the web application it will look like this and be playing the selected media file:

Additionally, the Media control exposes a rich variety of properties (which it translates into the proper JavaScript/XAML rendering to the client) to enable the developer to pretty much set any setting imaginable programmatically without having to worry about how it's actually being implemented. One of the neatest things it exposes is the ability to have chapters within the media being played. Primarily a chapter is a time index of a media file. It allows you to have points to which the user can jump around with. For instance the following instance of the control:

<asp:Media ID="Media1" runat="server" Height="240px" MediaSkin="Professional" MediaUrl="~/U2 - Miracle Drug.mp3"

Width="320px">

<Chapters>

<asp:MediaChapter ImageUrl="~/20.jpg" TimeIndex="20" Title="Twenty" />

<asp:MediaChapter ImageUrl="~/30.jpg" TimeIndex="30" Title="Thirty" />

</Chapters>

</asp:Media>

Will allow the user to jump to different sections as shown below:

So if we want to do something cool with this, we can have a client event execute when a new chapter occurs like below by setting the OnClientChapterStarted property, we specify a JavaScript function to execute when a new chapter starts:

<script>

function ChapterStarted(sender, args)

{

alert("A new chapter!");

}

</script>

 

<asp:Media ID="Media1" runat="server" Height="240px" MediaSkin="Professional" MediaUrl="~/U2 - Miracle Drug.mp3"

Width="320px" OnClientChapterStarted="ChapterStarted">

<Chapters>

<asp:MediaChapter ImageUrl="~/20.jpg" TimeIndex="20" Title="Twenty" />

<asp:MediaChapter ImageUrl="~/30.jpg" TimeIndex="30" Title="Thirty" />

</Chapters>

</asp:Media>

While runing it will look like so:

So the Media control wraps much of the streaming media functionality of Sliverlight into a convenient package that makes programming against extremely easy without making the developer have to worry about the low level intricacies of it.

Facebook + .net

Facebook is probably one of the (if not the) fastest growing social networking site's out there, with millions of users around the world. Microsoft and Facebook recently announced a partnership allowing end user's to program against there API using managed languages. The library is available here : http://www.microsoft.com/downloads/details.aspx?FamilyId=CCD46762-45EC-4FBE-AD91-FC916671E734&displaylang=en&amp;clcid=0x409.

The API allows a developer to access information about a persons friends, groups, and other info. However while the normal Facebook web UI allows a person to drill through a friends, friends you cannot through the API. This really limits what you can use it for.

After installing the component, you simply reference it into your assembly, and create a new instance using the following:

Facebook.Components.FacebookService service = new Facebook.Components.FacebookService();
service.ApplicationKey = "<removed, get your own from facebook.com";
service.IsDesktopApplication = true;
service.Secret = "<removed, get your own from facebook.com>";

The first time you call a function such as .GetFriends() the following window will appear asking the user to login to facebook:

If you want to get a list of the user's friends, and output them, you can use the following:

var friends = service.GetFriends());

foreach (Facebook.User u in friends)
     Console.Writeline(u.Name);

Just as an example, I have written one actual application using it, a XAML window using infragistics carousel window panel (I would post the source but it uses an infragistics control):

It’s reasonably cool if you’re really into Facebook, but the limitations in the information the UI can access, coupled with bizarre bugs, and the awkward authentication process make it almost not practical to use. But defiantly worth checking out.

Building DotNetNuke Style Portals Using ASP .net 2.0 WebParts

Recently, on a project I was working on, we really wanted to allow users to build rich & dynamic pages. We wanted to be able to build building blocks from which user’s could customize upon. We wanted to be able to have user’s quickly design their own pages without having to worry about HTML. The solution? Webparts.

So off to work I set out, building a series of webparts such as a rich html webpart with a HTML Text Box as its custom designer. A rich content web part allowing the user to display flash, video, or a picture. A user information webpart. So you get the idea, a wide pallet allowing the user to do what they wanted to do.

Next I built a page to host these wonderful web parts, and allowed the user (if logged in) to add, remove, and customize them. It was beautiful, but not what we needed. What we needed was to allow the user to dynamically create pages. I discovered, that webparts by default are bound to the specific .aspx page they are created with. For instance, there would be no way to separate home.aspx?page=1 from home.aspx?page=2.

After some investigating, it turns out the easiest solution (that I found) was to inherit the System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider and override the LoadPersonalizationBlobs and SavePersonalizationBlob methods to get them to recognize the difference as shown below:

Public Class AdvancedSqlPersonalizationProvider

        Inherits System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider

 

        Public Overrides Function LoadPersonalizationState(ByVal webPartManager As System.Web.UI.WebControls.WebParts.WebPartManager, ByVal ignoreCurrentUser As Boolean) As System.Web.UI.WebControls.WebParts.PersonalizationState

            Return MyBase.LoadPersonalizationState(webPartManager, ignoreCurrentUser)

        End Function

        Protected Overloads Overrides Sub LoadPersonalizationBlobs(ByVal webPartManager As WebPartManager, ByVal path As String, ByVal userName As String, ByRef sharedDataBlob As Byte(), ByRef userDataBlob As Byte())

            If Not (System.Web.HttpContext.Current.Request("page") Is Nothing) Then

                MyBase.LoadPersonalizationBlobs(webPartManager, System.Web.HttpContext.Current.Request("page"), userName, sharedDataBlob, userDataBlob)

            Else

                MyBase.LoadPersonalizationBlobs(webPartManager, path, userName, sharedDataBlob, userDataBlob)

            End If

        End Sub

 

        Protected Overloads Overrides Sub SavePersonalizationBlob(ByVal webPartManager As WebPartManager, ByVal path As String, ByVal userName As String, ByVal dataBlob As Byte())

            If Not (System.Web.HttpContext.Current.Request("page") Is Nothing) Then

                MyBase.SavePersonalizationBlob(webPartManager, System.Web.HttpContext.Current.Request("page"), userName, dataBlob)

            Else

                MyBase.SavePersonalizationBlob(webPartManager, path, userName, dataBlob)

            End If

        End Sub

    End Class

We then use this as the data provider for the webparts. What this does is it provides a mechanism to seamlessly create dynamic pages, and have it all handed by the existing and stable webparts engine.  This, coupled with properly done URL Re-Writing means you can virtually eliminate the need for multiple .aspx pages on your site.

So I'm Matt Cassell!

So hi everyone!  This is my first blog posting here, and I thought I’d introduce myself. I’m a high school student from Cambridge, Ontario, Canada (near Toronto). I’m also a Microsoft Visual C# MVP, and I currently work part-time for ObjectSharp Consulting in Toronto mainly focusing on their website.

Through this blog, I hope to share some of the solutions, and problems I face in my development experience.  I know blog’s have saved my but a few times, and it’d be nice to return the favour.