Archive

Archive for the ‘Programming’ Category

Changing URL of Team Foundation Server 2010 Projects

April 11, 2011 Leave a comment

If you want to change the URL of your projects in Team Foundation Server, sometimes it’s as straightforward as changing one URL in a dialog box.  However, good luck with that.  Probably there will be network, software configuration and work-flow after effects you need to deal with, and I thought I’d put them all in one place to make it easier for others trying to change their project URL’s.

Here is a summary of what you may have to do, and these steps are covered in this post:

  1. Change default URL in TFS administrative control panel
  2. Add new registry entry to allow default machine name to be different from URL
  3. Change TFS web config file to include your new URL
  4. Add new project location URL in Visual Studio
  5. Unbind solution from source control that points to old URL
  6. Bind solution to source control that points to new URL

This first blog post is helpful in that the author will also deal with what has to happen if  TFS is linked to SharePoint.  If simply changing the name does’t work completely further on down in interactive posts, there is a reference to changing your registry.  You’ll need to add a DWORD to HKLM\System\CurrentControlSet\Control\Lsa and call it DisableLoopbackCheck as you can see in the screen shot below.

For me, this was only part of the solution.  The other was that I had to edit the web.config file of TFS to allow me to use the new url.  Here is the link to that post.

So, after changing the URL in the TFS control panel, changing the registry and reconfiguring the TFS web site web.config file I was able to access TFS from my new URL both inside and outside of my network.

One additional issue remains.  That is in Visual Studio, your project is bound to the old location and now you’ll not only have to bind your project to your new location, but you’ll have to remove all source code bindings from the old location and change them to the new location.

To add a new TFS location, go to Connect to Team Project and then click on the Servers… button.  Then Click on add, and enter in the name of your new URL as shown below.  The old name was MMANT4, and the new name is tfs.maltercorp.com:

Connect to new TFS

To remove source control bindings from the old URL, you access that through File/Source Control.  The menu items will be different given what Visual Studio detects.  I opened my project and because it had source control bindings pointing to a different location, I got a dialog box that told me it was going to open in disconnected mode.

When you do that and then open Source Control through the File menu, you’ll see choices to unbind which I did.  Then I went back in to File/Source Control and clicked on bind to source control.  I clicked through the error messages using the ignore button.  All history is retained.

I did not test this in a multi-participant team environment, so I don’t know what will happen if you have other developers.  I suspect that they will have to unbind and bind back to source control as well as bind to a new TFS server location.  I’m sure if there are a number of developers, this will require some coordination on your part.

If I had TFS to set up all over again, I would look into what it would take to create it with a URL that is useful to outside users.

None of this was hard to do, but there was a lot of stuff in many different places, and I thought putting it all together on one place would be useful.

Breaking out of HTTP.SYS hell


I am working on using SSL with WCF and when it came time for me to add a service reference for my project I kept getting the following error: “This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case.

I was able to access my SVC file in a browser using the new domain certificate I had created for the service website.  The certificate was issued by our domain certificate authority.   I was also able to access the WSDL file as well with no problems.

SecureService Service SVC File

SecureService Service SVC File

So, why was I getting an error when trying to create a service reference?  Because the web site’s http binding did not have a host header.  To add a host header to your website, open IIS Manager and click on the web site you want to configure.

IIS Manager

Next, click on the bindings link to open the Site Bindings dialog box.  Find the http type, click on it and then click on the edit button on the right to open the Edit Site Binding dialog box.

Site Bindings Dialog Box

In the Host name edit control, enter the friendly name you used when creating the certificate.  Don’t enter http or https.  Click ok.  Click Close to close the Site Bindings dialog box.

Edit Site Binding

Edit Site Binding

Now go back to your client and click on Service References and right click to get the popup menu and then click on Add Service Reference.  In the Address: edit control enter the URL of your service, and in the Namespace enter in the name you want for your service reference and then click go.

Add Service Reference

Add Service Reference

You should get a windows login dialog box.  Provide your login credentials and click on and you now have your service reference.

I don’t have a lot of experience with host headers other than having to use them when you only have a single IP address and want multiple web sites (not virtual websites, but top level websites) to share it.  When given a choice,  I opt for adding multiple IP’s on a NIC and then every website gets a separate IP Address and separate DNS address.

However, I guess now there are other reasons for using host headers, and breaking out of HTTP.SYS hell is one of them.

Categories: IIS, Programming, SSL, WCF

Creating a Dropdown in an ASP.NET GridView Control

December 25, 2009 Leave a comment

To create a Dropdown control in an ASP.NET GridView control, you create a template field and wire the behavior to populate the dropdown in the RowDataBound event of the GridView.  Here is a simple example.

In the GridView, we created the template field with an ItemTemplate and inserted the Dropdown control.  Also, note that we wired up the OnRowDataBound event in the GridView’s tag.

<asp:gridview id="gvSeminarSchedule" onrowdatabound="gvSeminarSchedule_RowDataBound"
	runat="server" autogeneratecolumns="False" onselectedindexchanged="gvSeminarSchedule_SelectedIndexChanged"
	onselectedindexchanging="gvSeminarSchedule_SelectedIndexChanging" datakeynames="SeminarScheduleID">
	<alternatingrowstyle cssclass="GridRowAlternate" />
	<rowstyle cssclass="GridRowStandard" />
	<headerstyle cssclass="ItemLabelCenter" />
	<selectedrowstyle cssclass="GridRowSelected" />
	<columns>
		<asp:boundfield datafield="SeminarScheduleID" headertext="ID" />
		<asp:boundfield datafield="FormattedStartDate" headertext="Seminar Start" htmlencode="false" />
		<asp:boundfield datafield="FormattedEndDate" headertext="Seminar End" htmlencode="false" />
		<asp:boundfield datafield="RegisterStartDateString" headertext="Register Start" />
		<asp:boundfield datafield="RegisterEndDateString" headertext="Register End" />
		<asp:boundfield datafield="RegisterEarlyPriceEndDateString" headertext="Register Early Price End" insertvisible="False" readonly="True" />
		<asp:templatefield headertext="Students">
			<itemtemplate>
				<asp:dropdownlist runat="server" id="ddStudent"></asp:dropdownlist>
			</itemtemplate>
		</asp:templatefield>
	</columns>
</asp:gridview>

In the page behind, we are testing for a DataRow, and if it is then we find the DropDown control instance for the row and populate it.

protected void gvSeminarSchedule_RowDataBound( object sender, GridViewRowEventArgs e )
{
	if ( e.Row.RowType == DataControlRowType.DataRow )
	{
		SeminarSchedule seminarSchedule = new SeminarSchedule();
		seminarSchedule.SeminarScheduleID = e.Row.Cells[ 0 ].Text.ToInt();
		DropDownList ddl = (DropDownList)e.Row.FindControl( "ddStudent" );
		ddl.DataSource = seminarSchedule.ListStudentsByNameLastFirst();
		ddl.DataMember = "PersonID";
		ddl.DataTextField = "FullNameLastFirst";
		ddl.DataBind();
	}
}
Categories: Programming

Supporting Multiple Dates in .NET Calendar Control

December 25, 2009 1 comment

This post will help you to support using multiple dates in a calendar control.  You will be able to populate your control with multiple dates from a data source, and then allow your users to interact with those selections, selecting or deselecting additional or existing dates for saving back to your data source.

The calendar control does not support databinding, so you have to use the DayRender event to make your selections appear.   You’ll also need to use the SelectionChanged event to manage selections and then some kind of a persistent storage that can live on the page like a session or use the viewstate bag.

So, anything coming in from the database gets handled in the DayRender event, and any changes get handled in the SelectionChanged event.  All of this should point to persistant storage such as a session variable or in the view state.  When you want to save what the user did, grab whatever you have in your session or view state and send it back to the database.

Here is my html for the control.

<asp:calendar id="cSeminarDate" runat="server" enableviewstate="true"
	daynameformat="Shortest" cssclass="CalendarStandard"
	onselectionchanged="cSeminarDate_SelectionChanged"
	ondayrender="cSeminarDate_DayRender">
	<dayheaderstyle cssclass="CalendarStandardDayHeaderStyle" />
	<daystyle cssclass="CalendarStandardDayStyle" />
	<nextprevstyle cssclass="CalendarStandardNextPrevStyle" />
	<othermonthdaystyle cssclass="CalendarStandardOtherMonthDayStyle" />
	<selecteddaystyle cssclass="CalendarStandardSelectedDayStyle" />
	<selectorstyle cssclass="CalendarStandardSelectorStyle" />
	<titlestyle cssclass="CalendarStandardTitleStyle" />
	<todaydaystyle cssclass="CalendarStandardTodayDayStyle" />
	<weekenddaystyle cssclass="CalendarStandardWeekendDayStyle" />
</asp:calendar>

What I did in this example was to create a session variable to store a List<DateTime>.   After populating my list with selected dates elsewhere in code, in the DayRender event (this event fires for every date in the calendar control), I compared the date that the control was currently drawing with my list, and if there was a match, I set the cell’s css class property to my selector style.

The following code is what I am using to populate my calendar control with selected dates.

protected void cSeminarDate_DayRender( object sender, DayRenderEventArgs e )
{
	List<DateTime> dt = SessionManager.GetInstance( HttpContext.Current ).SeminarDateList;
	foreach ( DateTime d in dt )
	{
		if ( d.ToShortDateString() == e.Day.Date.ToShortDateString() )
		{
			e.Cell.CssClass = "CalendarStandardSelectorStyle";
		}
	}
}

After I have my calendar populated with selected dates, my users are now in a position to deselect existing dates as well as to add new dates.  The following code below uses the SelectionChanged event in conjunction with the session.

protected void cSeminarDate_SelectionChanged( object sender, EventArgs e )
{
	if ( SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Contains(cSeminarDate.SelectedDate) )
	{
		SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Remove( cSeminarDate.SelectedDate );
		cSeminarDate.SelectedDates.Remove( cSeminarDate.SelectedDate );
	}
	else
	{
		SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Add( cSeminarDate.SelectedDate );
	}

	foreach ( DateTime dt in SessionManager.GetInstance( HttpContext.Current ).SeminarDateList )
	{
		cSeminarDate.SelectedDates.Add( dt );
	}
}

Where you see references to SessionManager.GetInstance( HttpContext.Current ).SeminarDateList, you can replace with Session[“SeminarDateList” ] as I manage my sessions explicitly in a single location.  Make sure to remember to clear your session when you init your page.  I have an InitUI() method I call if not a postback in the Page_Load event and elsewhere.  In there I do this 

SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Clear();

Hope this helps.

Break out of WebForm_DoPostBackWithOptions Hell

October 28, 2009 2 comments

I have been going nuts all day trying to get a link button to fire its command event and cause a postback in a GridView control.  On this particular page, whenever I click on the link, I get a WebForm_DoPostBackWithOptions instead of __doPostback, and of course I never hit the grid’s command event in my page behind.

The solution?  Set causesvalidation=”false” in the link button and the command event will fire.   Why, I don’t know, this just works and hopefully you’ll find this post before having to spend too many hours trying to figure it out.

Mapping .NET CLR Datatypes with SQL Server 2008 Parameters

October 12, 2009 Leave a comment

The following table maps .NET CLR datatypes with SQL Server parameters.  The full Microsoft article is here.

SQL Server data type CLR data type (SQL Server) CLR data type (.NET Framework)
bigint SqlInt64 Int64, Nullable<Int64>
binary SqlBytes, SqlBinary Byte[]
bit SqlBoolean Boolean, Nullable<Boolean>
char None None
cursor None None
date SqlDateTime DateTime, Nullable<DateTime>
datetime SqlDateTime DateTime, Nullable<DateTime>
datetime2 SqlDateTime DateTime, Nullable<DateTime>
DATETIMEOFFSET None DateTimeOffset, Nullable<DateTimeOffset>
decimal SqlDecimal Decimal, Nullable<Decimal>
float SqlDouble Double, Nullable<Double>
geography SqlGeographySqlGeography is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. None
geometry SqlGeometrySqlGeometry is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. None
hierarchyid SqlHierarchyIdSqlHierarchyId is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. None
image None None
int SqlInt32 Int32, Nullable<Int32>
money SqlMoney Decimal, Nullable<Decimal>
nchar SqlChars, SqlString String, Char[]
ntext None None
numeric SqlDecimal Decimal, Nullable<Decimal>
nvarchar SqlChars, SqlStringSQLChars is a better match for data transfer and access, and SQLString is a better match for performing String operations. String, Char[]
nvarchar(1), nchar(1) SqlChars, SqlString Char, String, Char[], Nullable<char>
real SqlSingle Single, Nullable<Single>
rowversion None Byte[]
smallint SqlInt16 Int16, Nullable<Int16>
smallmoney SqlMoney Decimal, Nullable<Decimal>
sql_variant None Object
table None None
text None None
time TimeSpan TimeSpan, Nullable<TimeSpan>
timestamp None None
tinyint SqlByte Byte, Nullable<Byte>
uniqueidentifier SqlGuid Guid, Nullable<Guid>
User-defined type(UDT) None The same class that is bound to the user-defined type in the same assembly or a dependent assembly.
varbinary SqlBytes, SqlBinary Byte[]
varbinary(1), binary(1) SqlBytes, SqlBinary byte, Byte[], Nullable<byte>
varchar None None
xml SqlXml None

Hope this helps.

ASP.NET User Control events tamed through Page_PreRenderComplete

October 9, 2009 Leave a comment

Something that has been bothering me for a really long time is now under control thanks to a blog post in the .NET Geek’s Blog entry on Understanding the Page Life Cycle in ASP.NET.  In a nutshell, here is the issue.  I prefer to create user controls that wrap standard .NET controls and then put role enabled and other code into the controls.  That code determines if the control makes it self visible or disabled along with some other nice to haves.

The problem is that when a page first draws and fires off its events, the user control events follow, and if I come into the page wanting a button to be disabled in certian instances, the user controls resolve their states after the page.  So if I have a button in a user control and expose its Enabled property through a get/set variable, I can never make it stick when the page first draws.

In the source code below, I am using the Page_PreRenderComplete event to test for page state and call an appropriate method.  In this case the PrepUIforAdd is called and it disables a number of buttons as well other things.  If I called PrepUIforAdd in the Page_PreRender event, the buttons would never stay disabled.  But calling it in the Page_PreRenderComplete event will result in the outcome I want when the page displays.

		/// <summary>
		/// PreRender is complete
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void Page_PreRenderComplete( object sender, EventArgs e )
		{
			if ( !Page.IsPostBack )
			{
				ucErrorMessage.Clear();

				switch ( this.CurrentPageState )
				{
					case PageState.Add:
						{
							PrepUIforAdd();
							break;
						}
					case PageState.Edit:
						{
							PopulatePersonInfo();
							PopulateLinkedRoles();
							PopulateUnlinkedRoles();
							break;
						}
				}

				this.ManagePersonTabContainer.ActiveTabIndex = 0;
			}
		}

		/// <summary>
		/// Preps UI for adding a person
		/// </summary>
		private void PrepUIforAdd()
		{
			this.txtPersonID.Text = (PersonIDConstant.Everybody.ToInt()).ToString();

			this.txtLastName.Text = string.Empty;
			this.txtFirstName.Text = string.Empty;
			this.txtLogin.Text = string.Empty;
			this.txtPassword.Text = string.Empty;
			this.txtInceptionDate.Text = string.Empty;
			this.txtLastModifiedDate.Text = string.Empty;
			this.txtLastModifiedByPersonName.Text = string.Empty;
			this.ddActive.YesNoID = 1;
			this.ddDeleted.YesNoID = 0;

			lbRolesAvailable.Clear();
			lbRolesSelected.Clear();

			this.bDelete.Enabled = false;
			this.bNew.Enabled = false;
			this.bResetPassword.Enabled = false;
			this.bRoleLink.Enabled = false;
			this.bRoleUnlink.Enabled = false;

			ddEmailType.Clear();
			List<EmailCollection> dt = GetCachedEmailList();
			if ( this.ErrorLevel == Status.Success )
			{
				ddEmailType.DataSource = dt;
				ddEmailType.DataTextField = "EmailTypeName";
				ddEmailType.DataValueField = "EmailTypeID";
				ddEmailType.DataBind();
			}

			this.txtEmail.Text = GetCachedEmailAddress( PersonIDConstant.Everybody.ToInt(), ddEmailType );
		}

%d bloggers like this: