Tuesday, April 14, 2009

Типы файлов и "ASP.NET пайплайн"

Как-то давно возникал вопрос проходят ли через ASP.NET запросы к файлам картинок, скриптов, css-к и тому подобным ресурсам. Сегодня нашлось время это проверить и оказалось, что под студийным веб-сервером проходят, а под IIS-м - нет. Так что ограничивать доступ к таким файлам на уровне веб-конфига не получится. Хотя если захотеть, думаю можно и под IIS-м пропустить все что хочется через ASP.NET, только вряд ли стоит это делать.

Sunday, April 12, 2009

WCF, Known Types, Serialization, Dictionary

Если вам знакомо большинство слов из названия статьи то вам сюда.

Итак, проблема. Есть контракт сервиса:


  1. [ServiceContract]

  2. public interface IService1

  3. {

  4. [OperationContract]

  5. string GetData(int value);

  6. [OperationContract]

  7. CompositeType GetDataUsingDataContract(CompositeType composite);

  8. }


* This source code was highlighted with Source Code Highlighter.
Описание CompositeType ниже:


  1. [DataContract]

  2. public class CompositeType

  3. {

  4. [DataMember]

  5. public string StringValue

  6. {

  7. get;

  8. set;

  9. }

  10. [DataMember]

  11. public Dictionary<string, object> Parameters

  12. {

  13. get;

  14. set;

  15. }

  16. }


* This source code was highlighted with Source Code Highlighter.
Все довольно просто.
Создаем простой клиент для этого сервиса и пытаемся передать int[] в нашем словаре параметров CompositeType.Parametes (Dictionary):


  1. Service1Client client = new Service1Client();

  2. CompositeType input = new CompositeType();

  3. input.Parameters= new Dictionary<string, object>();

  4. input.Parameters.Add("array", new int[] { 1, 2 });

  5. CompositeType output = client.GetDataUsingDataContract(input);


* This source code was highlighted with Source Code Highlighter.
И при работе получаем такое вот исключение:
There was an error while trying to serialize parameter http://tempuri.org/:composite. The InnerException message was 'Type 'System.Int32[]' with data contract name 'ArrayOfint:http://schemas.microsoft.com/2003/10/Serialization/Arrays' 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.

В интернете куча таких постов, которые до сих пор висят без ответа. Ни ServiceKnownType, ни KnowType аттрибуты не помогают. Потому что они работают для классов-наследников.

Решение этой проблемы гениально просто.
Добавляем аттрибут [KnownType(typeof(int[]))] или [ServiceKnownType(typeof(int[]))] куда нужно и в DataContract-класс добавляем поле типа System.Object.
(For english readers: solution is pretty smart. Just add to DataContract-class DataMember field of type System.Object. Then use KnownType or ServiceKnownType attributes )


  1. [DataContract]

  2. [KnownType(typeof(int[]))]

  3. public class CompositeType

  4. {

  5. [DataMember]

  6. public object UsedForKnownTypeSerializationObject;

  7. [DataMember]

  8. public string StringValue

  9. {

  10. get;

  11. set;

  12. }

  13. [DataMember]

  14. public Dictionary<string, object> Parameters

  15. {

  16. get;

  17. set;

  18. }

  19. }


* This source code was highlighted with Source Code Highlighter.

Похожий вопрос тута
All about known types
Data Contract Known Types