WCF DataService的(CTP2):有在客户端和服务之间的类型不匹配 [英] WCF DataServices (CTP2): There is a type mismatch between the client and the service

查看:151
本文介绍了WCF DataService的(CTP2):有在客户端和服务之间的类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用WCF DataService的CTP2与实体框架4.1。那么现在我想通过我的DataContext获取任何数据,我得到这个异​​常:

I'm using WCF Dataservices CTP2 with Entity Framework 4.1. Now then I'm trying to get any data through my datacontext I get this exception:

System.Reflection.TargetInvocationException:
异常已被调用的
目标引发异常。 --->
System.InvalidOperationException:
还有就是
客户端和服务之间的类型不匹配。型
位Crm.Objects.Segmentation'不是
中的一个实体型,但在
响应有效载荷的类型表示的实体
型。请确保类型​​定义的客户端上的
匹配$ B $的数据模型B的服务或者更新客户端上的服务
的参考。
是在
System.Data这。 Services.Client.AtomMaterializer.MaterializeResolvedEntry(AtomEntry
项,布尔includeLinks)在
System.Data.Services.Client.AtomMaterializer.Materialize(AtomEntry
项,键入expectedEntryType,布尔
includeLinks)留在
System.Data.Services.Client.AtomMaterializerInvoker
System.Data.Services.Client.AtomMaterializer.DirectMaterializePlan(AtomMaterializer
materializer,AtomEntry项,键入
expectedEntryType) .DirectMaterializePlan(对象
materializer,对象条目,输入
expectedEntryType)在
System.Data.Services.Client.ProjectionPlan.Run(AtomMaterializer
materializer,AtomEntry项,键入
expectedType)在
System.Data.Services.Client.AtomMaterializer.Read()在
System.Data.Services.Client.MaterializeAtom.MoveNextInternal
()
$处在
System.Linq.Enumerable.d_ b $ b System.Data.Services.Client.MaterializeAtom.MoveNext()
B1 1.MoveNext()
。在在
System.Linq.Enumerable
System.Collections.Generic.List
1..ctor(IEnumerable的 1
集合)。了ToList [TSource](IEnumerable的
1
源)在在
$ b MangoCrm.Modules.Replication.ReplicaBuilder.GetItems [T](IEnumerable`1
查询) $ b MangoCrm.Modules.Replication.ReplicaBuilder.BeginReplication()
。在
MangoCrm.Modules.Replication.ReplicationWindowControl.b
的_0()
---内部异常堆栈结束跟踪---在System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo
方法,对象目标,对象[]
参数,SignatureStruct&安培; SIG,
MethodAttributes methodAttributes,
RuntimeType typeOwner)在
System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo
方法,对象目标,对象[]
参数,签名的签名,
MethodAttributes methodAttributes,
RuntimeType typeOwner)在
System.Reflection.RuntimeMethodInfo.Invoke(对象
OBJ,的BindingFlags invokeAttr,捆扎机
粘合剂,对象[]参数,
的CultureInfo文化,布尔
skipVisibilityChecks)在
System.Delegate.DynamicInvokeImpl(对象[]
参数)在
System.Windows.Threading.ExceptionWrapper.InternalRealCall(代表
回调,对象指定参数时,的Int32 numArgs)
。在
MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象
源,委托方法,对象ARGS,
的Int32 numArgs,代表catchHandler)

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: There is a type mismatch between the client and the service. Type 'Crm.Objects.Segmentation' is not an entity type, but the type in the response payload represents an entity type. Please ensure that types defined on the client match the data model of the service, or update the service reference on the client. at System.Data.Services.Client.AtomMaterializer.MaterializeResolvedEntry(AtomEntry entry, Boolean includeLinks) at System.Data.Services.Client.AtomMaterializer.Materialize(AtomEntry entry, Type expectedEntryType, Boolean includeLinks) at System.Data.Services.Client.AtomMaterializer.DirectMaterializePlan(AtomMaterializer materializer, AtomEntry entry, Type expectedEntryType) at System.Data.Services.Client.AtomMaterializerInvoker.DirectMaterializePlan(Object materializer, Object entry, Type expectedEntryType) at System.Data.Services.Client.ProjectionPlan.Run(AtomMaterializer materializer, AtomEntry entry, Type expectedType) at System.Data.Services.Client.AtomMaterializer.Read() at System.Data.Services.Client.MaterializeAtom.MoveNextInternal() at System.Data.Services.Client.MaterializeAtom.MoveNext() at System.Linq.Enumerable.d_b11.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at MangoCrm.Modules.Replication.ReplicaBuilder.GetItems[T](IEnumerable`1 query) at MangoCrm.Modules.Replication.ReplicaBuilder.BeginReplication() at MangoCrm.Modules.Replication.ReplicationWindowControl.b_0() --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

下面是我的代码:

            var uri = new Uri(webServiceUrl);
            var service = new DataServiceContext(uri);
            MessageBox.Show(service.CreateQuery<Segmentation>("DbSegmentations").ToList().Count.ToString());



任何帮助吗?

Any help?

更新
OK现在我发现我的WCF的反响含有修饰的实体对象。在这里,它是:

UPDATE ok now I found out that my WCF responce contains a modified entity object. Here it is:

<?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?何改回来?

So the question is why my Crm.Objects.Segmentation became Crm.Data.Segmentation? Ho to change it back?

UPDATE2
我认为这个问题是在我的数据上下文。数据上下文有一个命名空间Crm.Data。我的实体在Crm.Objects。然后我用4.0.0 WCF一切都很好,但后来我改用CTP2我的实体获得Crm.Data命名空间,而不是一个正确的Crm.Objects

UPDATE2 I think the problem is in my data context. The data context has a namespace Crm.Data. My entities are in Crm.Objects. Then I use 4.0.0 WCF everything is fine, but then I switch to CTP2 my entities get Crm.Data namespace instead of a correct Crm.Objects

推荐答案

你有没有尝试 DataServiceContext.ResolveName 和 DataServiceContext.ResolveType ?这2名代表,如果提供,可以用来修正内容ODATA命名空间+名之间的映射,而被序列化和反序列化客户端上的类型。

Did you try implementing delegates for DataServiceContext.ResolveName and DataServiceContext.ResolveType? Those 2 delegates, if provided, can be used to fixup the mapping between odata namespaces + names, and the types that are serialized and deserialized on the client.

下面是一个简单的例子:

Here is a simple example:

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数据服务客户端工作;

I had to do something like this (but I made it flexible instead of hard-coded) in order to make my entity classes work in the WCF Data Services client;

但是,即使这样做之后,我有此错误:

But even after doing this, I had this error:

System.InvalidOperationException:有是在客户端和服务之间的类型不匹配。型工作项'不是实体的类型,但在响应的负载的类型表示的实体类型。请确保在客户端上定义的类型相匹配的服务的数据模型,或者更新客户端上的服务引用

System.InvalidOperationException : There is a type mismatch between the client and the service. Type WorkItem' is not an entity type, but the type in the response payload represents an entity type. Please ensure that types defined on the client match the data model of the service, or update the service reference on the client.

我发现,这个工作两个定位:

I found two fixes that worked for this:


  1. [DataServiceKey(ID)] 属性添加到您的实体类。

  2. 重命名你的〜Id属性,使之与 ID结束

  1. Add a [DataServiceKey("Id")] attribute to your entity class. or
  2. Rename your ~Id property so that it ends with ID

我想通了#2硬盘的方式 - 看反编译的IL(这是WCF数据服务5.2.0)。检查之后 ClientEdmModel ClientTypeUtil ,我碰到这种方法来 ClientTypeUtil

I figured out #2 the hard way - looking at the decompiled IL (this is for WCF Data Services 5.2.0). After reviewing ClientEdmModel and ClientTypeUtil, I came across this method in 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数据服务的客户端您波苏斯时,这是关键。

It's that name1.EndsWith("ID" that is the key when using your POCOs on the client side of WCF Data Services.

希望有所帮助。

这篇关于WCF DataService的(CTP2):有在客户端和服务之间的类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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