Test Run Deployment Issue

I replaced one of my test files with an image from the internet. I was a bit surprised when I got the following error when trying to run a test that was working just minutes before:

Failed to queue test run ‘MYCOMPUTER 2008-12-08 15:11:35’: Test Run deployment issue: The location of the file or directory ‘Tests\Material\TestPic.jpg’ is not trusted.

 

I then googled around and found the following thread on the MSDN forums: http://social.msdn.microsoft.com/Forums/en-US/vststest/thread/1a9c13b3-e8b9-4619-9159-3edbfc67b8a9/

 

What you need to do is unblock the file. Go to your deployment files folder and open the file properties:

 

Blocked file

 

 

Notice the security note on the bottom. Click on the Unblock button and also uncheck the readonly checkbox.

 

After pressing OK Visual Studio will again accept the file.

 

 

Advertisements

Combining Enums and Attributes

Enums are a porwerful and simple way to define standard and expected values. Enums can be easily linked with the database by storing the values as numbers or with XML data by storing the value names as text. The values can be easily converted and parsed both ways using the functions of the Enum class.

Linking enum values with the user interface is more tricky. Longer enum names are not very user friendly so you don’t want to display them directly. Combining attributes with your enums offers a flexible way to control how your enums are presented to the user.

First you need a custom attribute to decorate the values definitions with:

[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]
public class EnumDescriptionAttribute : Attribute
{
   public EnumDescriptionAttribute(string description)
   {
      Description = description;
   }

   public string Description { get; set; }
}

Then use your attribute to decorate your enums like this:

public enum PowerConsumtion { 
   [
EnumDescriptionAttribute(“Full power”)]
   High,
   [EnumDescriptionAttribute(“Energy saver”)]
   Low
}

Then all you need is a function extending the features of the Enum.GetNames() to return the user friendly names:

public static string[] GetNames(Type enumType, string group)
{
   List<string> names = new List<string>();
   Type type = enumType;

   FieldInfo[] fields = type.GetFields();

   for (int i = 1; i < fields.Length; i++)
   {
      FieldInfo field = fields[i];
      EnumDescriptionAttribute attribute = GetDescription(field);

      string descrption = field.Name;

      if (attribute != null)
      {
         if (attribute.Description != null)
            descrption = attribute.Description;
      }

      names.Add(descrption);
   }

   return names.ToArray();
}

private static EnumDescriptionAttribute GetDescription(FieldInfo field)
{
   EnumDescriptionAttribute[] attributes = field.GetCustomAttributes(typeof(EnumDescriptionAttribute), false) as EnumDescriptionAttribute
[];    
  
   if (attributes != null && attributes.Length > 0)
   {
      return attributes[0];
   }
   else
   {
      return null;
   }
}

 

You can now use the attributes to help you decorate the values with any kind of information. I usually have properties for hiding and groupping values. 

Closing Returned Streams in WCF

Streams should always be closed after usage to free the resources behind them. WCF web service functions returning values likes streams are no exception. You should never rely on your client to do this but for some reason many WCF streaming examples overlook this.

To correctly dispose return values WCF provides you with two options:

  • Setting the OperationBehaviorAttribute.AutoDisposeParameters to true
  • Using the OperationCompleted event.

I like to use the event as it gives me more control.

Here is what I think is a correctly implemented GetFile method:

public Stream GetFile(string path) {
   Sream fileStream = null;    

   try   
   {
      fileStream = File.OpenRead(path);
   }
   catch(Exception)
   {
      return null;
   }

   OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args)
   {
      if (fileStream != null)
         fileStream.Dispose();
   });

       return fileStream;
}

The dispose method should not throw an error even if the client has already correctly closed the stream.

More info: http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.operationcompleted.aspx

Serializing DateTime to XML

The XmlConvert class has been obsolete since .NET 2.0. I found this out when I needed to manually serialize and deserialize DateTime values to XML and all the examples used the old class. After some researching I found out that the following call will return the date time alue in the same format as the XmlSerializer uses:

DateTime.Now.ToString("o");
Returns “2008-11-17T12:28:09.9862678+02:00”

The value is easily converted back using the DateTime.Parse() function.

If you happen to need the functions of the XmlConvert class, you can achive the same results by combining the XmlSerializer with the TextWriter/TextReader classes. The following deserializes a XML value back to the correct type.

XmlSerializer dateSerializer = new XmlSerializer(type);
StringReader reader = new StringReader(stringValue);
return dateSerializer.Deserialize(reader);