Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with knowntype attribute in wcf

I'm having the following error in my wcf client.

NetDispatcherFaultException was unhandled.

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetVehicleResult. The InnerException message was 'Error in line 1 position 266. Element 'http://tempuri.org/:GetVehicleResult' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/WCFServer:Car'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'Car' 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.'. Please see InnerException for more details.

Can anyone help me where is the fault.

WCF Server


IVehicle
--------
[ServiceContract]   
public interface IVehicleService
{
    [OperationContract]
    Vehicle GetVehicle(int type);

    [OperationContract]
    int GetNumberOfWheels(Vehicle vehicle);
}

VehicleService


[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]   
public class VehicleService : IVehicleService
{        
    public Vehicle GetVehicle(int type)
    {
        switch (type)
        {
            case 0:
                return new Car()
                {
                   ID = 10,
                   Brand = "Volvo",
                   SteeringWheelPosition = "left"
                };

            case 1:
                return new bike()
                {
                    ID = 11,
                    Brand = "Scott",
                    HasFrontWheelBreak = true
                };

            case 2:
                return new Kidsbike()
                {
                    ID = 12,
                    Brand = "Kid Scott",
                    HasFrontWheelBreak = false,
                    HasSupportingWheels = true
                };

            default:
                return null;
        }
    }

    public int GetNumberOfWheels(Vehicle vehicle)
    {
        return vehicle.NoOfWheels;
    }
}

abstract class


[KnownType(typeof(Car))]
[KnownType(typeof(bike))]
[DataContract]
public abstract class Vehicle
{       
    [DataMember]
    public int ID { get; set; }

    abstract public int NoOfWheels { get; }

    [DataMember]
    public string Brand { get; set; }
}

concrete classes


[DataContract]
public class Car : Vehicle
{          
    override public int NoOfWheels { get { return 4; } }
    [DataMember]
    public string SteeringWheelPosition { get; set; }  
}

[KnownType(typeof(Kidsbike))]
[DataContract]
public class bike : Vehicle 
{           
    override public int NoOfWheels { get { return 2; } }
    [DataMember]
    public bool HasFrontWheelBreak { get; set; }  
}

[DataContract]
public class Kidsbike : bike
{
    [DataMember]
    public bool HasSupportingWheels { get; set; }  
}

WCF Client


namespace WCFClient
{
    [ServiceContract]   
    public interface IVehicleService
    {
        [OperationContract]       
        Vehicle GetVehicle(int type);

        [OperationContract]       
        int GetNumberOfWheels(Vehicle vehicle);
    } 
}

namespace WCFClient
{
    [KnownType(typeof(Car))]
    [KnownType(typeof(bike))]
    [DataContract]
    public abstract class Vehicle
    {
        [DataMember]
        public int ID { get; set; }

        abstract public int NoOfWheels { get; }
        [DataMember]
        public string Brand { get; set; }
    }
    [DataContract]
    public class Car : Vehicle
    {
        override public int NoOfWheels { get { return 0; } }
        [DataMember]
        public string SteeringWheelPosition { get; set; }
    }

    [KnownType(typeof(Kidsbike))]
    [DataContract]
    public class bike : Vehicle
    {
        override public int NoOfWheels { get { return 0; } }
        [DataMember]
        public bool HasFrontWheelBreak { get; set; }
    }
    [DataContract]
    public class Kidsbike : bike
    {
        [DataMember]
        public bool HasSupportingWheels { get; set; }
    }
}

private void btnGetVehicle_Click(object sender, EventArgs e)
{
    Car carObj = (Car)fclient.GetVehicle(0);          
}

just creating proxy in client side . I can able to call the service successfully, but in response im having the problem. I try with Knowntype attribute. Whats wrong in this.

like image 711
C-va Avatar asked Aug 23 '11 11:08

C-va


People also ask

What is the KnownType attribute in WCF?

The KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization.

What is used if you expect the service to accept and return in inherited types in WCF?

The WCF service generally accepts and returns the base type. If you expect the service to accept and return an inherited type then we use the knowntype attribute.


1 Answers

The following code work fine without error.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService1 {
    [ServiceKnownType(typeof(Car))]
    [ServiceKnownType(typeof(bike))]
    [ServiceKnownType(typeof(Kidsbike))]
    [ServiceContract]
    public interface IVehicleService {
        [OperationContract]
        Vehicle GetVehicle(int type);

        [OperationContract]
        int GetNumberOfWheels(Vehicle vehicle);
    }

      [DataContract]
    public abstract class Vehicle
    {
        [DataMember]
        public int ID { get; set; }

        abstract public int NoOfWheels { get; }
        [DataMember]
        public string Brand { get; set; }
    }
    [DataContract]
    public class Car : Vehicle
    {
        override public int NoOfWheels { get { return 0; } }
        [DataMember]
        public string SteeringWheelPosition { get; set; }
    }

    [KnownType(typeof(Kidsbike))]
    [DataContract]
    public class bike : Vehicle
    {
        override public int NoOfWheels { get { return 0; } }
        [DataMember]
        public bool HasFrontWheelBreak { get; set; }
    }
    [DataContract]
    public class Kidsbike : bike
    {
        [DataMember]
        public bool HasSupportingWheels { get; set; }
    }

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]   
public class VehicleService : IVehicleService
{        
    public Vehicle GetVehicle(int type)
    {
        switch (type)
        {
            case 0:
                return new Car()
                {
                   ID = 10,
                   Brand = "Volvo",
                   SteeringWheelPosition = "left"
                };

            case 1:
                return new bike()
                {
                    ID = 11,
                    Brand = "Scott",
                    HasFrontWheelBreak = true
                };

            case 2:
                return new Kidsbike()
                {
                    ID = 12,
                    Brand = "Kid Scott",
                    HasFrontWheelBreak = false,
                    HasSupportingWheels = true
                };

            default:
                return null;
        }
    }

    public int GetNumberOfWheels(Vehicle vehicle)
    {
        return vehicle.NoOfWheels;
    }
}

}

Svc file:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.VehicleService" CodeBehind="Service1.svc.cs" %>

Testing service:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WcfService1;

namespace Test {
    class Program {
        static void Main(string[] args) {
            BasicHttpBinding hproxy = new BasicHttpBinding();
            hproxy.MaxReceivedMessageSize = 2147483647;
            hproxy.MaxBufferSize = 2147483647;
            hproxy.MaxBufferPoolSize = 2147483647;
            EndpointAddress eaddrr = new EndpointAddress("http://localhost:62807/Service1.svc");
            ChannelFactory<IVehicleService> CFactoryobj1 = new ChannelFactory<IVehicleService>(hproxy, eaddrr);
            IVehicleService isclientobj1 = CFactoryobj1.CreateChannel(); 
            Car ve = (Car)isclientobj1.GetVehicle(0);
        }
    }
}
like image 160
rpgmaker Avatar answered Oct 01 '22 23:10

rpgmaker