SOAP generic type serialization

2020-07-22 10:15发布

问题:

We have created a class to wrap the payload of web service response with common information as follows.

public class ItemResponse<T> : Response
    {
    /// <summary>
    /// constructor to set private properties Item and Status
    /// </summary>
    /// <param name="item"></param>
    /// <param name="status"></param>
    public ItemResponse(T item, ResponseStatusEnum status) : base(status)
    {
        _item = item;
    }

    public ItemResponse()
    {
    }


    public ItemResponse(ResponseStatusEnum status, System.Collections.Generic.List<ResponseError> errors) : base(status, errors)
    {
    }
    private T _item;

    public T Item
    {
        get
        {
            return _item;
        }
    }


}

The base class "Response" just holds error information and status of the the response. The wsdl clearly shows the definition of this response to be ItemResponseOfType[TypeName] but the item type information is missing from the definition.

We tried adding

[XmlInclude(typeof(TypeName))]

but to no avail. Any ideas what we can do to let the SOAP serializer know we want the "Item" type serializing?

回答1:

The SOAP serializer doesn't support generic types. Microsoft recommends using WCF http://msdn.microsoft.com/en-us/library/ms172342(v=VS.100).aspx. Before WCF, I remember them recommending the XML serializer.



回答2:

OK we have got to the bottom of this.

Its turns out that the XML Serializer can serialize generic types of a sort. As neontapir correctly points out Generic types are not fully supported by the XML Serializer but it can still serialise generic types as it creates types of ItemResponseOfType[TheType] as I mentioned in my question.

The XML Serializer just wont de serialize the type to a generic Type.

Our problem was simply that the property Item was read only and as a result SOAP missed the Item property out. We just needed to make the property publicy settable to fix as below

public class ItemResponse<T> : Response
{
/// <summary>
/// constructor to set private properties Item and Status
/// </summary>
/// <param name="item"></param>
/// <param name="status"></param>
public ItemResponse(T item, ResponseStatusEnum status) : base(status)
{
    Item = item;
}

public ItemResponse()
{
}


public ItemResponse(ResponseStatusEnum status, System.Collections.Generic.List<ResponseError> errors) : base(status, errors)
{
}

public T Item
{
     get; set;
}
}