Specified-поля в SOAP веб-сервисах
В уже упоминавшемся ASP.NET-приложении, которое использует сторонний SOAP-веб сервис, для генерации proxy-классов использует механизм, доступный из Visual Studio как «Add Web Reference». После обновления до Visual Studio 2010 SP1 для элементов, объявленных в WSDL с аттрибутом minOccurs="0" с типом, отличным от type="xsd:string", например, так:
<xsd:element minOccurs="0" name="MyField" type="xsd:boolean" />
В proxy-классах генерировалось дополнительное свойство bool MyFieldSpecified. Если не поставить его в true перед вызовом веб-сервиса, поле не будет включено в SOAP-запрос. В моём случае изменить веб-сервис не было возможности (он сторонний), а все поля в вызове сервиса на самом деле обязательные. Найденные существующие решения либо требовали дополнительной обработки кода proxy-классов, либо ручного заполнения свойств или не подходили в моей ситуации.
Решение через Reflection:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace CrispStudio.Routine.WebServices
{
public static class WebServicesUtils
{
public static void HandleSpecifiedFields(object obj)
{
var type = obj.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
if (property.Name.EndsWith("Specified"))
{
property.SetValue(obj, true, null);
}
}
}
}
}
Пример использования:
var myService = new MyServiceProxyClass(); var result = service.MyMethod(WebServicesUtils.HandleSpecifiedFields(params));
