I added a new method to my Domain Service today that has the signature:

public string[] GetSomething(string param1)

When I tried to compile this I got the following error, without any line or column information in Visual Studio’s Error List:

Type ‘String’ is not a valid entity type. Entity types cannot be a primitive type or a simple type like string or Guid.

After a bit of googling I found that returning a string is fine, but returning a string array is what’s causing the error. Lots of forum posts/blog entries recommend adding the ServiceOperation attribute to the method but I couldn’t find which namespace this was in.

I then found a breaking changed document for the PDC09 version of RIA services where it states that the ServiceOperation attribute was renamed to Invoke.

Simply adding the Invoke attribute to the domain service method enables a string array to be returned without any issues:

using System.ServiceModel.DomainServices.Server;

[Invoke]
public string[] GetSomething(string param1)

Detecting connection in Blackberry

Posted: 29th July 2010 by thegrayzone in Development
Tags:

This post is in response to an e-mail I received from Joerg. He was asking if I knew how to automatically switch on/off Bluetooth when a Blackberry is connected to an in-car charger.

I’m not sure if there has been a change in the most recent API but when I tried something similar using v4.5.0 of the Blackberry API it wasn’t possible to detect whether the handset is connected to an in-car charger. The way that I got round this is to detect whether the Blackberry is charging, this can be via normal charger or in-car charger.

To detect whether the handset is connected you can use the DeviceInfo class. I used the Java XOR operator (^), which returns 0 if both bits of the comparison are the same.

Below is some code to check if the battery is charging or using external power (fully charged and plugged in).

boolean charging = (DeviceInfo.getBatteryStatus() ^ DeviceInfo.BSTAT_CHARGING) == 0);
boolean pluggedIn = (DeviceInfo.getBatteryStatus() ^ DeviceInfo.BSTAT_IS_USING_EXTERNAL_POWER) == 0);

I’ve recently been using the Silverlight Report Viewer from Perpetuum Software. It’s the only real tool for viewing report services reports in Silverlight.

The Problem

Their start up example stores the report URL and data source credentials inside the web.config file. I wanted to encrypt these for added security and I also had to supply different report credentials, rather than using Windows credentials. The report credentials will be the same credentials that the user uses to login to the Silverlight application, to save them entering the credentials again.

The Code
using System.Configuration;
using System.Net;
using System.ServiceModel.Activation;
using System.Web;
using PerpetuumSoft.Reporting.Silverlight.Server.Core;
using PerpetuumSoft.Reporting.Silverlight.Server.ReportingServices;

namespace MyNamespace.Web.Services
{
  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
  public class ReportService : MsReportServiceRemote
  {
    protected override ICredentials GetServiceCredentials()
    {
      // Network credentials to access ReportServer
      return new NetworkCredential("username", "password");
    }

    protected override string GetServiceUrl()
    {
      // Returns url of ReportExecution2005.asmx
      return "http://127.0.0.1/ReportExecution2005.asmx";
    }

    public override ReportExecutionInfo LoadReport(string report, out ExceptionDetailBase ReportError)
    {
      // Call base.LoadReport to get ReportExecutionInfo, need this to get the DataSourceName and ExecutionID
      ReportExecutionInfo execInfo = base.LoadReport(report, out ReportError);

      if (execInfo.CredentialsRequired)
      {
        // Get users' credentials
        ReportDataSourceCredential[] credentials = new ReportDataSourceCredential[1] {
          // Credentials for report
          new ReportDataSourceCredential
          {
            DataSourceName = execInfo.DataSourcePrompts[0].Name,
            UserName = "username",
            Password = "password"
          }
        };

        // Set the data source credentials for report
        this.SetDataSourcesCredentials(execInfo.ExecutionID, credentials, out ReportError);
      }

      return execInfo;
    }
  }
}
Key Points
  1. Firstly override the GetServiceCredentials() and GetServiceUrl() methods and supply the required details, this saves putting these details into the web.config file.
  2. Override the LoadReport() method. The first thing we do in here is call base.LoadReport() as this gives us a ReportExecutionInfo object. We use this to get the DataSourceName, used when setting up the ReportDataSourceCredential object, and also the ExecutionID, which we use to call the SetDataSourcesCredentials method.

Background worker, passing and returning multiple parameters

Posted: 19th July 2010 by thegrayzone in Development
Tags:

I had a long running method that I decided to use the BackgroundWorker class to process. This process that the BackgroundWorker was running required multiple parameters to be passed to it, and it also returned multiple parameters back in the Completed method.

Rather than create a custom object like I had done in the past this time I decided to use the Tuple object to pass the multiple parameters.

Tuple Object

The Tuple object is very handy as it allows you to create a strongly typed object of up to 8 objects using the .Create() helper method, or if you need more than 8 objects you can use the standard constructor.

The Code

Below is some sample code, starting a BackgroundWorker object that takes in an integer, DateTime and a boolean. Once the background worker object has finished it returns a custom object, boolean and string.
Items within a Tuple object are accessed using the syntax:

myTuple.Item1;
myTuple.Item2;
using System;
using System.ComponentModel;

private void StartBackgroundWorker()
{
  BackgroundWorker worker = new BackgroundWorker();

  worker.DoWork += new DoWorkEventHandler(worker_DoWork);
  worker.RunWorkerCompleted += new  RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

  // Declare Tuple object to pass multiple params to DoWork method.
  var params = Tuple.Create<int, DateTime, bool>(44, DateTime.Now, false);
  worker.RunWorkerAsync(params);
}

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
  // Get Tuple object passed from RunWorkerAsync() method
  Tuple<int, DateTime, bool> params = e.Argument as Tuple<int, DateTime, bool>

  // Do some long running process

  // Set the result using new Tuple object to pass multiple objects to completed event handler
  e.Result = Tuple.Create<CustomObject, bool, string>(customObj, true, "hello");
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  // Get result objects
  Tuple<CustomObject, bool, string> res = e.Result as Tuple<CustomObject, bool, string>
}

In my previous post I wrote about overriding the LinqToEntitiesDomainService.CreateObjectContext() method to dynamically set the connection string for the used by the domain service.

I realised that I would be using this in a couple of different services in my current project and potentially use it in the future so I wrote a generic abstract class to enable me to do this.

The Class
using System;
using System.Data.Objects;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Server;

public abstract class DomainServiceBase <TContext> : LinqToEntitiesDomainService<TContext>
  where TContext : ObjectContext, new ()
{
  protected override TContext CreateObjectContext()
  {
    // Build up the connection string
    string connection = "connectionString";

    Type contextType = typeof(TContext);
    object objContext = Activator.CreateInstance(contextType, connection);

    return objContext as TContext;
  }

  protected override void OnError(DomainServiceErrorInfo errorInfo)
  {
    // Deal with errors
  }
}

You then inherit from this DomainServiceBase class for your Doman Services rather than LinqToEntitiesDomainService.

Key Points
  1. public abstract class DomainServiceBase <TContext> : LinqToEntitiesDomainService<TContext>
      where TContext : ObjectContext, new ()
    

    Generic class inherits from the LinqToEntitiesDomainService class. Constrain the types of objects that can be accepted to anything that inherits from ObjectContext and has a public parameterless constructor.

  2. Type contextType = typeof(TContext);
    object objContext = Activator.CreateInstance(contextType, connection);
    

    Use the Activator class to create an instance of the specified generic type, using the connection string that you have built up as a parameter. This will call the ObjectContext(string) constructor.

  3. return objContext as TContext;
    

    Cast the object to the supplied type before returning it.

The Problem

One of the requirements for a Silverlight 4/WCF RIA Service application that I am working on is that the connection string is stored encrypted within the web.config file. This left me with the problem that I would need to somehow unencrypt the connection string and manually set it before any database interaction was done.

Fortunately there is a virtual method inside the LinqToEntitiesDomainService class that is created, overriding this allows you to set the connection string before the database is accessed.

The Code

The below code shows an example of overriding the CreateObjectContext() method.

In the code I fetch the encrypted connection string from the web.config file, decrypt it and then return a new EntitySet using this connection string.

using System.Configuration;

[EnableClientAccess()]
public class TestDomainService : LinqToEntitiesDomainService<TestEntities>
{
  protected override TestEntities CreateObjectContext()
  {
    string encConnection = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
    string decConnection = encConnection.Decrypt();

    return new TestEntities(decConnection);
  }
}

Extra Information

There is another method of the LinqToEntitiesDomainService that came in very handy when I was figuring out the above code, this is the OnError method which, when overriden, gives you access to a DomainServiceErrorInfo object, allowing you to see details of any errors that occured.

For example, when I was running this code I had made a spelling mistake in my pre-encrypted connectionString.

Edit

I’ve written a new post about how to put this into a re-usable base class.

VB.NET Object Initializer and single line If statements

Posted: 4th June 2010 by thegrayzone in Development
Tags: ,

I’ve recently started working at a company that has quite a few VB.NET application sitting around, and as you can see from the rest of my posts I’m used to using C#

A couple of C# language features that I use a lot are Object Initializers and single line if statements. This might be old news to some of you but I finally discovered how to implement these two features in VB.NET. Both of the following features were introduced in VB.NET 9.0 (.NET 3.5).

Object Initializers

Take the following object initializer in C#

Person p = new Person
{
  Name = "Peter Piper",
  Age = 20
};

This can be replicated in VB.NET using the With keyword.

Dim p As New Person() With {.Name = "Peter Piper", .Age = 20}
Single Line If statement

To keep code clean and neat I often use the following syntax in C# (and Javascript) for single line If statements:

string name = person == null ? string.Empty : person.Name;

The VB.NET equivalent of this was introduced in VB.NET 9.0 and superceded the IIF function which evaluates all 3 parts of the function before calling it because it was a function rather than a tertiary operator.

Dim name As String = If(person Is Nothing, String.Empty, person.Name)

Setting maximum object size in WCF

Posted: 2nd June 2010 by thegrayzone in Development
Tags: ,

I have recently been working on a Silverlight application that uses WCF for all data access functions.

The application worked fine on my development machine but when I moved it over to a test environment I received the following, rather vague, error when making a few of the database calls:

“The remote server returned an error: NotFound”

After some debugging I realised that this happened when data being returned to the Silverlight application was too large, I then found the inner exception was:

Maximum number of items that can be serialized or deserialized in an object graph is ’65536′. Change the object graph or increase the MaxItemsInObjectGraph quota

The fix for this involves changing the MaxItemsInObjectGraph property for the service in both the client and the server code.

Server Side

The server side change is done within the web.config file of the web application that is hosting the Silverlight application. Add the following tag to the behavior tag for the misbehaving service:

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

This sets the maxItemsInObjectGraph = to Int32.Max. Now the fill behavior tag should look something like:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyService.Service1Behavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
.....
Client Side

I made the client side change in the code behind page within my Silverlight application. I added a service reference to the above WCF service, Service1, and rather than just declaring a new instance of Service1 the way I was originally doing it, like:

private Service1Client myService = new Service1Client();

I altered the declaration of my Service1Client variable to be:

private Service1Client _myService;
private Service1Client myService
{
  get
  {
    if (_myService == null)
    {
      BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
      binding.MaxReceivedMessageSize = 2147483647;
      Uri serviceUri = new Uri(App.Current.Host.Source, "../Service1.svc");

      _myService = new Service1Client(binding, new EndpointAddress(serviceUri));
    }
    return _myService;
  }
}

In the above code I manually declare a BasicHttpBinding object and set it’s MaxReceivedMessageSize to Int32.Max (default 65,536).

Using Int32.Max for these values is slightly overkill but it shows how you can limit the amount of data being passed from your service.

Checking for property differences in object

Posted: 14th May 2010 by thegrayzone in Development
Tags: ,

I recently had to come up with a way to check the properties to 2 similar objects and find any differences between them. The solution that I came up with was to write a generic extension method that compares the 2 objects and returns a list of ObjectDifferences objects. The ObjectDifferences class is as follows:

public class ObjectDifferences
{
  public string FieldName { get; private set; }
  public string OriginalVal { get; private set; }
  public string NewVal { get; private set; }

  public ObjectDifferences(string fieldName, string originalVal, string newVal)
  {
    FieldName = fieldName;
    OriginalVal = originalVal;
    NewVal = newVal;
  }
}

The Method

Below is the extension method that I ended up using for finding the difference between 2 objects. It takes in the object to compare to and a list of any fields not to compare. For example if you were comparing an object with a unique ID field, you might not want to compare this as it would always be different.

using System;
using System.Collections.Generic;
using System.Reflection;

public static IList<ObjectDifferences> GetDifferences<T>(this T originalValuesObj, T newValuesObj, params string[] ignore)
  where T: class
{
  if (originalValuesObj == null || newValuesObj == null)
  {
    throw new ArgumentNullException(originalValuesObj == null ? "Original" : "New");
  }

  List<string> ignoreList = new List<string>(ignore ?? new string[] { });

  IList<ObjectDifferences> differences = new List<ObjectDifferences>();
  Type type = typeof(T);

  foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
  {
    if (ignoreList.Contains(pi.Name))
      continue;

    object oVal = pi.GetValue(originalValuesObj, null);
    object nVal = pi.GetValue(newValuesObj, null);

    if (!object.Equals(oVal, nVal))
      differences.Add(new ObjectDifferences(pi.Name, oVal.ToString(), nVal.ToString()));
  }
  return differences;
}

Method Use

You can see the use of this method using the following example, using Person class with 4 properties (Forename, Surname, Age and Country).

Person p = new Person("Forename", "Surname", 19, "UK");
Person p2 = new Person("Forename", "Surname", 22, "USA");

List<ObjectDifferences> diff1 = p.GetDifferences(p2);
List<ObjectDifferences> diff2 = p.GetDifferences(p2, "Age", "Country");

In the above example, diff1 will contain 2 ObjectDifferences objects, one for Age and one for Country. diff2 will be empty because we are using the second parameter to specify that we want to ignore the “Age” and “Country” parameters.

Key Points
  1. Type type = typeof(T);
    
    foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    

    First we get the Type of the objects to be compared and enumerate through every Public and Instance property (specified using BindingFlags enum) in that type, getting a PropertyInfo object for each property.

  2. if (ignoreList.Contains(pi.Name))
      continue;
    

    As we enter the loop we check if the current property was specified in the ignore list, if it is continue to the next property.

  3. object oVal = pi.GetValue(originalValuesObj, null);
    object nVal = pi.GetValue(newValuesObj, null);
    
    if (!object.Equals(oVal, nVal))
      differences.Add(new ObjectDifferences(pi.Name, oVal.ToString(), nVal.ToString()));
    

    Lastly we get an object representing the value for the current property in the original and comparison object. We then compare these 2 objects using Object.Equals(Object, Object). If the objects are different we add a new ObjectDifferences object to the differences object, which is then returned to the calling method.

Limitations

There are a few limitations with this method. In my current project I use the above method on simple DTO objects with no complex types. If this was used, for example, on a LINQ2SQL model with a property that references another table then there might be issues, depending on how they check equality.

Setup Facebook Like Button and Like Box

Posted: 7th May 2010 by thegrayzone in Development
Tags: , , ,

I recently added a Like Button and Like Box to LesleyWilliamson.com. This is part of their new set of Social Plugins and was surprisingly easy.

There are 2 ways that you can add each of the plugins, I opted to use the XFBML option rather than the iframe method (which is easier!).

Initial Setup

Before you use the XFBML method you need to tell Facebook about your site to get an APP ID and use the Javascript SDK. To do this log in to Facebook and go to Create an application page and add in the required information. You will then be give an Application ID that you will need in the following code, which you will need to add just under the <body> tag of every page that you’re going to use XFBML functionality:

<script> window.fbAsyncInit = function() { FB.init({appId: 'YOUR APP ID', status: true, cookie: true, xfbml: true}); }; (function() { var e = document.createElement('script'); e.async = true; e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js'; document.getElementById('fb-root').appendChild(e); }()); </script>

If you are developing locally from the file structure you will need to change the line:

e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';

to

e.src = 'http://connect.facebook.net/en_US/all.js';

or it will try to find ‘file://connect.facebook.net/en_US/all.js’

Like Box

The Like Box allows you to view a live stream of what is happening on your Facebook page, along with any fans of the page. To add it, use the above script tag and then use the <fb:like> tag:

<fb:like-box profile_id="PAGE PROFILE ID" width="830" height="430" connections="0" stream="true" header="false" />

You can easily change the various options, like width, height, header etc. to get the box to look exactly how you want it. Check out the Like Box Reference for all options.

You must ensure that the Facebook page that you are displaying is open to the public by going to settings->edit and removing all age and country restrictions and setting the published status to “Published (publicly Visible)”.

Like Button

The Like button allows users with a Facebook account to ‘like’ your page and it will be displayed on their wall. You can use <meta> tags to set what appears on the users’ wall when they ‘like’ your page. You can use the following tags:

<meta property="og:title" content="Setup Facebook Social Plugins"/>
<meta property="og:site_name" content="The Gray Zone"/>
<meta property="og:image" content="http://www.thegrayzone.co.uk/someimage.jpg"/>
<meta property="og:type" content="website"/>
<meta property="og:url" content="http://thegrayzone.co.uk"/>
<meta property="fb:app_id" content="YOUR APP ID"/>

The last tag is important as without it, the like box won’t work and you’ll get the following nasty error:

You failed to provide a valid list of administrators. You need to supply the administrators using either a “fb:app_id” meta tag or a “fb:admins” meta tag to specify a comma-delimited list of Facebook users..

With the meta data tags setup all that needs to be done is add a <fb:like> tag onto your page:

<fb:like href="http://thegrayzone.co.uk" layout="button_count" show_faces="false" width="50" action="like" font="arial" colorscheme="dark" />

As with the Like Box you can change the various options to make it look exactly how you want it to, by check out the Like Button Reference.