Ошибка известного типа WCF - PullRequest
2 голосов
/ 31 мая 2011

Я получаю эту ошибку при вызове моей службы:

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 

Услуга является услугой передачи данных для поставщика членства. Я создал DTO для MembershipUser для перемещения данных между сервисами. Используются только стандартные классы: string, int, DateTime. Я использую Guid вместо object для providerUserKey.

Интерфейс для сервиса выглядит так:

[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>

Как я могу определить, какой тип или объект вызывает ошибку? Спасибо

1 Ответ

2 голосов
/ 31 мая 2011

Используйте следующий конструктор ServiceKnownTypeAttribute, чтобы указать тип класса (declaringType), содержащий статический метод methodName, который будет возвращать известные типы сервисов:

public ServiceKnownTypeAttribute(
    string methodName,
    Type declaringType
)

Внутри вышеупомянутого статического метода добавьте все сервисыизвестные типы, которые уже добавлены (хотя я думаю, что вы бы хорошо обходились без DateTime и Guid), а также добавили бы System.OrdinalComparer.

Уловка в том, что System.OrdinalComparer является внутренним классом, поэтому выдолжен получить тип с помощью отражения.

РЕДАКТИРОВАТЬ:

System.OrdinalComparer является частью mscorlib сборки.Как правило, вы можете получить его тип следующим образом:

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

, а затем вы можете получить нужный тип по имени (используя Linq, добавьте необходимые с помощью операторов).

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

Предыдущийдве строки могут быть объединены в одну, для простоты, используя две строки.

Если вам нужно больше деталей, просто скажите.

...