wcf中的knowntype属性问题 [英] Problem with knowntype attribute in wcf

查看:97
本文介绍了wcf中的knowntype属性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的wcf客户端出现以下错误.

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

未处理NetDispatcherFaultException.

NetDispatcherFaultException was unhandled.

格式化程序尝试反序列化消息时引发异常:尝试反序列化参数 http://时出错. tempuri.org/:GetVehicleResult . InnerException消息是第1行的位置266错误.元素' http://tempuri.org/:GetVehicleResult '包含来自映射到名称' http://schemas.datacontract.org的类型的数据/2004/07/WCFServer:Car ".解串器不知道任何映射到该名称的类型.考虑使用DataContractResolver或将与"Car"相对应的类型添加到已知类型的列表中-例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型的列表中.有关更多详细信息,请参见InnerException.

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服务器

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

    [OperationContract]
    int GetNumberOfWheels(Vehicle vehicle);
}

VehicleService

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;
    }
}

抽象类

[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 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客户端

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);          
}

仅在客户端创建代理.我可以成功调用该服务,但对此存在问题.我尝试使用Knowntype属性.怎么了?

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.

推荐答案

以下代码可以正常工作而不会出错.

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文件:

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

测试服务:

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);
        }
    }
}

这篇关于wcf中的knowntype属性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆