Friday, April 15, 2011

First Foray into Windows Home Server (WHS)

I just inherited an HP EX485 MediaSmart Server in near new condition. First impression is that it is *tiny* — about as tall as a college textbook standing on edge and six inches wide. WHS machines are network-ready, do not have a VGA output nor display adapter and typically have multiple drive bays designed for adding low cost serial ATA (SATA) drives as storage needs grow. system_diskThe EX485 comes with a single 750 GB drive partitioned with a small 20 GB system (“C:\”) and the remainder as a large “D:\” data drive.The specifications state that fully loaded with four drives it will consume a paltry 76 watts of power!

WHS is an interesting, strange brew – a fully-functioning Windows server product with an easy to use setup and interface sold only to OEMs. The intention is to provide something dead-simple to setup that consumers can take home, plug-in and it just works. Scott Hanselman wrote a nice introductory review of WHS and the MediaSmart here. As the name suggests, the EX485 is designed to store and serve media – movies, music and photos.

whs_consoleUnder the covers WHS v1 is Windows Server 2003 so it’s a solid and reliable server platform. It exposes a user-friendly console that OEMs can extend to provide functionality as shown here. Notice the small link indicated in the upper right that opens a settings panel where you can configure the server – again the dialog is extensible by OEMs.

whs_upnpWHS supports universal plug and play (UPnP) so other machines in your home network can discover and access it. From there you can install a client “connector” that gives you access to the console shown above. Connecting a client machine is sort of like an ultra-light version of joining a domain without the intrusive “taking over”.

Client computers will get a “Shared Folders” link on their desktop that shows all the pre-configured shares (e.g. Documents, Music, Photos, Videos) on the server as well as any custom ones you’ve added. A “Windows Home Server Connector Service” will be installed along with a system tray icon and nightly backups will be configured.

ex485_serverWindows Home Server 2011 (a.k.a. v2) was released a couple of weeks ago. While articles are popping up that show how to wipe the existing v1 and install the shiny new toy I’m going to stay put. I’m currently running HP MediaSmart Server v2.5.15.35297 which was released in April 2009. The system shipped with this configuration and it’s got the latest patches and updates. I expect to be running this until the hardware fails or becomes so outdated that it becomes compelling to update to a newer platform.

Friday, December 24, 2010

How To Build an ASP.NET 4.0 Web Service and Consume It With Excel 2007-Part 2

With a freshly built web service we can now have a bit of fun.
  1. Create a new project utilizing the Visual Studio Tools for Office template for Excel 2007 Workbook:
    2010-12-05_091921
  2. Accept the default settings for Create a new document and click OK:
    2010-12-05_091937
    Note: if you encounter errors while creating a new project it is most likely because the VSTO add-ins are not configured until first used.
    2010-12-05_091947
    The quickest way to resolve the issue is to exit out of Visual Studio and use the right-click Run as administrator trick to launch with elevated permissions.
  3. From the Solution Explorer, right-click on the References folder then choose Add Service Reference:
    2010-12-05_092357
  4. Type in the web address of the web service we just created:
    2010-12-05_092441
    Hint: You may want to switch (Alt-Tab) over to the browser window where we tested the web service against IIS after deploying then copy the address from the address bar.
  5. After pressing Go the deployed web service will be queried and the results displayed for confirmation:
    2010-12-05_092507
  6. With the Excel Workbook Designer displayed from within Visual Studio right-click anywhere on the worksheet and choose View Code:
    2010-12-05_092756
  7. Create a new method called DisplayCustomer containing the following code:
    public void DisplayCustomer(int customerKey)
    {
    // Call the Web service.
    using (var service = new
    Assignment3Service.WebServiceSoapClient())
    {
    var result = service.GetCustomerByKey(customerKey);
    if (result != null)
    {
    var items = result.Tables["Customer"]
    .Rows[0].ItemArray;
    var limit = items.GetLength(0);
    for (int i = 0; i < limit; i++)
    {
    var item = items[i];
    this.Cells[1, i + 1] = item;
    }
    }
    }
    }

  8. Right-click on the Excel Workbook project and choose Add New Item:
    2010-12-05_093805
  9. Select Office under the Visual C# Installed Templates then choose Ribbon (Visual Designer) and click Add:
    2010-12-05_093910
  10. From the Toolbox drag an EditBox control then a Button control onto the designer surface:
    2010-12-05_094125
    Resulting in the following:
    2010-12-05_094212
  11. Clean up the Labels to make the Ribbon more meaningful and useful:
    2010-12-05_094313
    2010-12-05_094332
  12. The completed Ribbon should look similar to this:
    2010-12-05_094451
  13. Double-click on the Search button (text) on the Ribbon to jump to the event-handler section. Put the following code to call the add-in method DisplayCustomer previously created:
    private void btnSearch_Click(object sender, RibbonControlEventArgs e)
    {
    Globals.Sheet1.DisplayCustomer(int.Parse(CustomerKeyBox.Text));
    }

  14. Notice as you start typing that Intellisense will provide filtered statement completion:
    2010-12-05_094538
  15. Here is the completed method:
    2010-12-05_094721
    Pay attention to the name of the control (shown as “CustomerKeyBox” above) – this name must match the name you gave to the EditBox control immediately preceding this step.
  16. Now press F5 to debug the solution. Doing so will launch Excel 2007 (or Excel 2010) and you’ll notice the Add-Ins tab of the Ribbon UI displays your custom fields:
    2010-12-05_094814
  17. Simply type in a customer number then click Search, the results should look something like this:
    2010-12-05_110725
At this point we have used a custom add-in running on a client desktop to invoke a web service published and deployed in IIS which in turn connects to a SQL database to execute a query using the data supplied by the client (customer key value) and the results are returned and displayed in Excel.

Wednesday, December 22, 2010

How To Build an ASP.NET 4.0 Web Service and Consume It With Excel 2007-Part 1

This short series builds upon the previous How to Build a 2-Tier ASP.NET 4.0 Web Site (Parts 1, 2, 3). If you’re jumping in here you’ll need to adjust accordingly.
  1. Right-click on the web project in Solution Explorer, choose Add New Item:
    2010-12-04_221654
  2. Ensure that Visual C# is chosen under Installed Templates on the left, select Web Service:
    2010-12-04_221753
  3. Replace the default boilerplate code show here:
    2010-12-04_221902
    With the following code (begin replacement on line 10 above):
    [WebService(Namespace = "http://pragmatic/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class WebService : 
          System.Web.Services.WebService {
    [WebMethod]
    public DataSet GetCustomerByKey(int CustomerKey)
    {
      DataSet resultSet = new DataSet();
      SqlConnection conn = new SqlConnection(
      ConfigurationManager.ConnectionStrings["AdventureWorksDW2008R2ConnectionString"]
         .ConnectionString);
      using (SqlCommand cmd = new SqlCommand(
    @"SELECT [LastName], [FirstName], [MiddleName], [BirthDate], [EmailAddress], [Phone] 
    FROM [DimCustomer] 
    WHERE ([CustomerKey] = @CustomerKey)"))
      {
      cmd.Parameters.AddWithValue(
                "@CustomerKey", CustomerKey);
      conn.Open();
      cmd.Connection = conn;
      SqlDataAdapter dataAdapter = 
            new SqlDataAdapter(cmd);
      dataAdapter.Fill(resultSet, "Customer");
      }
      return resultSet;
    }
  4. Here is the resultant web service code-behind file:
    2010-12-04_223404
  5. Explanation of above lines:
    10: Replace default namespace with meaningful one.
    12: Define a web method called GetCustomerByKey which accepts an integer assigned to the variable “CustomerKey” and returns an ADO.NET DataSet object.
    17: Declare an ADO.NET DataSet that will be populated with the results of the Sql query.
    19-20: Declare an ADO.NET SqlConnection used to connect to the Sql database *AND* initialize the connection string using the same value previously stored in the configuration file from Part 3. Note that your connection string value (shown here as “AdventureWorksDW2008R2ConnectionString” may be different. Open web.config file to obtain the actual value to use from the “name=” attribute:
    2010-12-05_114702
    22-24: Construct a SqlCommand using the same SELECT statement previously used in Part 3. Note the “@CustomerKey” parameter token.
    26: Add an entry for the @CustomerKey parameter token and set its value to be the variable that is passed into the web method.
    27: Open the connection to the database.
    28: Associate the open connection to the SqlCommand object so the command will use it.
    29: Declare an ADO.NET DataAdapter and associate it to the SqlCommand object. This “magic” object will take care of a TON of work executing the Sql statement, taking the query results returned from the database and filling the collection of .NET DataSet objects (tables, rows, columns, values) with the result of the query.
    30: Simple little statement calling the Fill method of the DataAdapter, giving it the command to use and the dataset to be filled. This is the truly “magic” part of high-level object oriented programming.
    32: Return the populated dataset to the caller of this method.
  6. To test the web service, simply press “F5” or click the green arrowhead on the toolbar next to “Debug”. When the web browser comes up, type the name of the web service file in the address bar and hit enter:
    2010-12-04_224423
    Remember that your port number may be different than the :1483 shown above – that’s okay.
  7. You should see the sample web service test page shown here:
    2010-12-04_224441
  8. Click the “GetCustomerByKey” hyperlink and you’ll see the test page for the web method:
    2010-12-04_224514
  9. Input a value, such as 11000 and click invoke to see the results of the web method:
    2010-12-04_225618
  10. You can re-publish the website as shown in the first few steps of Part 3 – no need to go through all the one-time configuration steps however. Verify the web service is published by opening a browser and typing in the correct address:
    2010-12-04_232205
Next time we’ll use Excel to quickly test consuming the published web service with very little effort.

Monday, December 20, 2010

How To Build a 2-Tier ASP.NET 4.0 Web Site–Part 3

Now that IIS 7.5 is installed on Windows 7 let’s move on to deploying the website to IIS and testing it there.
  1. From the Build menu choose Publish Web Site:
    2010-12-01_232940
  2. You can either accept the default location or change it to something else:
    2010-12-01_232958
    Make note of the location chosen as you will need it shortly.
  3. Now let’s configure the website in IIS 7. Launch IIS manager from Control Panel | Administrative Tools | Internet Information Services (IIS) Manager:
    2010-12-01_225342
    2010-12-01_225416
    Hint: IIS Manager is the configuration tool for IIS and you’ll be jumping into it often. You can use the Run dialog for faster access via the Windows + R then typing “inetmgr”:

    2010-12-01_225504
  4. Expand the tree control on the left, right-click on Default Web Site then right click and choose Add Application:
    2010-12-01_233031
  5. Type in an Alias name that will be used as the website name when browsing, Select the ASP.NET v4.0 Application pool and choose the same Physical path where you just published the website to previously. You should click the Test Settings button to verify that Authentication and Authorization are configured correctly:
    2010-12-01_233205
    2010-12-01_233703
  6. If you received the above Authorization error it means that IIS does not have permission to access the folder where you published the website to. If this occurs, click Close then OK to complete the creation of the application. Back in the tree view control right-click on Edit Permissions to grant the IIS web server permission to the publish folder:
    2010-12-01_233315
  7. On the Security tab choose Edit, then Add, then Advanced, and finally Find Now:
    2010-12-01_2333482010-12-01_2334042010-12-01_2334232010-12-01_233445
  8. From the list of users and groups use Control + click to select the follow three:
    • IIS_IUSRS
    • IUSR
    • NETWORK SERVICE
    2010-12-01_233512 Now you can click OK through until the dialogs are dismissed, right-click on the Website in the tree control again and choose Edit Application where you can Test Settings again.
  9. When testing from within Visual Studio we are running under the permissions of ourselves – the account we signed into Windows with. When browsing against IIS, it is IIS that is connecting to the database. Since the IIS web server will be acting as a proxy for the user when accessing the database, you must grant the IIS user permission to the database. Using SQL Server Management Studio, execute the following T-SQL statements:
    CREATE LOGIN [IIS APPPOOL\ASP.NET v4.0] 
      FROM WINDOWS 
      WITH DEFAULT_DATABASE=[master], 
      DEFAULT_LANGUAGE=[us_english]
    GO
    
    CREATE USER [AdventureWorksUser] 
      FOR LOGIN [IIS APPPOOL\ASP.NET v4.0]
    GO
    
    EXEC sp_addrolemember 'db_datareader', 'AdventureWorksUser'
    GO
    

    2010-12-02_000021
  10. Finally right-click on the website again, choose Browse:
    2010-12-01_233228
  11. Sit back and enjoy the fruits of your hard labor:
    2010-12-02_000036
While testing the site in IIS is not absolutely required, it is helpful to go through the publishing process to help shake out potential problems such as the fact that IIS runs under a service account and not the you (the logged in user) the way Visual Studio’s build in web server does.

Saturday, December 18, 2010

TD Bank website team is sloppy

Hmmm…Saturday before Christmas here in the U.S. of A., major banking site, error page like this:

TDBank_error

I’ve been developing in ASP.NET since 2002 so I think I can safely say that somebody screwed up and they’ve got some sloppy practices in place!

Looks like ‘Banknorthct’ is a valid #bankid# token in case you’re trying to discover information about their site. Also, they like to use D:\websites to store their site files in so hackers shouldn’t have to go hunting for that configuration detail. Finally, they’re running .NET 2.0 which means it’s a lot easier for folks to attack because they can immediately try all known exploits.

Do I seem too harsh? Well, two simple steps would’ve prevented this:

  1. Turn ‘RemoteOnly’ back on in your web.config – someone explicitly changed it from the default value.
  2. Code a custom error page possibly with a redirect so the customer doesn’t see your dirty underwear!!

Tell me again how much banks got for a bailout in ‘09 and ‘08 and how much profit are they raking in now?