开发者

WCF Problem Sending Object To Client

开发者 https://www.devze.com 2022-12-11 04:21 出处:网络
Background Converting from using .Net Remoting to WCF.Most of the methods on the WCF server are working fine, but ran into one that isn\'t working today.

Background

Converting from using .Net Remoting to WCF. Most of the methods on the WCF server are working fine, but ran into one that isn't working today.

This is the service contract:

[ServiceContract]
public interface IMyService
{
  [OperationContract]
  generated.Response.ACS_Response Check(generated.Request.ACS_Request request);
}

I snipped out the rest of the methods on that interface, since they are working. Basically, I'm trying to pass in a request object and get back a response object.

The class开发者_如何学JAVAes for ACS_Response and ACS_Reqeust are generated using XSD.exe against an XSD file. Those classes reside in an Api assembly that is referenced by both the WCF client and WCF host.

Problem

I am able to make the call to the WCF host and the Request object and the host is able to do its work. When the host attempts to return the Response object, that's where I encounter an exception.

I turned on tracing for WCF and see an SerializationException saying:

Type 'Api.generated.Response.ACS_ResponseQuestion'
with data contract name 'ACS_ResponseQuestion:http://...' is
not expected.  Add any types not known statically.........

Questions

First, I'm confused because I am able to successfully send a Request object, so it would seem the basics are working.

Second, this serialization was working under .Net Remoting. The classes are all generated by WSDL so shouldn't they be serializable as is?

Third, the host and client both reference the same Api assembly which defines these classes, so they are known to both server and client.


I believe it is because Api.generated.Response.ACS_ResponseQuestion is not used in the contract (API) so it is not automatically tagged as a known type.

Read these articles, they should explain everything:

  1. Known Types
  2. Data Contract Known Types
  3. Understanding Known Types

Quick solution: Try adding this to the class which implements the interface:

[KnownType(typeof(Api.generated.Response.ACS_ResponseQuestion))]

If this doesn't work, you may have to declare it as a ServiceKnownType:

// Define a service contract and apply the ServiceKnownTypeAttribute
// to specify types to include when generating client code. 
// The types must have the DataContractAttribute and DataMemberAttribute
// applied to be serialized and deserialized. The attribute specifies the 
// name of a method (GetKnownTypes) in a class (Helper) defined below.
[ServiceKnownType("GetKnownTypes", typeof(Helper))]
[ServiceContract()]
public interface ICatalog
{
    // Any object type can be inserted into a Hashtable. The 
    // ServiceKnownTypeAttribute allows you to include those types
    // with the client code.
    [OperationContract]
    Hashtable GetItems();
}

// This class has the method named GetKnownTypes that returns a generic IEnumerable.
static class Helper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        System.Collections.Generic.List<System.Type> knownTypes =
            new System.Collections.Generic.List<System.Type>();
        // Add any types to include here.
        knownTypes.Add(typeof(Widget));
        knownTypes.Add(typeof(Machine));
        return knownTypes;
    }
}

[DataContract()]
public class Widget
{
    [DataMember]
    public string Id;
    [DataMember]
    public string Catalog;
}

[DataContract()]
public class Machine : Widget
{
    [DataMember]
    public string Maker;
}


Take a look at this ServiceKnownType provider It should save you some grief. Its very simple for you to register a base type and it will scan the assembly for all classes that inherit from the base class.


You are referencing the classes from both the client and the server, I would therefore recommend that you look at this way of doing WCF:

http://www.dnrtv.com/default.aspx?showNum=122

0

精彩评论

暂无评论...
验证码 换一张
取 消