Specified-поля в SOAP веб-сервисах

27.05.2011 16:52 / Артём Волк / 553 просмотра / ...

В уже упоминавшемся 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));