RIA.NET + Silverlight 3: Store picture in database and display it in UI controls (DataGrid, DataForm)
We have a table in SQL server with field of “Image” type. We add ADO.NET Entity Data Model by standard way:

Then add table to model. Sql type Image by default is mapping on C# Binary type.
Then Domain Service Class.

And link it with EF Model:

Main rule of web services: to hide service realization (platform and source code of course
). RIA.NET code generator creates entity class on client side, where picture stored in field of type – byte[] (simple byte array).
Add DataGrid on from and add DomainDataSource:
[CODE language="XML"]
[/CODE]
In the grid set AutoGenerateColumns=”False”. Add column to grid to display image (add image control into grid field template):
[CODE language="XML"]
[/CODE]
Direct binding doesn’t work. We need to convert “byte[]” value to “BitmapImage” value (we need write in xaml “Source =”{Binding Photo, Converter={StaticResource ImageConverter}}”/>“
There is a simple image converter below:
[CODE language="CSharp"]
public class ImageConverter : IValueConverter {
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture) {
BitmapImage bi = new BitmapImage();//create bitmap image
if(value!=null)
//fill bitmap by data from db
bi.SetSource(new MemoryStream((Byte[])value));
return bi;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();//image is readonly(view only)
}
}
[/CODE]
We need to create template field in DataForm (code is the same as in DataGrid):
[CODE language="XML"]
[/CODE]
Ok, now we want to open picture and store it on server. It’s very simple:
Add “open picture” button and on Onclick event add this code:
1) Get stream on local file using OpenFileDialog.
2) Read all bytes in array.
3) Assign selected entity Photo field to reader array.
[CODE language="CSharp"]
private void LoadPicture_Click(object sender, RoutedEventArgs e) {
var openFileDialog = new OpenFileDialog();
var res = openFileDialog.ShowDialog();
if (res.HasValue && res.Value) {
Stream stream = openFileDialog.File.OpenRead();
BinaryReader binaryReader = new BinaryReader(stream);
byte[] currentImageInBytes = binaryReader.ReadBytes((int) stream.Length);
//get selected entry from grid
((Gamer) gamerGrid.SelectedItem).Photo = currentImageInBytes;
}
}
[/CODE]
And last one, Call DomainDataSource::SubmitChanges to store in Database.
P.S. Waiting for RTM release of RIA.NET. And of course MSDN 2010
Hi,
When i bind the byte array into BitMapImage object (bi.SetSource(new MemoryStream((Byte[])value))), it raise this error
System.Exception was unhandled by user code
Message=”Catastrophic failure (Exception de HRESULT : 0×8000FFFF (E_UNEXPECTED))”
StackTrace:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.BitmapImage_SetSource(BitmapImage bitmapImage, CValue& byteStream)
at System.Windows.Media.Imaging.BitmapImage.SetSource(Stream streamSource)
at BusinessApplication1.ValueConverters.ImageConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
at System.Windows.Data.BindingExpression.ConvertToTarget(Object value)
at System.Windows.Data.BindingExpression.GetValue(DependencyObject d, DependencyProperty dp)
at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)
at System.Windows.Data.BindingExpression.RefreshExpression()
at System.Windows.Data.BindingExpression.SendDataToTarget()
at System.Windows.Data.BindingExpression.DataContextChanged(Object o, DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyProperty dp)
at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.FrameworkElement.set_DataContext(Object value)
at System.Windows.Controls.DataForm.UpdateCurrentItem()
at System.Windows.Controls.DataForm.GenerateUI()
at System.Windows.Controls.DataFormField.set_IsDataFormCurrentItemNull(Boolean value)
at System.Windows.Controls.DataFormFieldGroup.OnIsDataFormCurrentItemNullChanged(EventArgs e)
at System.Windows.Controls.DataFormField.set_IsDataFormCurrentItemNull(Boolean value)
at System.Windows.Controls.DataForm.OnCurrentItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.DataForm.set_CurrentItem(Object value)
at System.Windows.Controls.DataForm.UpdateCurrentItem()
at System.Windows.Controls.DataForm.OnCollectionViewCurrentChanged(Object sender, EventArgs e)
at System.Windows.Data.EntityCollectionView.OnCurrentChanged()
at System.Windows.Data.EntityCollectionView.MoveCurrentToPosition(Int32 position)
at System.Windows.Data.EntityCollectionView.MoveCurrentToFirst()
at System.Windows.Controls.DomainDataSource.DomainContext_Loaded(Object sender, LoadedDataEventArgs e)
at System.Windows.Ria.Data.DomainContext.OnLoaded(LoadedDataEventArgs e)
at System.Windows.Ria.Data.DomainContext.CompleteLoad(IAsyncResult asyncResult)
at System.Windows.Ria.Data.DomainContext.c__DisplayClass10.b__a(Object )
InnerException:
What’s wrong ?
what “Byte[])value” contain? maybe wrong data or very big picture %)
I have made some tests with jpeg or png format but the result is the same (Catastrophic failure ).
The size of my images is not very big (10 KB max).
Maybe you show you code??
It’s ok now.
My images were not good…