Tuesday, 28 August 2012

WPF Resizing Inner DataGrid Problem

I started this post in December last year and I am only just getting round to completing it now. While I was working a colleague came to me with a WPF problem which I had to look into and sort as it was bothering me.

The Problem:
A WPF DataGrid with each row having its own row details and the template for this is another DataGrid. This is fine however the tricky part was getting the inner DataGrid width to resize along with its columns when the window resizes like the outer grid will as long you are using the correct layout and no width has been set.

Now I have been doing WPF for about 3 years and I am still finding out the ins and outs of the DataGrid control I find it can be very powerful yet at the same time stab you in the back and not work the way you want, sometimes when problems like this arise they are extremely frustrating.

After looking into this somewhat the best option that I could come up with to do this without any code behind (XAML based only) was to bind the width of the inner grid to the ActualWidth property of its parent grid. for example:

<DataGrid Name="dgrDetails" DataContext="{Binding XPath=Tracks}" 
          ItemsSource="{Binding XPath=Track}" AutoGenerateColumns="False"
          Style="{StaticResource DataGridStyle}" Margin="0" 
          Width="{Binding ElementName=dgrMain, Path=ActualWidth}">
        <DataGridTextColumn Header="No." Binding="{Binding XPath=No}" Width="*" />
        <DataGridTextColumn Header="Title" Binding="{Binding XPath=Title}" Width="*" />
        <DataGridTextColumn Header="Length" Binding="{Binding XPath=Length}" 
                            Width="*" />

I will upload the full source for this problem along with some other useful data grid examples up to my GitHub in the next 2 weeks and will link it in here.

Wednesday, 22 August 2012

Sending files as a Base64 String to a WCF RESTful Service

I recently came across a problem at work which was so frustrating and took the total of 3 days to fix so I thought it was vital that I write this blog.

For a project I am working on at work we are using a WCF RESTful service as an endpoint to provide and revive data in JSON format to an iPad. It came to the point where we needed to get PDF's (not overly sized I might add) off the iPad and back up to the server using the WCF REST service. It was my job to create the methods on the service to allow this to happen. I did a quick Goggle as this was newish territory for me and from what I found it seemed like a relatively simple task to do. (Oh how I was wrong). Me and my colleague had decided that the best way to do this was to convert the file into a Base64 string and then send this up with in the JSON to the service.

So I created the method signature that took a DateTime for sync purposes and an object which would have a set of properties one of which being the Base64 string.

Example WCF RESTful Service PUT Signature

Once this was done I went on to use a quick C# test app that I have created to test the service before the iPad connects to it and in this I kept getting a 400 Bad Request HTTP response.

The problem was due to a setting in the configuration file it took me 3 days to come round to this and a whole world of hurt.

During the second day of pain and when I was getting ready to give up my colleague found an excellent post that was very helpful and it was in fact from this post that I got the working config needed.


Essentially in the example in the above link he sends a large byte array around the size of 10mb up to a WCF RESTful service. The key thing in his example though is the configuration file and that he is using a attribute called TransferMode and this was set to streamed request.

Transfer Mode Attribute Set To Streamed Request

After implementing his example I then began to move it over to our project and and everything seemed to be working, first a byte array and then a Base64 string however I came across one last problem and that is as follows. The WCF RESTful project we have created uses Basic Authentication to ensure that our traffic is encrypted and sent over SSL. The problem is this you can't have streamed request turned on with Basic Authentication. However upon removing this attribute form the config it started to work which lead me to believe there was something not set up correctly i nthe orriginal config which was causing the server to ignore the maxReceivedMessageSize, maxBufferSize, etc attributes in the config.

Configuration Settings for Binding and the Behaviors 

To summarise the two problems I faced were:

  1. The configuration settings not being set correctly
  2. The transferMode="StreamedRequest" attribute doesn't work with Basic Authentication.