WCF известный тип от системы. Объект в конфигурации

Я пытаюсь указать известный тип в своей конфигурации, но у меня есть проблемы с тем, что она происходит из Объекта. Я могу заставить его работать, указав известный тип через атрибут. Но в этом случае я должен заставить его работать от конфигурации.

Вот пример. Следующее хорошо работает:

[ServiceContract]
[ServiceKnownType(typeof(MyData))]
public interface IContract
{
    [OperationContract]
    void Send(object data);
}

[DataContract]
public class MyData
{
    [DataMember]
    public string Message { get; set; }
}

Но если я удаляю атрибут ServiceKnownType и помещаю следующее в конфигурацию:

<system.runtime.serialization>
  <dataContractSerializer>
    <declaredTypes>
      <add type="System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <knownType type="WpfApplication1.MyData, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </add>
    </declaredTypes>
  </dataContractSerializer>
</system.runtime.serialization>

Я добираюсь, ConfigurationErrorsException с сообщением "Значение для свойства 'тип' не допустим. Ошибка: система типов. Объект не может использоваться в качестве заявленного типа в конфигурации".

Там должен так или иначе сделать эту работу через конфигурацию?

8
задан abatishchev 23 June 2012 в 18:19
поделиться

1 ответ

Ответ оказался в том, что невозможно сделать то, что я хочу, только в конфигурационном файле. Конфиг выше соответствует атрибуту [KnownType], используемому в DataContracts. Похоже, нет способа реализовать [ServiceKnownType] в конфигурации.

Альтернативный подход заключается в использовании атрибута [ServiceKnownType(methodName, type)] с пользовательским разделом конфигурации. Новый конфиг выглядит так:

<configuration>
  <configSections>
    <section
      name="serviceKnownTypes"
      type="WpfApplication1.ServiceKnownTypesSection, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </configSections>
  <serviceKnownTypes>
    <declaredServices>
      <serviceContract type="WpfApplication1.IContract, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <knownTypes>
          <knownType type="WpfApplication1.MyData, WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </knownTypes>
      </serviceContract>
    </declaredServices>
  </serviceKnownTypes>
</configuration>

Контракты:

[ServiceContract]
[ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))]
public interface IContract
{
    [OperationContract]
    void Send(object data);
}

[DataContract]
public class MyData
{
    [DataMember]
    public string Message { get; set; }
}

Класс-помощник, содержащий обратный вызов, возвращающий список известных типов

public static class KnownTypeHelper
{
    public static IEnumerable<Type> GetServiceKnownTypes(ICustomAttributeProvider provider)
    {
        List<Type> result = new List<Type>();

        ServiceKnownTypesSection serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes");
        DeclaredServiceElement service = serviceKnownTypes.Services[((Type)(provider)).AssemblyQualifiedName];

        foreach (ServiceKnownTypeElement knownType in service.KnownTypes)
        {
            result.Add(knownType.Type);
        }

        return result;
    }
}

Информацию о создании пользовательских секций конфига можно найти здесь:

http://msdn.microsoft.com/en-us/library/2tw134k3.aspx

http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx

9
ответ дан 5 December 2019 в 15:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: