Библиотека WCF и Castle (Glass Mapper)

привет, у меня есть служба WCF с webHttpEndpointBehavior под Sitecore 6, и я использую Glass Mapper для чтения элементов, Glass mapper зависит от библиотеки Castle.

Он работает хорошо, но у меня есть несколько методов с контрактом, например:

        [OperationContract]
        [WebInvoke(Method = "POST",BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        List<Shade> GetAllShades(int columns, int rows);

где я пытаюсь вернуть список своего класса в формате JSON, во время отладки моей службы с помощью SvcTraceViewer.exe я обнаруживаю следующую ошибку:

Произошла ошибка при попытке сериализации параметра :GetFamilyShadesResult. Сообщение InnerException было «Тип Castle.Proxies.ShadeProxy» с именем контракта данных «ShadeProxy:http://schemas.datacontract.org/2004/07/Castle.Proxies' не ожидается. Рассмотрите возможность использования DataContractResolver или добавления любых типов, которые не известны статически, в список известных типов, например, с помощью атрибута KnownTypeAttribute или добавления их в список известных типов, передаваемых в DataContractSerializer.'. Пожалуйста, смотрите InnerException для более подробной информации.

Как решить эту проблему? Castle.Proxies.ShadeProxy — это динамический класс в Castle, и я не могу использовать KnownTypeAttribute.

На самом деле, если я использую библиотеку JSON.net и возвращаю результаты в виде строки, все работает нормально.


person Arbejdsglæde    schedule 30.07.2012    source источник


Ответы (1)


Я предполагаю, что у вас есть класс, который ссылается на другие классы, загруженные через Glass, например.

[SitecoreClass]
public class Shade{

    [SitecoreField]
    public virtual IEnumerable<AnotherClass> SomeField{get;set;}

    [SitecoreChildren]
    public virtual IEnumerable<AnotherClass> Children{get;set;}      
}
[SitecoreClass]
public class AnotherClass{}

Чтобы разрешить ленивую загрузку классов, Glass использует прокси-серверы, созданные Castle, поэтому во время выполнения, когда классы загружаются в свойство SomeField, вы фактически получаете подкласс класса AnotherClass.

Чтобы решить эту проблему, вы должны явно указать классу загружать другие классы как конкретные типы, обновление атрибута SitecoreField должно решить эту проблему:

[SitecoreClass]
public class Shade{

    [SitecoreField(Setting=SitecoreFieldSettings.DontLazyLoad)]
    public virtual IEnumerable<AnotherClass> SomeField{get;set;}

    [SitecoreChildren(IsLazy=false)]
    public virtual IEnumerable<AnotherClass> Children{get;set;}
}
[SitecoreClass]
public class AnotherClass{}
person Michael Edwards    schedule 31.07.2012
comment
@Michael: Как мне объединить настройки? т.е. для public virtual IEnumerable<AnotherClass> SomeField{get;set;} я хочу отключить отложенную загрузку, а также включить InferType. Это возможно? - person GFoley83; 12.04.2013