I'm trying to send a BitmapSource from my WCF service to my client app. Both are .NET 3.5 applications. I'm seemingly able to serialze the object without an issue (no exceptions occur), but my callback on my client never gets called. After adding a trace to log exceptions on my client, I see that the DataContractSerializer can't deserialize the BitmapSource.

The error is: 'Element 'http://schemas.datacontract.org/2004/07/Test.VisionStudio.Remote:Image' contains data of the 'http://schemas.datacontract.org/2004/07/System.Windows.Interop:InteropBitmap' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'InteropBitmap' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'.

So, I did what it said and added the known types to the service contract and callback contract, but I'm still getting the same errors.

Here's the service callback contract and data contract I'm sending (remove irrelevant DataMembers):

[ServiceKnownType(typeof(BitmapSource))]
[ServiceKnownType(typeof(InteropBitmap))]
public interface IZynVisionStudioRemoteServiceCallback
{
    [OperationContract(IsOneWay=true)]
    void OnVisionResultsReady(RemoteVisionProductResult result);

    [OperationContract(IsOneWay = true)]
    void ServiceShuttingDown();
}


[DataContract]
public class RemoteVisionProductResult
{
    private bool _status;
    /// <summary>
    /// Status of the overall inspection. Pass = True, Fail = False
    /// </summary>
    [DataMember]
    public bool Status
    {
        get { return _status; }
        set { _status = value; }
    }

    private string _product;
    /// <summary>
    /// Name of the product the results came from
    /// </summary>
    [DataMember]
    public string Product
    {
        get { return _product; }
        set { _product = value; }
    }

    private string _inspection;
    /// <summary>
    /// Name of the inspection the results came from
    /// </summary>
    [DataMember]
    public string Inspection
    {
        get { return _inspection; }
        set { _inspection = value; }
    }

    private List<RemoteVisionImage> _images = new List<RemoteVisionImage>();
    [DataMember]
    public List<RemoteVisionImage> Images
    {
        get { return _images; }
        set { _images = value; }
    }

    private List<RemoteVisionImage> _imagesWithGraphics = new List<RemoteVisionImage>();
    [DataMember]
    public List<RemoteVisionImage> ImagesWithGraphics
    {
        get { return _imagesWithGraphics; }
        set { _imagesWithGraphics = value; }
    }
}


[DataContract]
public class RemoteVisionImage
{
    /// <summary>
    /// Image uploaded from the vision system
    /// </summary>        
    [DataMember]
    public BitmapSource Image { get; set; }

    /// <summary>
    /// Name of the camera the image was uploaded from
    /// </summary>
    [DataMember]
    public string Camera { get; set; }

    public RemoteVisionImage()
    {
    }
}

Can anyone help me figure out why I can't send this image across the wire?

EDIT: I should add, my client updates the service reference as expected, and shares assemblies with the service, so the implementation of RemoteVisionProductResult and RemoteVisionImage is also on the client.

有帮助吗?

解决方案 2

This was resolved by adding a Bitmap property to the DataContract, converting from BitmapSource to Bitmap on the service side, sending it across the wire, and re-building the BitmapSource on the client side using the palette and other properties from the Bitmap.

其他提示

I solved a similar problem in the past (creating a VS debug visualizer for BimapSources) by implementing serialize and deserialize methods that read/write the:

  • Format (PixelFormat)
  • PixelHeight
  • PixelWidth
  • Stride
  • Buffer

Using CopyPixels(Int32Rect, IntPtr, Int32, Int32) in the serializer
and Create(Int32, Int32, Double, Double, PixelFormat, BitmapPalette, IntPtr, Int32, Int32) in the deserializer.

Unfortunately I do not have the source code, however, the implementation is pretty straightforward.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top