Вопрос о динамическом вызове веб-служб

я играл с атрибутами через веб-службы, и я видел, что класс SoapHttpClientProtocol должен определить атрибут WebServiceBinding.

Наблюдая за этим вопросом, кажется нельзя изменить атрибуты во время выполнения, как я могу добиться динамического вызова веб-службы, изменяющего этот атрибут во время выполнения? Является ли это возможным?

[Изменить] Я ищу подход к динамическому вызову «общего стиля», а не к изменению атрибута WebServiceBinding.

Это, в двух словах, мой класс:

using System.Web.Services;
using System.Web.Services.Protocols;

namespace Whatever {
    [WebServiceBinding(Name = "", Namespace = "")]
    public class WebServiceInvoker : SoapHttpClientProtocol {
        public WebServiceInvoker(string url, string ns, string bindingName) {

            ChangeNamespace(ns);
            ChangeBinding(bindingName);
            Url = url;
            // credentials, etc
    }
        public void ChangeNamespace(string ns) {
            var att = GetType().GetCustomAttributes(typeof (WebServiceBindingAttribute), true);         
            if (att.Length > 0) {
                // doesn't work
                ((WebServiceBindingAttribute)att[0]).Namespace = ns;
            }
        }
        private void ChangeBinding(string bindingName) {
            var att = GetType().GetCustomAttributes(typeof(WebServiceBindingAttribute), true);

            if (att.Length > 0) {
                // doesn't work
                ((WebServiceBindingAttribute)att[0]).Name = bindingName;
            }
        }
        public object[] MakeInvoke(string method, object[] args) {
            var res = Invoke(method, method);
            return res;
        }

        public TRet InvokeFunction<TRet>(string method) {
            //Funcion<T1, T2, T3, TRet>
            var res = Invoke(method, null);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, TRet>(string method, T1 par1) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1 };
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, T2, TRet>(string method, T1 par1, T2 par2) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2 };
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }
        public TRet InvokeFunction<T1, T2, T3, TRet>(string method, T1 par1, T2 par2, T3 par3) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] {par1, par2, par3};
            var res = Invoke(method, args);
            return MyUtils.ForceCast<TRet>(res);
        }

        public void InvokeAction(string metodo) {
            //Funcion<T1, T2, T3, TRet>
            Invoke(method, null);
        }
        public void InvokeAction<T1>(string method, T1 par1) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1 };
            Invoke(method, args);
        }
        public void InvokeAction<T1, T2>(string method, T1 par1, T2 par2) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2 };
            Invoke(method, args);
        }
        public void InvokeAction<T1, T2, T3>(string method, T1 par1, T2 par2, T3 par3) {
            //Funcion<T1, T2, T3, TRet>
            var args = new object[] { par1, par2, par3 };
            Invoke(method, args);
        }
    }
}

[Изменить] Я хотел бы назвать свой класс так:

var miProxy = new WebServiceInvoker("http://webServiceLocation", "ns", "Binding");
var res = miProxy.InvokeFunction<string, string, Entity>("MyWebMethod", stringPar1, stringPar2);

person Community    schedule 30.03.2009    source источник


Ответы (5)


Я не совсем уверен, что вы пытаетесь здесь сделать... вы пытаетесь создать веб-службу, которая поддерживает вызов произвольных методов вызывающей стороной? Если да, то вот пример из практики: Создание динамического веб-сервиса для упрощения кода

person Community    schedule 30.03.2009
comment
Предоставленное вами решение хорошее, мне оно нравится, однако я искал способ объединить общие делегаты с вызовами веб-служб, я имею в виду, для вызова веб-службы, просто зная ее URL-адрес, не знаю, возможно ли это. - person Jhonny D. Cano -Leftware-; 31.03.2009

Вы не можете изменять атрибуты во время выполнения. Это просто метаданные в коде IL, и если вы запрашиваете атрибут, создается и возвращается экземпляр указанного класса атрибута. Таким образом, фактические экземпляры атрибутов не существуют, пока вы их не запросите.

Возможно, можно изменить сборку с помощью отражения, но я не уверен, и, вероятно, это не то, что вы хотели бы попробовать.

person Community    schedule 30.03.2009

Есть еще один действительно хороший пример этого в Crows Programming. Он описывает класс, который позволяет вам вызывать произвольные сообщения на любом веб-сервисе. Это на самом деле довольно гладко. Надеюсь, поможет.

person Community    schedule 11.04.2009

Как вы сказали, вы не можете изменить атрибут во время выполнения.

Единственный способ добиться эффекта добавления/удаления/изменения атрибута во время выполнения — это создать новый тип, обертывающий фактический тип. Однако прокси-классы времени выполнения имеют накладные расходы (сложность разработки и производительность) и редко когда-либо оправдывают себя в производственном коде.

Я бы, однако, проверил правильность утверждения:

Класс SoapHttpClientProtocol должен определить атрибут WebServiceBinding.

Microsoft обычно предлагает как минимум два способа снять шкуру с кота. Готов поспорить, что вышеизложенное не совсем верно. Вероятно, есть другой способ выполнить то, что вы пытаетесь сделать.

Я пытаюсь сказать следующее: вы можете лаять не по тому дереву, следуя маршруту атрибутов времени выполнения.

person Community    schedule 30.03.2009

Вы пробовали это

http://techmentis.blogspot.com/2011/05/dynamic-web-service-invoker.html

person Community    schedule 30.06.2011
comment
Хотя теоретически это может ответить на вопрос, было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки. - person Bill the Lizard; 30.06.2011