2013-07-01 2 views
1

Я пытаюсь использовать сторонний SOAP API от .NET. Как обычно, я создал класс прокси-сервера C# для его вызова, и все работает нормально.В чем заключается изменение атрибута класса .NET?

Затем я поговорил с продавцом и выяснил, что для переключения между арендаторами (базами данных) я должен указать другое пространство имен XML. Проблема в том, что пространство имен выпекается в прокси-код. Обезличенная версия:

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] 
[System.Web.Services.WebServiceBindingAttribute(
    Name="eStrangeAPI", Namespace="urn:wsTenantSpecific")] 
public partial class eTimeWSService : System.Web.Services.Protocols.SoapHttpClientProtocol { 
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", 
     RequestNamespace="urn:wsTenantSpecific:eStrange", 
     ResponseNamespace="urn:wsClientSpecificNamespace:eStrange", ...] 
    ... 
    public string methodCall(ref Param param) { 
     ... 
    } 

Так что мне нужно изменить wsTenantSpecific пространства имен в зависимости от учетной записи в настоящее время используется. Я могу захватить атрибуты класса и изменить их на лету ...

var attr = ((WebServiceBindingAttribute[]) 
    typeof(eTimeWSService).GetCustomAttributes(
    typeof(WebServiceBindingAttribute), false))[ 0 ]; 
attr.Namespace = "urn:wsADifferentNameSpace"; 

... но я обеспокоен тем, как поточно это. Мы могли бы одновременно подключать несколько учетных записей, используя ASP.NET-запросы для разных потоков в одном и том же процессе.

Вопрос в нижней строке: если я изменяю атрибут, он изменен для всего процесса или только текущего потока?

ответ

2

Вопрос о нижнем строчке: если я изменяю атрибут, изменен ли он для всего процесса или только текущего потока?

Ни то, ни другое. И то и другое. Это зависит.

Объекты атрибутов фактически не существуют до тех пор, пока кто-то не попросит их, и даже тогда нет никакой гарантии, что каждый раз, когда вы спросите, вы получите тот же экземпляр - так что изменение значений атрибута может иметь никакого воздействия вообще на другом вызывающем абоненте, проверяющем атрибут. Однако в некоторых сценариях экземпляр атрибута может быть кэширован, и в этом случае вы получите , и это может иметь значение. Но! Говоря о сериализаторах и аналогичных инструментах, есть хорошая ставка, что мета-программирование и кэшированные стратегии используются, поэтому он не проверяет атрибуты каждый раз - действительно, он мог бы испустить какой-то динамический код в первый раз и теперь не имеет никакого намерения пересмотреть рефлексивный аспект.

Я бы искал другой подход, лично. Мутирующие атрибуты - не лучший способ сделать это.

В качестве примера, это пишет hello/hello (изменение теряется):

using System; 
class FooAttribute : Attribute { 
    public FooAttribute(string bar) { 
     Bar = bar; 
    } 
    public string Bar { get; set; } 
} 
[Foo("hello")] 
class Program { 
    static void Main() { 
     WriteFooBar<Program>(); 
     var d = (FooAttribute)Attribute.GetCustomAttribute(
      typeof(Program), typeof(FooAttribute)); 
     d.Bar = "world"; 
     WriteFooBar<Program>(); 
    } 
    static void WriteFooBar<T>() { 
     var bar = ((FooAttribute)Attribute.GetCustomAttribute(
      typeof(T), typeof(FooAttribute))).Bar; 
     Console.WriteLine(bar); 
    } 
} 

и записывает это похоже код hello/world (изменение сохраняется):

using System; 
using System.ComponentModel; 
class FooAttribute : Attribute { 
    public FooAttribute(string bar) { 
     Bar = bar; 
    } 
    public string Bar { get; set; } 
} 
[Foo("hello")] 
class Program { 
    static void Main() { 
     WriteFooBar<Program>(); 
     var d = (FooAttribute)TypeDescriptor.GetAttributes(typeof(Program))[ 
      typeof(FooAttribute)]; 
     d.Bar = "world"; 
     WriteFooBar<Program>(); 
    } 
    static void WriteFooBar<T>() { 
     var bar = ((FooAttribute)TypeDescriptor.GetAttributes(typeof(Program))[ 
      typeof(FooAttribute)]).Bar; 
     Console.WriteLine(bar); 
    } 
} 

(потому что TypeDescriptor.GetAttributes кэширует фактические экземпляры атрибутов для каждого типа, где-Attribute.GetCustomAttribute создает новые экземпляры за звонок)

+0

спасибо Марк. Я предположил, что мне нужно попробовать другой подход, но надеялся, что есть простой способ. –

1

Я думаю, что лучший способ здесь - не использовать прокси-класс, а отправить запрос SOAP на сервер, который дает полный контроль над xml, который вы хотите отправить и получить на и с сервера соответственно.

Используйте класс HttpWebRequest и WebResponse, чтобы получить контроль над запросом на мыло. Измените пространство имен (xmlns: xsi) в соответствии с вашей логикой.

Для е, г,: -

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     Your Request goes here.... 
    </soap:Body> 
</soap:Envelope> 

Пожалуйста, см proxy less web service client

+0

Я думал об этом ... этот API очень уродливый, хотя :-) –

Смежные вопросы