[英]WCF DataServices (CTP2): There is a type mismatch between the client and the service
我正在使用WCF Dataservices CTP2和Entity Framework 4.1。 现在,我试图通过我的datacontext获取任何数据,我得到了这个异常:
System.Reflection.TargetInvocationException:调用目标抛出了异常。 ---> System.InvalidOperationException:客户端和服务之间存在类型不匹配。 类型“Crm.Objects.Segmentation”不是实体类型,但响应有效内容中的类型表示实体类型。 请确保客户端上定义的类型与服务的数据模型匹配,或更新客户端上的服务引用。 在System.Data.Services.Client的System.Data.Services.AtomMaterializer.MaterializeResolvedEntry(AtomEntry条目,布尔包含链接)处于System.Data.Services.Client.AtomMaterializer.Materialize(AtomEntry条目,类型expectedEntryType,Boolean includeLinks)处。 System.Data.Services.Client.ProjectPlan.Run上的System.Data.Services.Client.AtomMaterializerInvoker.DirectMaterializePlan(Object materializer,Object entry,Type expectedEntryType)中的AtomMaterializer.DirectMaterializePlan(AtomMaterializer materializer,AtomEntry条目,类型expectedEntryType)(AtomMaterializer materializer) ,AtomEntry条目,类型expectedType)位于System.Data.Services.Client.MaterializeAtom.MoveNextInternal()的System.Data.Services.Client.AtomMaterializer.Read()处于System.Data.Services.Client.MaterializeAtom.MoveNext()at System.Linq.Enumerable.d_ b1
1.MoveNext() at System.Collections.Generic.List
MangoCrm.M的1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)的1.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
在MangoCrm.Modules.Replication.ReplicaBuilder.BeginReplication()MangoCrm.Modules.Replication.ReplicationWindowControl.b _0()---内部异常堆栈跟踪结束时的odules.Replication.ReplicaBuilder.GetItems [T](IEnumerable`1查询) ---在System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo方法,Object target,Object []参数,SignatureStruct&sig,MethodAttributes methodAttributes,RuntimeType typeOwner)处于System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo方法,Object target,Object []参数,Signature sig) System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object []参数,CultureInfo文化,布尔值skipVisibilityChecks),System.Delegate.DynamicInvokeImpl(Object [] args)at System,MethodAttributes methodAttributes,RuntimeType typeOwner) MS.Internal.Threading.ExceptionFilterHelper.TryCatchWh中的.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,Object args,Int32 numArgs) en(对象源,委托方法,对象args,Int32 numArgs,Delegate catchHandler)
这是我的代码:
var uri = new Uri(webServiceUrl);
var service = new DataServiceContext(uri);
MessageBox.Show(service.CreateQuery<Segmentation>("DbSegmentations").ToList().Count.ToString());
有帮助吗?
更新现在好了,我发现我的WCF响应包含一个修改过的实体对象。 这里是:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<entry xml:base="http://localhost:99/Services/CrmDataService.svc/"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<id>http://localhost:99/Services/CrmDataService.svc/DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')</id>
<title type="text"></title>
<updated>2011-06-16T15:07:48Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Segmentation" href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Companies"
type="application/atom+xml;type=feed"
title="Companies"
href="DbSegmentations(guid'e9854210-85d1-4822-ba70-7e1d3d29cf62')/Companies" />
<category term="Crm.Data.Segmentation" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Guid">e9854210-85d1-4822-ba70-7e1d3d29cf62</d:Id>
<d:Name>Promoter</d:Name>
<d:Description m:null="true" />
<d:ReplicaInfo m:type="Crm.Data.ReplicaInfo">
<d:CreateDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:CreateDate>
<d:ModifyDate m:type="Edm.DateTime">2011-06-09T20:35:22.29</d:ModifyDate>
<d:CreatedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:CreatedById>
<d:ModifiedById m:type="Edm.Guid">00000000-0000-0000-0000-000000000000</d:ModifiedById>
<d:IsDeleted m:type="Edm.Boolean">false</d:IsDeleted>
</d:ReplicaInfo>
</m:properties>
</content>
</entry>
这是一个问题
<category
term="Crm.Data.Segmentation"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"
/>
所以问题是为什么我的Crm.Objects.Segmentation成为Crm.Data.Segmentation? 何要改回来?
UPDATE2我认为问题出在我的数据环境中。 数据上下文具有名称空间Crm.Data。 我的实体在Crm.Objects中。 然后我使用4.0.0 WCF一切都很好,但后来切换到CTP2我的实体获取Crm.Data命名空间而不是正确的Crm.Objects
您是否尝试为DataServiceContext.ResolveName
和DataServiceContext.ResolveType
实现委托? 这两个代理(如果提供)可用于修复odata名称空间+名称之间的映射,以及在客户端上序列化和反序列化的类型。
这是一个简单的例子:
internal class CustomDataServiceContext : DataServiceContext
{
public CustomDataServiceContext(Uri serviceRoot)
: base(serviceRoot, DataServiceProtocolVersion.V3)
{
this.ResolveName = ResolveNameFromType;
this.ResolveType = ResolveTypeFromName;
}
protected string ResolveNameFromType(Type clientType)
{
if (clientType.Namespace.Equals("ODataClient.MSProducts", StringComparison.Ordinal))
{
return string.Concat("ODataService.Models.", clientType.Name);
}
return clientType.FullName;
}
protected Type ResolveTypeFromName(string typeName)
{
if (typeName.StartsWith("ODataService.Models", StringComparison.Ordinal))
{
return this.GetType().Assembly.GetType(string.Concat("ODataClient.MSProducts", typeName.Substring(19)), false);
}
return null;
}
}
为了使我的实体类在WCF数据服务客户端中工作,我必须做这样的事情(但我使它变得灵活而不是硬编码);
但即使这样做,我也有这个错误:
System.InvalidOperationException:客户端和服务之间存在类型不匹配。 Type WorkItem'不是实体类型,但响应有效内容中的类型表示实体类型。 请确保客户端上定义的类型与服务的数据模型匹配,或更新客户端上的服务引用。
我找到了两个适用于此的修复:
[DataServiceKey("Id")]
属性添加到您的实体类。 要么 ID
结尾 我很难找到#2 - 看看反编译的IL(这是针对WCF数据服务5.2.0)。 审查后ClientEdmModel
和ClientTypeUtil
,我碰到这个方法来ClientTypeUtil
:
private static ClientTypeUtil.KeyKind IsKeyProperty(PropertyInfo propertyInfo, DataServiceKeyAttribute dataServiceKeyAttribute)
{
string name1 = propertyInfo.Name;
ClientTypeUtil.KeyKind keyKind = ClientTypeUtil.KeyKind.NotKey;
if (dataServiceKeyAttribute != null && dataServiceKeyAttribute.KeyNames.Contains(name1))
keyKind = ClientTypeUtil.KeyKind.AttributedKey;
else if (name1.EndsWith("ID", StringComparison.Ordinal))
{
string name2 = propertyInfo.DeclaringType.Name;
if (name1.Length == name2.Length + 2 && name1.StartsWith(name2, StringComparison.Ordinal))
keyKind = ClientTypeUtil.KeyKind.TypeNameId;
else if (2 == name1.Length)
keyKind = ClientTypeUtil.KeyKind.Id;
}
return keyKind;
}
这就是name1.EndsWith("ID"
,它是在WCF数据服务的客户端使用POCO时的关键。
希望有所帮助。
刚刚遇到相同的错误消息并将其修复到我的最后。 原来我在服务和客户端之间混合了程序集。 一个是使用Microsoft.Data.Services,另一个是使用System.Data.Services。
我要说你引用的是Segmentation
类的另一个实现,而不是服务的实现。 检查出的命名空间Segmentation
你CreateQuery<>()
调用和的命名空间Segmentation
类服务。
好的,我认为这是一个新的WCF CTP2的错误。 然后我添加了System.Data.Services 4.0.0引用我在我的数据服务中获得了正确的命名空间。 但后来我使用v4.99.2.0我在我的ds中得到了错误的命名空间。
我有类似的问题,不知道它是否能解决你的问题。
我必须做的是覆盖“CreateDataSource”方法并关闭svc.cs文件中的代理创建。
这是代码:
protected override DataServiceContext CreateDataSource()
{
var db = base.CreateDataSource();
db.Configuration.ProxyCreationEnabled = false;
return db;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.