2011-05-31 75 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