Problem with knowntype attribute in wcf

后端 未结 2 1062
南旧
南旧 2021-01-18 10:51

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

NetDispatcherFaultException was unhandled.

The formatter threw an exception while trying

相关标签:
2条回答
  • 2021-01-18 11:41

    The KnownType should be used on the service contract interface itself not the vehicle class since it is the one that is returning the Vehicle object for one of its operations. Adding KnownType to the Vehicle class does nothing I think. because by default now, you don't need to add DataContract to your class for them to be useable in WCF. so you should have something like below.

    [ServiceKnownType(typeof(Car))]
    [ServiceKnownType(typeof(bike))]
    [ServiceKnownType(typeof(Kidsbike))]
    [ServiceContract]   
    public interface IVehicleService
    {
        [OperationContract]
        Vehicle GetVehicle(int type);
    
        [OperationContract]
        int GetNumberOfWheels(Vehicle vehicle);
    }
    
    0 讨论(0)
  • 2021-01-18 11:52

    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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题