This blog has moved, permanently, to http://software.safish.com.
Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, January 27, 2011

WCF Quick and Dirty

I added some WCF services to an existing project today, and I found I had completely forgotten the easy way of setting this stuff up.  So, here goes.  Note that you will usually split your host and consumer between separate projects – this is just an outline of the basics when working with Visual Studio 2010 and isn’t really concerned with actual implementation.

Create the DataContract Classes

These are the classes that will be serialized and submitted by WCF.  For example, if you are creating a service to add two numbers, you would have a class like so:

[DataContract] 
public class ExampleDataContract 
{ 
 [DataMember] 
 public int Num1 { get; set; } 

 [DataMember] 
 public int Num2 { get; set; } 
} 

Create the Service

Now that we have the data contract, we can create the actual service. 

  1. Navigate to the location in your solution where the service will sit, and add a new item (a WCF Data Service).
  2. The service is now created.  The interface should be decorated with a ServiceContract attribute.
  3. Any methods added to the interface will need to be decorated with an OperationContract attribute.
  4. In terms of the contract implementation, you will need to decorate your class with a ServiceBehavior attribute.  For example:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode = AddressFilterMode.Any)] 

Configure the Service

You can manually configure your service in your App.config file, but there is actually a GUI that makes this a lot easier.  All you need to do is righ-click your config file and there will be an option to Edit WCF Configuration – click this to launch the editor.

Note that if your project is not a WCF project, this may not be available in the context menu.  There’s an easy work-around for this though:

    1. Select Tools->WCF Configuration Editor from the Visual Studio menu, and click WCF Configuration Editor
    2. Close the WCF Configuration Editor

Now when you right-click the App.config the Edit WCF Configuration option should be available.

Usually there shouldn’t be too much to change here unless you’re manually creating your endpoints/services.  If you’re just wanting the basic endpoints, you can give the endpoints names (e.g. AddNumbersHttp for the wsHttpBinding) and continue.

We now have enough set up to host and test the service.

Test the Service

Visual Studio 2010 makes testing WCF apps really simple.  If you’re working with a WCF project, when you run the project Visual Studio will fire up the WCF test client by itself.

If you’re developing a web project, this won’t work, so you will need to fire up the client manually by opening a Visual Studio Command Prompt and typing the following:

wcftestclient http://yoursite/Services/YourService.svc.

If you get errors here, you may need to configure your web site.  There are two possible issues:

  1. IIS has not been configured to handle the .svc extension.  This is easily fixed by running the registration tool that comes with .NET – run ServiceModelReg.exe -i from the "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation" directory
  2. If you are getting an error that the service cannot be activated because it does not support ASP.NET compatibility you can either configure your application for compatibility mode, or mark your service implementation with the following attribute:
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

Create the Client

You can now create the client that will consume the services created above. 

  1. Right-click your project’s References, and click Add Service Reference
  2. If you want to use a service within another project in your solution, you can click the Discover button and select Services in Solution
  3. Select the service, and enter a namespace that will be used within the client project to refer to the service
  4. You can now use the service like any other C# class, for example:
    MyServiceNamespace.MyServiceClient client = new MyServiceNamespace.MyServiceClient();
    client.AddNumbers(1, 2);
    client.Close();
    

Resources

  1. http://msdn.microsoft.com/en-us/netframework/dd939784
  2. http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/

Wednesday, September 8, 2010

.NET – Detecting Modem COM Ports

We have a project at the moment where we’re using GSM modems attached to the local machine to send an SMS.  One of the issues we’ve had is when the modem is not actually connected before our service starts up: our service sometimes attaches to the COM Port that is required by the modem, and this prevents the modem from ever connecting.

There is a simple way to detect which COM ports are assigned to modems installed on your machine:

using System.Management;

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_POTSModem");
foreach (ManagementObject mo in mos.Get())
{
    string s= mo["AttachedTo"].ToString();
}

Other properties available can be looked up here: http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx

Thursday, August 26, 2010

Unit Testing and DateTime Comparisons

 

One thing I’ve found annoying for the long time, is trying to assert DateTime equality when unit testing, particularly when the DateTimes have been parsed from strings in the underlying method.  Two DateTime constructs, despite being identical in terms of their values, often won’t assert as being equal and your unit test fails.  As such, you end up doing other sorts of tests, for example checking the individual values.

To help test dates, what I’ve done is created a helper class for asserting two dates are “equal”, to a specifed level of precision:

public static class AssertHelper
    {
        /// 
        /// Asserts that two dates are equal by checking the year, month, day, 
        /// hour, minute, second and millisecond components.
        /// 
        /// The current date
        /// 
        public static void AreDatesEqual(DateTime expected, DateTime actual, DateTimePrecision precision)
        {
            if (precision >= DateTimePrecision.Year && expected.Year != actual.Year)
            {
                throw new NUnit.Framework.AssertionException("Year in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Month && expected.Month != actual.Month)
            {
                throw new NUnit.Framework.AssertionException("Month in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Day && expected.Day != actual.Day)
            {
                throw new NUnit.Framework.AssertionException("Day in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Hour && expected.Hour != actual.Hour)
            {
                throw new NUnit.Framework.AssertionException("Hour in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Minute && expected.Minute != actual.Minute)
            {
                throw new NUnit.Framework.AssertionException("Minute in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Second && expected.Second != actual.Second)
            {
                throw new NUnit.Framework.AssertionException("Second in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Millisecond && expected.Millisecond != actual.Millisecond)
            {
                throw new NUnit.Framework.AssertionException("Millisecond in dates do not match as expected.");
            }


        }
    }

    public enum DateTimePrecision
    {
        Year = 0,
        Month = 1,
        Week = 2,
        Day = 3,
        Hour = 4,
        Minute = 5,
        Second = 6,
        Millisecond = 7
    }
This effectively allows me to unit test that the dates were close enough, without worrying to much about the exact equality. This solution, although working, somehow feels dirty. I'd love to know if anyone else has any better solutions for unit testing date equality in .NET.

Friday, February 19, 2010

HTTP Pre-Authentication

Rick Strahl posted this excellent article on pre-authenticating HTTP requests - this is something that's caught me in the past but he explains the whole concept so well here I thought this was worth noting for my own future reference.

Friday, August 7, 2009

Backing up and Restoring SQL Server Databases with .NET

I need to create a tool that would do some backing up and restoring of databases as part of a long-running job this week. I had heard it was fairly simple C# code, but I was pleasantly surprised when I realised just HOW simple it is.

The namespaces of the SMO libraries required changed between 2005 and 2008, so if you're using the SQL Server 2008 objects, you need to reference the following libraries (usually located in C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\). If you're using SQL Server 2005 you only need the first two.

Microsoft.SqlServer.ConnectionInfo Microsoft.SqlServer.Smo Microsoft.SqlServer.SmoExtended Microsoft.SqlServer.Management.Sdk.Sfc

Backing Up Code

SqlConnection conn = new SqlConnection("ConnectionString!");
Server dbServer = new Server(new ServerConnection(conn));
Backup backupMgr = new Backup();
backupMgr.Devices.AddDevice("E:\Backups\YourFile.bak", DeviceType.File);
backupMgr.Database = conn.Database;
backupMgr.Action = BackupActionType.Database;
backupMgr.SqlBackup(dbServer);

Restoring Code

SqlConnection conn = new SqlConnection("ConnectionString!");
Server dbServer = new Server(new ServerConnection(conn));
Restore restoreMgr = new Restore();
restoreMgr.Devices.AddDevice("E:\Backup\MyFile.bak", DeviceType.File);
restoreMgr.Database = conn.Database;
restoreMgr.Action = RestoreActionType.Database;
restoreMgr.SqlRestore(dbServer);

Tuesday, May 19, 2009

Encrypting cookies with ASP.NET

I hadn't noticed it before, but ASP.NET provides a really simple way to encrypt your cookies. Cryptography is a field best left to the expert, but for simple encryption purposes this method is perfectly adequate.

First off, you will need to add an entry to your machine/web.config:
  <machineKey
    validationKey="AutoGenerate,IsolateApps"
    decryptionKey="AutoGenerate,IsolateApps"
    validation="SHA1" decryption="AES" />
You can then encrypt/decrypt as follows:
  // encryption
  var ticket = new FormsAuthenticationTicket(2, "", DateTime.Now, DateTime.Now.AddMinutes(10), false, "mycookievalue");
  var encryptedData = FormsAuthentication.Encrypt(ticket);

  // decryption
  string myValue = FormsAuthentication.Decrypt(encryptedData).UserData.ToString();

Thursday, May 14, 2009

Custom Dictionary Sections in .NET Config Files

When you need to add complex configuration structures to .NET config files, you will generally create your own custom configuration section classes, and implement them within your application. However, if you just need a standard key/value pair, you don't need a custom configuration type at all. Instead, you can just define a section using the System.Configuration.DictionarySectionHandler, and there you go - no code required.

Example

Say, for instance, you want a list of status codes that get checked by your application:

In the App.config, define the section and implement the required values:
<configSections>
<section name="StatusCodes" type="System.Configuration.DictionarySectionHandler"  />
</configSections>
...
<StatusCodes>
  <clear />
  <add key="2" value="Two" />
  <add key="3" value="Three" />
  <add key="4" value="Four" />
  <add key="5" value="Five" />
</StatusCodes>
To read these values in code, all you need to do is the following, and you have a Hashtable containing all the values defined in the config file:
Hashtable statusCodes = ConfigurationManager.GetSection("StatusCodes") as Hashtable;