Tuesday, October 2, 2012

IIS: Update Application Pool user passwords

Hi guys,
I wanted to share a short powershell script for updating Application Pool user's passwords.

Problem
You have Application Pools which are running with a user identity (Custom Account). When the user's password is changed, you have to update all Application Pools and set the new password.
For instance, if you're using your credentials for the Application Pools and you have a policy to change your password timely based, you have to go every time and change your password in the Application Pools users, too.

Why would I use my identity for an application pool? One reason I do it is so that I can easily start a SQL Profiler at any time, change the connection strings to use "Integrated Security" and capture all requests to the SQL server and filter them by my identity name.

Solution
Pretty straight-forward Powershell script - Get All Application pools on the IIS, which are with the identity you want. Iterate and update their passwords.

Import-Module WebAdministration
$applicationPools = Get-ChildItem IIS:\AppPools | where { $_.processModel.userName -eq "domain\username" }

foreach($pool in $applicationPools)
{
    $pool.processModel.userName = "domain\username"
    $pool.processModel.password = "newpassword"
    $pool.processModel.identityType = 3
    $pool | Set-Item
}

Happy scripting!

Thursday, January 26, 2012

Binding UI controls using Fluent API

Hi guys,

I've been working on ASP.NET Web Forms application for a while and have been constantly writing Data Binding on all kinds of containers - repeaters, list views, grid views and etc.

Let's imagine a very simple scenario. We have a Contact Class and Address Class. You get the Address of the Contact, using the Contact Id. In most cases, these objects will come from the databases, but for the purposes of this post, we don't need any complications. Therefore here are my classes:
namespace FluentBindingSample.Data
{
public class Address
{
public int ContactId { get; set; }
public string Country { get; set; }
public string City { get; set; }
public int PostalCode { get; set; }

public Address()
{
}
}
}
and
namespace FluentBindingSample.Data
{
public class Contact
{
public int ContactId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }

public Contact()
{
}
}
}

Now, here is a sample data provider, which will help us retrieve Contacts and retrieve data (currently, hardcoded):
using System;
using System.Collections.Generic;
using System.Linq;
using FluentBindingSample.Data;

namespace FluentBindingSample.Model
{
public class SampleDataProvider
{
public static IEnumerable< Contact > GetSampleContacts()
{
yield return new Contact { ContactId = 1, FirstName="Leo", LastName="Messi" };
yield return new Contact { ContactId = 2, FirstName = "Wayne", LastName = "Rooney" };
yield return new Contact { ContactId = 3, FirstName = "Christiano", LastName = "Ronaldo" };
}

public static Address GetAddressByContactId(int contactId)
{
switch (contactId)
{
case 1:
return new Address { Country = "Argentina" };

case 2:
return new Address { Country = "England" };

case 3:
return new Address { Country = "Portugal" };

default:
throw new NotSupportedException();
}
}
}
}
We're ready with our sample Business Layer. Now, let's bind this data to a Repeater:
<asp:Repeater ID="rptContats" runat="server">
<HeaderTemplate>
<table>
<thead>
<tr>
<th>
Contact Id
</th>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Country
</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="ltrContactId" runat="server" />
</td>
<td>
<asp:Literal ID="ltrFirstName" runat="server" />
</td>
<td>
<asp:Literal ID="ltrLastName" runat="server" />
</td>
<td>
<asp:Literal ID="ltrCountry" runat="server" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
We've finally set up our sample - we've reached the main point of this article. What I have always found boring is implementing an ItemDataBound event, getting all controls, casting and initiating them. I think this is a common problem and the code looks like this:
private void rptContats_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Contact contact = e.Item.DataItem as Contact;

Literal ltrContactId = e.Item.FindControl("ltrContactId") as Literal;
Literal ltrFirstName = e.Item.FindControl("ltrFirstName") as Literal;
Literal ltrLastName = e.Item.FindControl("ltrLastName") as Literal;
Literal ltrCountry = e.Item.FindControl("ltrCountry") as Literal;

ltrContactId.Text = contact.ContactId.ToString();
ltrFirstName.Text = contact.FirstName;
ltrLastName.Text = contact.LastName;

Address address = SampleDataProvider.GetAddressByContactId(contact.ContactId);
ltrCountry.Text = address.Country;
}
}

You see, we get all controls. Cast them, initialize them. Get some other things, related to the object and bind them too.
What are the problems of this approach - we do not have any code reusability. In case I want to show some Contact details in another Template Control I'll have to copy paste my whole code. The code is bloated - we say few things with much lines.
How can we improve the current situation? What I've come to useful in my projects is to implement a Fluent API. Let us see, how can Fluent API improve our code.
We first have to create the Interface of the API, itself. For our Contact and Address classes, this can look like this:
using System;
using System.Linq;
using System.Web.UI;

namespace FluentBindingSample.Model.Binders
{
public interface IContactBinder
{
IContactBinder WithTextControl(Control control, string controlName);

IContactBinder BindFirstName();

IContactBinder BindLastName();

IContactBinder BindContactId();
}
}

and
using System.Web.UI;

namespace FluentBindingSample.Model.Binders
{
public interface IAddressBinder
{
IAddressBinder WithTextControl(Control control, string controlName);

IAddressBinder BindCountry();
}
}

The implementation of this Fluent APIs is quite straight forward, too:
using System;
using System.Linq;
using System.Web.UI;
using FluentBindingSample.Data;

namespace FluentBindingSample.Model.Binders
{
public class ContactBinder : IContactBinder
{
private readonly Contact contact;
private ITextControl textControl;

private ContactBinder()
{

}

public ContactBinder(Contact contact)
{
if (contact == null)
{
throw new ArgumentNullException();
}

this.contact = contact;
}

public IContactBinder WithTextControl(Control control, string controlName)
{
ITextControl textControl = control.FindControl(controlName) as ITextControl;

this.textControl = textControl;

return this;
}

public IContactBinder BindFirstName()
{
textControl.Text = contact.FirstName;

return this;
}

public IContactBinder BindLastName()
{
textControl.Text = contact.LastName;

return this;
}

public IContactBinder BindContactId()
{
textControl.Text = contact.FirstName;

return this;
}
}
}

and
using System;
using System.Linq;
using System.Web.UI;
using FluentBindingSample.Data;

namespace FluentBindingSample.Model.Binders
{
public class AddressBinder : IAddressBinder
{
private readonly Address address;
private ITextControl textControl;

private AddressBinder()
{

}

public AddressBinder(Address address)
{
if (address == null)
{
throw new ArgumentNullException();
}

this.address = address;
}

public IAddressBinder WithTextControl(Control control, string controlName)
{
ITextControl textControl = control.FindControl(controlName) as ITextControl;

this.textControl = textControl;

return this;
}

public IAddressBinder BindCountry()
{
textControl.Text = address.Country;

return this;
}
}
}

Now we've come to the sweet part. Integrating the Fluent API in the Item Data Bound event:
private void rptContats_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Contact contact = e.Item.DataItem as Contact;

IContactBinder contactBinder = new ContactBinder(contact);
contactBinder.WithTextControl(e.Item, "ltrContactId").BindContactId();
contactBinder.WithTextControl(e.Item, "ltrFirstName").BindFirstName();
contactBinder.WithTextControl(e.Item, "ltrLastName").BindLastName();

Address address = SampleDataProvider.GetAddressByContactId(contact.ContactId);
IAddressBinder addressBinder = new AddressBinder(address);
addressBinder.WithTextControl(e.Item, "ltrCountry").BindCountry();
}
}

Now - this is much shorter, more readable and reusable. If I need to bind such information elsewhere, I have the functionality to do it and can just reuse it.
When can we use such approach?
- If we want to reuse code.
- If we want to encapsulate some logic - for instance formatting of the text, default values and etc.
What's the cost? We have to create Fluent API for the objects - this means little more developer effort in the beginning, which can be paid off later. It all depends on the case. If you have complex objects and functionality with formatting, default values and etc, I think such approach will armor you better than the simpler way.

The solution we outlined in this blog post can be downloaded from here:
Fluent Binding API Sample
Hope you found some ideas for yourselves in this post.

Happy Coding!