我的wcf客户端出现以下错误.
NetDispatcherFaultException未处理.
格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数http://tempuri.org/:GetVehicleResult时出错.InnerException消息是'第1行中的错误266.元素' http://tempuri.org/:GetVehicleResult '包含映射到名称' http://schemas.datacontract.org/2004/07/的类型的数据WCFServer:Car '.反序列化器不知道映射到此名称的任何类型.考虑使用DataContractResolver或将与"Car"对应的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中.有关更多详细信息,请参阅InnerException.
任何人都可以帮助我在哪里是错误.
WCF服务器
IVehicle
--------
[ServiceContract]
public interface IVehicleService
{
[OperationContract]
Vehicle GetVehicle(int type);
[OperationContract]
int GetNumberOfWheels(Vehicle vehicle);
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
抽象类
[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; }
}
Run Code Online (Sandbox Code Playgroud)
具体课程
[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; }
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
只是在客户端创建代理.我能够成功调用该服务,但作为回应我遇到了问题.我尝试使用Knowntype属性.这有什么不对.
以下代码正常工作没有错误.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Svc文件:
<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.VehicleService" CodeBehind="Service1.svc.cs" %>
Run Code Online (Sandbox Code Playgroud)
测试服务:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
KnownType应该在服务合同接口本身而不是车辆类上使用,因为它是为其中一个操作返回Vehicle对象的类.将KnownType添加到Vehicle类没有任何意义.因为现在默认情况下,您不需要将DataContract添加到您的类中,以便它们可以在WCF中使用.所以你应该有类似下面的东西.
[ServiceKnownType(typeof(Car))]
[ServiceKnownType(typeof(bike))]
[ServiceKnownType(typeof(Kidsbike))]
[ServiceContract]
public interface IVehicleService
{
[OperationContract]
Vehicle GetVehicle(int type);
[OperationContract]
int GetNumberOfWheels(Vehicle vehicle);
}
Run Code Online (Sandbox Code Playgroud)