Thursday, 27 October 2011

Handling WCF faults in Silverlight

Here’s a quick reminder to self about handling SOAP faults in Silverlight applications, something that happened recently and I forgot a simple step.

Before going any further read this (it will probably answer all your questions): Creating and Handling Faults in Silverlight

Firstly, I had a WCF service that was exposing faults contracts using the [FaultContract] attribute.

[ServiceContract(Namespace = "http://some_namespace_here/ConfigurationService/2011/10/01/01", Name = "ConfigurationService")]
public interface IConfigurationService
{
    [OperationContract(Name = "GetConfiguration")]
    [FaultContract(typeof(MyFault))]
    [FaultContract(typeof(ValidationFault))]
    ConfigurationResponse GetConfiguration(ConfigurationRequest request);
}

The service was implemented along with fault types, for example:

[DataContract(Namespace = "http://some_namespace_here/WIRM/2011/10/01/01", Name = "MyFault")]
public class MyFault
{
    [DataMember(IsRequired = true, Name = "FaultDetail", Order = 0)]
    public string FaultDetail { get; set; }

    [DataMember(IsRequired = true, Name = "FaultCode", Order = 1)]
    public string FaultCode { get; set; }
}

The problem was that back in Silverlight when I was handling exceptions generated from service calls the exception didn’t have the specific detail of the fault. The trick to making this work is in the article linked to above. We chose to use the “alternative client HTTP stack” approach by adding this to App.xaml.cs:

public partial class App : Application
{
    public App()
    {
        bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
        InitializeComponent();
    }
}

Thereafter it was possible to get at the actual fault exceptions and take advantage of specific exception details:

private void ClientGetConfigurationCompleted(object sender, GetGetConfigurationEventArgs e)
{
    if (e.Error == null)
    {
        // Do normal processing here...
        return;
    }
            
    if (e.Error is FaultException<ValidationFault>)
    {   
        var ex = e.Error as FaultException<ValidationFault>;
        // Do stuff with validation errors (via ex.Detail)
    }
            
    if (e.Error is FaultException<MyFault>)
    {
        var ex = e.Error as FaultException<WirmFault>;
        // Do stuff with MyFault (via ex.Detail)
    }
}

That’s it.

Wednesday, 19 October 2011

Feature layers not displaying when using the ArcGIS Silverlight API

I have been using the ArcGIS Silverlight API to create a mapping application. To provide some context, the application had to show a pipe network together with valves and other associated assets. The pipes were to be selectable in the interface so that pipe asset IDs could be used to drive queries and other processing.
In order to render the valves etc. I chose to use the ESRI FeatureLayer. I also used a FeatureLayer with a Mode of SelectionOnly for pipe selection.
One of the requirements of the system was that background imagery be used. This was created using an ArcGISDynamicMapServiceLayer. The feature layers and the background layer were taking their data from different ArcGIS services.
Although my code was using MVVM the scenario could be replicated in XAML like this (this is the map control XAML only with a number of layers omitted):
<esri:Map x:Name="AWMap">
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/backgroundservicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/featureservicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>

The problem

The problem was that as soon as the background layer was included the feature layers simply didn’t render. Handling the feature LayerInitialized and InitializationFailed events showed that the feature layers were initialised and that no errors were reported.
So what was going on?

The solution

After hours of head-scratching I reread the ESRI documentation and this popped out:
“By default, the first layer with a valid spatial reference defines the spatial reference for the map. Dynamic ArcGIS Server map and image services as well as feature layers (FeatureLayer) will be reprojected to the map's spatial reference if necessary.” - http://help.arcgis.com/en/webapi/silverlight/help/index.html#/Creating_a_map/016600000011000000/
When I checked the metadata for the 2 services in the ArcGIS Services Directory I noticed that the Spatial Reference was different for the 2 services. So, I changed the XAML to something like this (note lines 2 to 8):
<esri:Map x:Name="AWMap">
    <esri:Map.Extent>
        <esri:Envelope XMin="111111" YMin="222222" XMax="333333" YMax="444444" >
            <esri:Envelope.SpatialReference>
                <esri:SpatialReference WKID="27700"/>
            </esri:Envelope.SpatialReference>
        </esri:Envelope>
    </esri:Map.Extent>
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>
The result was that the missing feature layer magically appeared.
So, if you are having problems with missing feature layers check your spatial references. My guess is you should change the spatial references at the server to prevent re-projection on the client; performance may be better.

Wednesday, 28 September 2011

Open XAML file in XAML view by default in VS 2010

When working with XAML in Visual Studio 2010 I prefer to see XAML as text rather than in the design or split views. To set this as a default in Visual Studio 2010:

  1. Open Visual Studio 2010.
  2. Go to Tools > Options > Text Editor > XAML > Miscellaneous.
  3. Check “Always open documents in full XAML view”.
  4. Click OK.
  5. Job done.

 

Untitled

Wednesday, 27 July 2011

No send action on Visio 2007 activity diagram signal shapes

One thing that’s not intuitive in Visio 2007 is how to change the text on a UML activity diagram signal element. When you first drag the signal shape on to an activity diagram it displays the text “<no send action>”.

Untitled3

 

No amount of editing properties will change that unless you do some thing like the following:

1. Create a new Static Structure Diagram (if you haven’t got one already).

2. Using the UML Static Structure shape palette drag a new Signal on to the Static Structure Diagram.

Untitled2

 

3. Right-click on the signal and open Properties.

4. Change the Name to whatever you want to signal to be called.

5. Return to your Activity Diagram and using the UML Activity Diagram palette add a Signal to your activity diagram.

6. Right-click on the signal and open Properties.

7. Choose Actions from the left-hand pane.

8. Select the Send Action and choose Properties.

9. Under Send Action you can now see the signal you added to the Static Structure diagram in the Signal drop down. Select it.

Untitled4

 

10. OK to all the dialogs and now the name of the signal appears on your signal shape.

Untitled5

 

Intuitive, isn’t it!

Monday, 25 July 2011

Renaming files with PowerShell

Problem: I had a directory full of PDF files that needed renaming. Specifically, I had to remove part of each file name.

Solution: Let’s try PowerShell!

PowerShell has been sitting on my machine for ages but for some reason I haven’t got around to using it. This seemed like a great opportunity to get my feet wet and – happily - this example turned out to be very straight forward. Firstly, I discovered that PowerShell was installed to C:\WINDOWS\system32\windowspowershell\v1.0 and I checked that the directory was in my Path system environment variable.

I launched Console2  - it’s so much more fun than using the standard Windows command prompt – and changed directory to the one holding the files I wanted to rename. I then ran powershell.exe which brought up the PowerShell command prompt and used the following PowerShell command to rename the files in the current directory:

get-childitem *.pdf | foreach{rename-item $_ $_.Name.Replace("text to replace", "")}

 

Untitled 

 

That was it. The files were renamed replacing “text to replace” with an empty string.

References

Wednesday, 22 June 2011

Bulk copy, full text and a severe error

I have a program that is using SqlBulkCopy to batch update data in a SQL Server Express 2008 database. Everything was working fine until, for no apparent reason, the bulk inserts failed with the following exception:

“A severe error occurred on the current command. The results, if any, should be discarded.”

After much hair pulling the cause of the error turned out to be the addition of a full text index on one of the fields being updated. Removing the full text index stopped the exception from being thrown. That’s all well and good but I needed a full text index.

The index had been defined something like this:

EXEC sp_fulltext_database 'enable'
GO

CREATE FULLTEXT CATALOG MyCatalog
GO

CREATE FULLTEXT INDEX ON dbo.MyTable
(
    MyColumn
    Language 0X0
)

KEY INDEX PK_MyTable ON MyCatalog WITH CHANGE_TRACKING AUTO

After some experimentation the problem seemed to be with the CHANGE_TRACKING option. By setting it to OFF the bulk copy worked fine but failed with either AUTO or MANUAL.* For my purposes this was acceptable because the data was fairly static and updated infrequently. I was left with having to ensure the index was rebuilt or populated appropriately as a separate process.

 

References

* Full-Text Index Population - http://msdn.microsoft.com/en-us/library/ms142575.aspx

Monday, 20 June 2011

Error installing SQL Server Express 2008

I ran in to an issue when trying to install SQL Server Express 2008 with Advanced Services. The installation file was a single executable (SQLEXPRADV_x86_ENU.exe)  but when I ran it I got the following error in a dialog box:

“SQL Server Setup has encountered the following error:

Invoke or BeginInvoke cannot be called on a control until the window handle has been created..”

The solution to the problem is:

  1. SQLEXPRADV_x86_ENU.exe is a self-extracting Zip file. Use WinZip to extract it to a local folder.
  2. Open a command window and navigate to the folder containing the extracted setup files.
  3. Run setup.exe from the command prompt.

That’s it.

Note that if you want to use Add or Remove Programs feature to add new features you can use the extracted files as the ‘installation media’.