Which data types WCF service can handle ?

2019-07-21 05:22发布

问题:

I am new to WCF. Previously I used WCF service for basic data types like string, int32 etc. But when I try to use BitmapImage class its Test Client giving following error

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.

When I replace BitmapImage with String it works fine. That means I am missing some piece of code.

For better understanding here is my code.

WCF Interface code

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace MyWcfService
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        void MyMethod(MyDataContract obj);
    }

    [DataContract]
    public class MyDataContract
    {
        [DataMember]        
        public BitmapImage MyProperty { get; set; }
    }
}

WCF Service code

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace MyWcfService
{
    public class Service1 : IService1
    {
        public void MyMethod(MyDataContract obj)
        {
            //No code. It is blank.
        }
    }
}

Web.Config code

  <system.serviceModel>
    <services>
      <service name="MyWcfService.Service1" behaviorConfiguration="MyWcfService.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address="" binding="wsHttpBinding" contract="MyWcfService.IService1">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyWcfService.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

回答1:

You should add KnownType of BitmapImage on your MyDataContract class.

[KnownType(typeof(BitmapImage))]
[DataContract]
    public class MyDataContract
    {
        [DataMember]        
        public BitmapImage MyProperty { get; set; }
    }

this is because string is primitive type and BitmapImage is not, so you should "tell" compiler which data types would it deal when serializing/deserializing.



回答2:

My guess would be that BitmapImage is not one of the types supported by the DataContractSerializer (see http://msdn.microsoft.com/en-us/library/ms731923.aspx ), and so the data contract becomes invalid (and thus metadata generation fails, resulting in the error message you posted).

If this is the case, you will need to remove [DataMember] from the BitmapImage property, and create a new [DataMember] property that handles the serialization manually (converts MyProperty to some supported type such as byte[])