Monday 26 April 2010

Installing SharePoint 2010 with local user accounts

One of the things that was very easy in SharePoint 2007 was installing SharePoint with a local account to the default instance of a database. This is not the case in 2010. I won’t say its hard but its not straight forward.

If you try to install SharePoint as part of a server farm using the Complete install method where you have not created a configuration database first and try to use a local account as the service account, you will get an error “The specified user xxxx is a local account. Local accounts should only be used in stand alone mode”

There are a couple of ways around this. You can change some registry settings and update the server configuration a bit once the install is complete with a domain account. But what happens if you don’t have a domain account to install with. Well enter PowerShell and the cmd-let New-SPConfigurationDatabase.

Config You will need to run the SharePoint 2010 Management Shell as an administrator and using the command let New-SPConfigurationDatabase. Enter the name of the database you want to create and the name of the server. Now enter the name of the user account you want to create as the farm admin making sure that this account is a member of the local administrators group. Enter the final passphrase and press return to start the operation.

Once this completes successfully, you can run the SharePoint configuration wizard and it will pick up the database server and configuration database. Make sure you don’t disconnection from the farm.

Click next and follow the prompts to finalise the installation of SharePoint.

If you get an error about a non unique user, make sure the user is a member of the local administrators group. Close the PowerShell command window and reopen it and rerun the cmd-let.

Update: 01-06-2010: If you get an Access denied on the Wizard setup for the user that set up the installation and you are running on Windows Server 2008, close the browser and run IE again as administrator. The administrator credentials which are required to create application pools etc are not carried forward unless you do.

Thursday 22 April 2010

Office 2010 and SharePoint 2010 RTM

So now Office 2010 and SharePoint RTM are now on TechNet and MSDN so those of you with those subscriptions, you can go and download and evaluate them.

It will available to Software Assurance customers April 27th and it be able to buy for Volume Licence customers on May 1st. Its available online May 15th and in stores June 15th.

Tuesday 20 April 2010

A new computer

Way in 2005 I built my current machine. Its an AMD Athlon64 X2 4400+ using the socket 939 chipset with 4GB of RAM on an MSI K8N Diamond motherboard. I also put in two Gainword 7800GT cards into it because it was going to be my gaming machine as well. Over the years additional drives have been added but the core components have remained the same. Time has passed and caught up with this machine so I decided it was time to create my new development machine again.

I checked out and around for a while before deciding on what to buy. I looked at the existing AMD offerings and Intel chips and for the first time in 10 years I decided to go with the Intel platform.

IntelCorei7

I choose the Intel Core i7 930 which is a quad core CPU with hyper threading which effectively means that Windows sees the CPU as 8 processors when you look at it in the Device Manager or in Task Manager.

The 930 allows a decent amount of over-clocking ability if I should ever need it. Its not overly expensive and compared to the next chip up in the 900 series its just over half the price.

So once I picked the CPU, I went on to the motherboard. I looked at the varying options out there and decided on a fairly decent X58A-UD7motherboard  from Gigabyte the GA-X58-UD7 which contained fairly everything AND the kitchen sink. Supports SLI and CrossFire technologies, USB 3.0 (or SuperSpeed USB if you will), a large number of SATA connections, 10 in all with support for eSata and the new SATA3 600 devices. So all in all, a hefty amount of kit squeezed onto an ATX board.

After that it was off to get the RAM and this was my downfall. I choose ECC RAM instead of non ECC RAM. It was only when I got all the parts from the online retailer which was Komplett.no in this case did I discover my mistake. Actually, it wasn’t until I installed the RAM and the system wouldn’t boot did I uncover my error. Thankfully Komplett took back the RAM and refunded me on that part so I could buy the non-ECC RAM PC3-10600 DDR3 RAM that the i7 supports. Currently there is 12GB in there using 3 slots so I can expand it to the full 24GB at a later stage.

WEI

I installed Windows 7 Ultimate x64 edition and everything bar the extremely new NEC USB3.0 chip was recognised straight out of the box.

Running the Windows Experience Index gave me a score of 5.5 due to the gaming graphics performance of my 5 year old graphics card. The CPU and RAM both got scores of 7.5

The computer is definitely much snappier and the whole experience is much better. Virtual machines load in a matter of seconds due to the fact that I can assign two processors and a chuck of RAM to them. As upgrades go there was a lot of bang for the buck. I was lucky that I could reuse most of my drives, my PSU and my GFX card.

 

The total cost of the build was about 11000 Norwegian Kroner which is 1,385EUR. If you are in the US this price doesn’t bear thinking about as components in Europe are more expensive.

A quick comparison on newegg.com for the same components came in at 1286USD or 7500NOK. A considerable difference. And if you ask why I didn’t order from the US. Well return policies in Norway are quite good and the warranty periods on consumer goods range from 3 to 5 years as standard due to legislature. And import tax would have negated the amount of savings I would have got and I would have lost the extremely nice warranty on my new parts.

Overall I am extremely happy with the new performance of my developer machine.

Thursday 8 April 2010

Dynamic User Controls – Part 5 – Refactoring the code

The previous post dealt with getting the user controls to be dynamic with both addition and removal methods for the controls. In this post we will look at doing code reduction and making the code reusable with a minimum amount of effort. We created only one type of user control in the previous set of examples, but it is easy to image a situation where you would be creating more than one type type of control and in this scenario it would be handy not to have to write a massive amount of code for each control but use generic methods.
So that is what we are going to do in this post, some good old fashioned code refactoring. First we will look at the interface that is being used by user control and how it can be made generic. The original code for the interface is as follows
We can change the interface to a generic type like so

We will now change our existing PersonControl to use this new interface. The existing code is like this

And to implement the new interface we change it to the following

It is a simple as that. Any new control we want to use should use the new interface and whichever entity it is being used to represent.

We will now take a look at the method that enumerates the repeater items for the items values. Before we had this code

If we take a look at the code, we can make it generic by supplying a reference the type of entity in the list we want to return and also the name of the placeholder control and the repeater we want to use as parameters to a method. So by applying that logic we end up with this code.

As you can see now we have a nice reusable method. But we can further change this code and use some LINQ to replace the foreach statement. It will now look like this

To use the method we would replace the List<Person> CurrentPersonList as follows

Now we will look at changing the methods that add items to the repeater. Again we will take a look at the original code that was used in the last post.

If we look at what we could do here, we could change the code so that we supply the entity type that we want to use along with the current list of items, and the repeater that want to bind to. There is one slight additional change we need to do and that is when you use a generic method to create a new instance of a type, you must specify in the method declaration, the new constraint.

We can now replace the contents of the AddPerson method the the following

We look at the ItemCommand method which can generic the same way we have refactored the AddItem methods. The original code looks like this

Again we will look at the code and see what is reusable. If we supply the RepeaterItemEventArgs, a generic list of items and the repeater to bind to. So with that we end up like this

To use the method in the RemovePerson event, we change the contents of the repeater ItemCommand method to

Now the final piece of the puzzle is to change the ItemCreated event and the ItemLoad events. We can merge the ItemLoad into the ItemCreated event using a lambda expression. So the two methods before we start look like this.

If you use the lambda operator => we can merge the the ItemLoad and ItemCreated events into one method.

Now that we have it merged we can refactor this method into a generic method. We can replace the entity parts and if we pass in the name of the placeholder control and the path of the control to load as well as the RepeaterItemEventArgs we can re-use the method.

And there we have it, the code distilled down so that we can reuse certain methods if we have more than one repeater with different type of controls. So that is the end of the series of posts on dynamic controls. You can get the code bits from the post in the series

Tuesday 6 April 2010

Dynamic User Controls – Part 4 – Data Bound User Controls

We have shown in the previous post how to dynamically add a standard ASP.NET control to a page. Now we are going to look at how to make dynamically add user controls to the page and also make them databound. First of all we need to look at our entities. We have a very simple Person class, which has a couple of properties.
 public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

As you can see it is very basic. The user control we will be using, models this in front end code.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PersonControl.ascx.cs" Inherits="DynamicUserControls.Web.UserControls.PersonControl" %>
<table>
<tr>
<td>First Name</td>
<td><asp:TextBox ID="txtFirstName" runat="server" Width="300px"></asp:TextBox></td>
</tr>
<tr>
<td>Last Name</td>
<td><asp:TextBox ID="txtLastName" runat="server" Width="300px"></asp:TextBox></td>
</tr>
</table>

The textboxes just represent the the strings in the class. We also have an interface which we will implement in the user control.
public interface IPersonControl
{
Person Data { get; set; }
void DataBind();
}

To implement this in our user control we use the following code
public partial class PersonControl : UserControl, IPersonControl

If you are using ReSharper you can press ALT+Enter to implement the members, although I am fairly sure Visual Studio 2008 and above does this as well. The codebehind of the user control looks like this
public partial class PersonControl : UserControl, IPersonControl
{
private Person _data;

public override void DataBind()
{
if (Data != null)
{
txtFirstName.Text = Data.FirstName;
txtLastName.Text = Data.LastName;

_data = null;
}

base.DataBind();
}


public Person Data
{
get { return _data ?? (
_data = new Person
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text
}); }
set { _data = value; }
}
}

We have a new property called Data which allows us to get and set the information in the control. We also have a DataBind method which is fired when the control being databound.

The Data property when set, sets a private variable called _data which we will come back to later. When we DataBind our control, we set the values of the textboxes to the appropriate values of the class and we null the _data variable so that each time when we get Data property, we check to see if _data is null i.e. has been databound. We can then assign the values of the textboxes to a new instance of the class and return it. In the code above, I am using a null-coalescing operator (??) to shorten the code a bit.

That is all we need to do with the user control for the moment. We will now swap back to the Default.aspx page and add a new tab to the page.
<cc1:TabPanel ID="tabPeople" runat="server" HeaderText="Person User Control Demo">
<ContentTemplate>
<asp:Repeater ID="rptPeople" runat="server">
<ItemTemplate>
<asp:PlaceHolder ID="phPerson" runat="server"></asp:PlaceHolder>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnAddPerson" runat="server" Text="Add a person" CausesValidation="false" OnClick="AddPerson" />
</ContentTemplate>
</cc1:TabPanel>

As you can see it is very similar to the tab we created for the textbox example in the previous post. We will also create a new page property in the code behind file called CurrentPersonList
List<Person> CurrentPersonList
{
get
{
var items = new List<Person>();

foreach(RepeaterItem item in rptPeople.Items)
{
var control = (PersonControl) item.FindControl("phPerson").Controls[0];
items.Add(control.Data);
}
return items;
}
}

We can reference our Data property in our control by casting the control we access in the placeholder as a PersonControl. And because the Data property is a Person class we can add it to our generic list.

Adding a new control is a case of getting the current list, adding a new Person class, set the data source of the repeater to the new list and the binding the list again.
protected void AddPerson(object sender, EventArgs e)
{
var currentData = CurrentPersonList;
currentData.Add(new Person());
rptPeople.DataSource = currentData;
rptPeople.DataBind();
}

As you can see we take a copy of the current data, add a new one and rebind the repeater. Now we need to override the ItemCreated event of the repeater and change it so that it loads a user control with the correct data.
private void RptPeopleItemCreated(object sender, RepeaterItemEventArgs e)
{
var data = (Person) e.Item.DataItem;
if(!Equals(data,default(Person)))
{
var placeholder = (PlaceHolder) e.Item.FindControl("phPerson");
var control = (PersonControl) LoadControl("~/UserControls/PersonControl.ascx");
control.Data = data;
placeholder.Controls.Add(control);
}
else
{
e.Item.Load += PersonItemLoad;
}
}

First we cast the DataItem as a Person object and then we check to see if its a blank object i.e. default. If its not a blank object, we need to load the control and set its Data property. So we need to get the placeholder control in the ItemTemplate. We need to then load an instance of our user control and set the Data property with the casted DataItem. We add the control to the Controls collection of the placeholder. On the other hand if the object is blank we just want to load the control with no Data property set. So we use the Item.Load event to achieve this.
var literal = (RepeaterItem)sender;
var placeHolder = literal.FindControl("phPerson");
var control = (PersonControl)LoadControl("~/UserControls/PersonControl.ascx");
placeHolder.Controls.Add(control);

So its very similar to the ItemCreated event. We can now run the page and it will add a user control to the page when you click the button. That’s the first part of the story, the second part is being able to remove the item from the page. There is no point in being able to add controls if you cannot remove them-

To do this we are going to add a LinkButton to the user control so that it now looks like this
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PersonControl.ascx.cs" Inherits="DynamicUserControls.Web.UserControls.PersonControl" %>
<table>
<tr>
<td>First Name</td>
<td><asp:TextBox ID="txtFirstName" runat="server" Width="300px"></asp:TextBox></td>
</tr>
<tr>
<td>Last Name</td>
<td><asp:TextBox ID="txtLastName" runat="server" Width="300px"></asp:TextBox>&nbsp;<asp:LinkButton ID="lnkRemove" runat="server" OnClick="RemoveItem" Text="Remove this item"></asp:LinkButton></td>
</tr>
</table>

With the new link button we have a handler that will raise an event which we can handle in our repeater. We will send the command “Remove” to whatever handler is listening.


     protected void RemoveItem(object sender, EventArgs e)
{
RaiseBubbleEvent(this, new CommandEventArgs("Remove", null));
}

To handle this event, we need to use the ItemCommand event the repeater. The ItemCommand event is fired whenever a command is received by the repeater.



if (e.CommandName != "Remove") return;
var index = e.Item.ItemIndex;
var currentData = CurrentPersonList;
currentData.RemoveAt(index);
rptPeople.DataSource = currentData;
rptPeople.DataBind();

We check to see if the CommandName is the correct one, and if not we will just break out of the event. We find the ItemIndex of the item that raised the event and because we are using a list, it will be in the same position in that list. We can then remove the item at that position.

In the next post we will look at refactoring the code and making it generic so that you can use the same methods for all the repeaters etc.

Sunday 4 April 2010

Dynamic User Controls – Part 3 – Using a repeater

Continuing on from my previous posts (parts 1 and 2) this post will detail how to use a repeater to add a textbox control dynamically.

First off we will create a new tab that will contain a button control and a repeater that will contain a placeholder control


The idea are working with is the following. The placeholder will contain only 1 control at a time, be a composite user control or in this example a textbox control. We will bind a generic list of strings to the repeater and using the ItemCreated event of the repeater, we will program it to create a textbox and put the contents of the string item into the text property of the textbox.

We will also create a page property that returns a generic list of strings. This will be got from the repeater but looping through each item in the Items collection and finding the textbox in the placeholder control and getting its text property. Each time we want to add a new textbox, we will use this page property to get all the current values and then add a new blank string to this list. After we have done that, we will rebind the repeater with the new list. By using this method to create our textboxes, we can store the values easily and manage state easily as well.



So now the page property

What we are doing here, is firstly creating a new list on line 5. Then we are looping through all the RepeaterItems in the Items collection of the Repeater. In the item, we are finding the textbox that we have added. We do this by using the FindControl method of the RepeaterItem to find the specified placeholder control and then accessing its Controls collection and casting that object as a textbox control. We dont need to cast the placeholder control because it inherits from the Control object which has a Controls collection. Once we have that textbox we add the value of the Text property to our list. Once we have looped through all the RepeaterItems we will return the list.

Now to the OnClick event handler of the button which will add a new textbox

So we first create a new list called currentData and assign it to the value of CurrentTextBoxData which is the page property we created just before. We then add a blank string to the list. Once we have done that, we set the repeater’s data source to the new list and then databind it.

Why do we create a new list and what doesn’t the CurrentTextBoxData property have a setter?. The answer to both these questions is the following. Firstly we are using the repeater as a date store to store the current values in the textbox. Each time we want to add to it, we should get a copy of the current values and add the new value to this copied list. Finally we will replace the current values with the new copy of the values. So in this way, there is no need for a setter per se because the databind event acts as the setter since it places all the values in the repeater.



We will continue with the ItemCreated event of the repeater. You will need to either manually add the event to the repeaters declaration in the ASPX page or add it in the Page.OnInit entry in the code behind.

Firstly, we cast the DataItem to a string. We know this is a string because that is what are binding to the repeater control. We then create a new instance of a textbox control and set its text property to the string in the DataItem. Now we create a placeholder and assign it to the placeholder in the repeater item using the FindControl method. We then add our newly created textbox to the placeholder. This how we dynamically create our controls.

Running this will now allow you to click the button and that will add a new control. You can edit the values of the textboxes and they will survive postback because each time we need to create new ones, we get the current values and then recreate them all again.

The next post will deal with adding dynamic databound user controls and also how to remove dynamic controls as well as bubbling events up from your user control to be handled by the repeater.

The code bits for all these posts can be found in the first post here

Friday 2 April 2010

Dynamic User Controls – Part 2 – The Wrong Way

Following on from my session intro post, this post will deal with the “wrong” way to add controls to the page. Its wrong in the traditional sense, it just doesn’t provide as much control as you would like. Also it makes it difficult to manage the number of controls and events on the page. So lets get into it. Some prerequisites. I am using the AJAX Control Toolkit for my demos. Specifically I am using the AJAX Tab control to show off the demo. If you are not using one of the versions I uploaded, you will need this toolkit to follow the code I will be writing. Or you can just not use it and take out the tabContainer code :) Starting off, I have the standard Default.aspx page with a ScriptManager control on it. Also on the page I have an instance of the AJAX Control Toolkit TabControl. In the TabControl I have one tabPanel with an ASP PlaceHolder control and an ASP Button Control
<cc1:TabPanel ID="tabStart" runat="server" HeaderText="Start">
<ContentTemplate>
<asp:PlaceHolder ID="phControls" runat="server" />
<br />
<asp:Button ID="btnAddControl" runat="server" Text="Add a new text box"
CausesValidation="false" OnClick="AddDemoControl"/>
</ContentTemplate>
</cc1:TabPanel>

In the code behind of the page I have the Page_Load event and the event handler for the OnClick event of the ASP button.
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack) return;
//Add 2 new textboxes to the specified placeholder
phControls.Controls.Add(new TextBox());
phControls.Controls.Add(new TextBox());
}

protected void AddDemoControl(object sender, EventArgs e)
{
phControls.Controls.Add(new TextBox());
}

When the page is loaded for the first time, 2 textbox controls are added to the page. When you click the button, only one textbox is shown. This is because the check to see if the page is a postback stops the first two textboxes from being loaded. Removing this line will mean that when you click the button three textboxes are shown on screen.

If you keep clicking the button, only three textboxes will be shown. This is because the controls do not survive the postback event and so are recreated new every time. So in this way this is one of the reasons I will use the repeater model to create dynamic controls.

How to do this using a basic textbox control will be covered in the next post.

Dynamic User Controls – Part 1 – Session Intro

I recently gave three talks around Ireland on this topic for the Irish Microsoft Technology User Group (MTUG). I travelled to Derry, Dublin and Cork over three days and met some great folks. I was also very lucky to be presenting on the same night as Adam Kinney from Microsoft which was an excellent chance for me to get some news on Silverlight and the new bits from MIX10. A big thanks to Alan Bradley, David Gargan and Joe Gill on the MTUG side and Martha Rotter and Enda Flynn from Microsoft for facilitating this and also making sure I got to where I was supposed to go.

As promised to all those who attended my talks I am posting the session as a series of blog posts along with the bits from the sessions. The bits can be downloaded in 3 versions

If you are using the Visual Studio 2010 RC version make sure to download the Designer patch for the RC. This version will also work with the Beta 2 version of Visual Studio 2010.

So on with the speaker bits. I am not putting the PowerPoint online as it does not contain anything other than pictures and some text and its pretty useless without the speaker notes. So I am going to instead to put the speaker notes in this blog post with the PowerPoint slides as images.

WhyDoYouWantDynamicControls

The first question you should be asking is why do you want user controls in the first place. And the answer is usually one of the following three options

  • You don’t know the number or type of controls that you will need until runtime. This is possibly the most common reason to use dynamic controls.
  • You have a large number of the same type of control that you need to add to the application and you don’t want to spend the time manually putting them onto the design surface. Most people will be familiar with this because I doubt you have ever manually created 100 list items in a DataList for example
  • And finally its because of an architectural decision such as a custom server control and you have no choice.

 

 

The next question is what is the different between static and dynamic controls. Well firstly static controls StaticVsDynamicControls 

  • Can be added to the design surface at design time
  • They can be programmed against with intellisense because they are in the .designer.cs file
  • And finally they survive post back and the page life cycle.

On the other hand dynamic controls

  • Dynamic controls are added to the page control tree at runtime
  • They cannot be programmed against using intellisense in the traditional way. You can declare an object of the type of control and bring it to your instance of the control and program against it in that way
  • Dynamic controls do not survive the post back unless you give them a place to stay. And that is the crux of the problem involving dynamic controls.

PostBack

 

Now that we know what the issue is how do we solve it. Normally when you are using dynamic controls you add the controls to a placeholder and this works ok to a point. A better way of doing it is to use a repeater with a placeholder in the ItemTemplate and use custom methods of the ItemCreated and ItemCommand events. There are a few good reasons for this.

  • You can databind your list to your repeater allowing to quickly create a lot of controls
  • You can make your controls have databinding properties.
  • You can use the fact that the repeater is IEnummerable to get the information in and out
  • The ItemCommand event allows you to handle events from your controls
  • And finally it gives you a way to easily store state by using the repeater.

 

 

So that was the intro part of the session. As you can see I didn’t use a lot of time in PowerPoint because I believe that developers learn better from seeing the code rather than from a slide deck. The next posts will be all on the code parts of the sessions.

If you want to learn more about the whole viewstate relationship with dynamic controls you can read Dave Reed‘s excellent blog posts on the subject. I would like to take this chance to thank him for his kind permission in allowing me to use some of his material for my sessions.

Setting up Visual Studio 2010 for presentations

Lately I have been giving a couple of talks and they are mainly code demonstrations. So you really need to make sure you have your Visual Studio set up correctly to handle the different way you write code when you are presenting as compared to normal development.

Some essential things.

  • Increase the size of your font
    • This is possibly the single biggest thing (pardon the pun) that you can do to increase the takeup and attendee satisfaction is to increase the size of your font to a decent size that works well on projector screens. Thanks to Scott Hanselman who suggested in his blog post that you should use Lucida Console 14 to 18pt and bolded. Believe me it works and allows your audience to actually read your code.
    • You can also use the command line devenv /fs 16 to increase all the font sizes in the menus to 16 for example. You can reset it back using devenv /fs 8 . But you don’t need to do this if you aren’t showing off any menu options.
  • Adjust your IDE color
    • I know i know, your IDE color is your own. But I am fan of the plain standard white background with the standard keyword colors. Its just a bit easier. However if you do find a color scheme that works on a large screen to a diverse audience please do let me know
  • Use snippets
    • Snippets are your best friend. Use them. You don’t have to use them for everything but if you are doing a decent amount of code its helps you if you make it a mistake. And remember the keystrokes CTRL+K followed by CTRL+X to bring up the snippets menu.
    • There are a number of snippet designer tools such as Snippet Designer which allows you to to create your snippets in the IDE. Make sure to add descriptions to your snippets so you can see what they do without have to read the name.
    • I also create folders for my demo snippets and in the title I number them so I can find them easily. In the last set of demos, I had them labeled with numbers that corresponded to the section I was demonstrating in.

Now some additional tools for Visual Studio 2010. There is an excellent free tool called Custom Intellisense Presenter which allows to show the intellisense popup in a higher more visible which for your audience is very handy as they can read and hopefully understand while you are coding. Also with the snippets it will display your description which will help you when you are coding.

There are also custom zoom tools which can be found here and also the very handy windows key + (+) key to zoom in if you don’t find anything that works for you.

And finally make sure your code compiles :)