2011-05-31 78 views
2

叫我的服务,当我得到这个错误:WCF已知类型错误

Server Error in '/' Application. 
-------------------------------------------------------------------------------- 

Configuration Error 
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. 

Parser Error Message: There was an error while trying to serialize parameter http://DSD.myCompany.net/DsdWebServices/2011/05/:config. The InnerException message was 'Type 'System.OrdinalComparer' with data contract name 'OrdinalComparer:http://schemas.datacontract.org/2004/07/System' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details. 

Source Error: 


Line 130:   passwordAttemptWindow="10" 
Line 131:   passwordStrengthRegularExpression="" 
Line 132:   type="DsdWebsite.Providers.DsdMembershipProvider, DsdWebsite.Providers" /> 
Line 133:  </providers> 
Line 134: </membership> 


Source File: C:\Development\DSD Website\WebUI\web.config Line: 132 


-------------------------------------------------------------------------------- 
Version Information: Microsoft .NET Framework Version:2.0.50727.5444; ASP.NET Version:2.0.50727.5420 

的服务是成员资格提供数据服务。我创建了一个MembershipUser DTO来在整个服务中来回移动数据。它只使用标准类:string,int,DateTime。我使用guid而不是objectUserKey作为对象。

该服务的界面看起来是这样的:

[ServiceContract(Namespace = "http://DSD.myCompany.net/DsdWebServices/2011/05/")] 
[ServiceKnownType(typeof(MembershipUserDTO))] 
[ServiceKnownType(typeof(NameValueCollection))] 
[ServiceKnownType(typeof(Guid))] 
[ServiceKnownType(typeof(DateTime))] 
public interface IDsdMembershipProviderService 
{ 
    [OperationContract] 
    void Initialize(string name, NameValueCollection config); 

    [OperationContract] 
    MembershipUserDTO CreateUser(string username, 
     string salt, 
     string encodedPassword, 
    ... 

的DTO看起来像这样

namespace DsdWebsite.Services.Providers 
{ 
    [Serializable] 
    [DataContract] 
    [KnownType(typeof(Guid))] 
    [KnownType(typeof(DateTime))] 
    public class MembershipUserDTO 
    { 
     public MembershipUserDTO(string providerName, string userName, Guid providerUserKey, string email, 
           string passwordQuestion, string comment, bool isApproved, bool isLockedOut, 
           DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, 
           DateTime lastPasswordChangedDate, DateTime lastLockoutDate, 
           string firstName, string lastName, string cellPhone, string officePhone, 
           string brokerId, bool isAdmin, bool mustChangePassword) 
     { 
      ProviderName= providerName; 
      UserName = userName; 
      ProviderUserKey= providerUserKey; 
      Email= email; 
      PasswordQuestion= passwordQuestion; 
      Comment= comment; 
      IsApproved=isApproved; 
      IsLockedOut= isLockedOut; 
      CreationDate= creationDate; 
      LastLoginDate= lastLoginDate; 
      LastActivityDate= lastActivityDate; 
      LastPasswordChangedDate = lastPasswordChangedDate; 
      LastLockoutDate=lastLockoutDate; 
... 

最后,我的web.config看起来是这样的:

<membership 
defaultProvider="DsdMembershipProvider" 
userIsOnlineTimeWindow="15" 
hashAlgorithmType=""> <providers> 
    <clear/> 
    <add 
     name="DsdMembershipProvider" 
     connectionStringName="DsdMembershipConnectionString" 
     enablePasswordRetrieval="true" 
     enablePasswordReset="true" 
     requiresQuestionAndAnswer="true" 
     applicationName="/DsdWebsite/" 
     requiresUniqueEmail="true" 
     passwordFormat="Encrypted" 
     maxInvalidPasswordAttempts="5" 
     minRequiredPasswordLength="7" 
     minRequiredNonalphanumericCharacters="0" 
     passwordAttemptWindow="10" 
     passwordStrengthRegularExpression="" 
     type="DsdWebsite.Providers.DsdMembershipProvider, 
DsdWebsite.Providers" /> 
</providers> </membership> 

如何我可以确定导致错误的类型或对象吗? 感谢

+0

我无法找到System.OrdinalComparer - 来自哪里? – 2011-05-31 17:28:33

+0

@Terry:我会在短时间内更新信息。 – 2011-05-31 17:34:03

+0

总猜测:右键单击服务参考,单击配置服务参考,使用集合类型和字典集合类型下拉框。 – 2011-05-31 19:26:49

回答

2

使用以下ServiceKnownTypeAttribute构造指定包含静态方法methodName,将返回服务已知类型的类的类型(declaringType):

public ServiceKnownTypeAttribute(
    string methodName, 
    Type declaringType 
) 

里面的上述静态方法添加的所有服务而闻名类型已经(尽管我认为如果没有DateTimeGuid,你会做得很好),并且还要加上System.OrdinalComparer

问题在于System.OrdinalComparer是内部类,因此您必须通过反射来获取类型。

编辑:

System.OrdinalComparermscorlib组件的一部分。基本上你可以用以下方式获得它的类型:

Type[] types = typeof(string).Assembly.GetTypes(); 

,然后你可以(使用LINQ,添加使用报表进行必要的)按名称检索想要的类型。

Type type = types.Where(x => x.FullName == "System.OrdinalComparer"); 

以上两行可以合并为一个,为简单起见使用两行完成。

如果您需要更多的细节,请说。

+0

我试过但得到完全相同的错误。我从契约接口中删除了[ServiceKnownType]属性,并将[ServiceKnownType(“GetKnownType”)]属性添加到类本身。 类型[] corTypes = typeof(string).Assembly.GetTypes();类型[] 类型ordinalCompareType =(从corTypes中的t where t.FullName ==“System.OrdinalComparer”select t)。FirstOrDefault(); Type [] types = new [] {ordinalCompareType,typeof(MembershipUserDTO)}; 返回类型; } 不幸的是它没有区别。 – Sisiutl 2011-05-31 18:43:19

+0

@Sisiutl:你重建并重新运行服务,然后更新服务参考? – 2011-05-31 19:04:31

+0

很多时候:-)有没有办法告诉哪些类正在使用OrdinalComparer?我的DTO只使用字符串,int,bool和DateTime。服务方法接受并返回bool,int,string,Guid,DTO,List 和NameValueCollection。它可能是NameValueCollection? – Sisiutl 2011-05-31 19:18:17