WCF: что такое использование пространства имен как именованного параметра в атрибуте DataContract [duplicate]

Интересно, что ни один из ответов на этой странице не упоминает два крайних случая, надеюсь, никто не возражает, если я их добавлю:

Случай с краем # 1: одновременный доступ к словарю

Родовые словари в .NET не являются потокобезопасными, а иногда могут бросать NullReference или даже (чаще) a KeyNotFoundException при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае является довольно ошибочным.

Случай с краем # 2: небезопасный код

Если код NullReferenceException задан кодом unsafe, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.

(Еще одна причина для небезопасного использования небезопасного кода, если вам это нужно)

17
задан Xaisoft 27 September 2010 в 21:18
поделиться

5 ответов

Эти свойства управляют пространством имен и именем элемента в WSDL. Важной частью вашего кода является Namespace="": это переопределит пространство имен по умолчанию (http://tempuri.org) и установит его значение в пустой URL.

В конце концов, класс User будет переименован в WSDL из http://tempuri.org/User просто пользователю.

7
ответ дан Johann Blais 27 August 2018 в 21:40
поделиться

Ответ Johann, IMO является правильным.

Он работает таким образом, потому что когда вы отправляете сообщения SOAP, элементы должны иметь пространство имен, иначе WCF не знает, как десериализовать SOAP в Контракт пользовательских данных из-за несоответствия пространства имен.

В C # эти два объекта различаются, потому что они находятся в разных пространствах имен ...

namespace UserServices
{
    public class User
    {
        public string FirstName { get; set; }
    }
}

namespace TempuriServices
{
    public class User
    {
        public string FirstName { get; set; }
    }
}

Пространство имен в XML / SOAP служит с той же целью, чтобы объекты были из одного и того же «тела» / «компании» / «организации» / «домена» и т. д.

. Из того, что я нашел, когда я создаю службы SOAP, я как правило, сохраняют все мои контракты с данными, контракты на обслуживание и пространства имен имен в одном и том же пространстве имен, например « http://mycompany.com/services/serviceName "

вот некоторые большие ресурсы ... Эквивалентность контракта данных => http://msdn.microsoft .com / ru-ru / library / ms734767.aspx Оптимизация версий контрактов данных => http://msdn.microsoft.com/en-us/library/ms733832.aspx

Надеюсь, это поможет.

10
ответ дан CedricB 27 August 2018 в 21:40
поделиться

В дополнение к другим ответам пространство имен в DataContract допускает два объекта с одинаковым именем в разных пространствах имен - например, управление версиями.

Эти два объекта могут существовать как разные свойства в WSDL и будут известны десериализуемые типы при условии, что они имеют разные пространства имен:

[DataContact(Namespace = "http://myservice/v1/thing")]
V1.Thing

[DataContact(Namespace = "http://myservice/v2/thing")]
V2.Thing

Конечно, они должны существовать и в вашем коде C #, чтобы он был действительным. Или, альтернативно, вы можете изменить имя, которое объекты известны с помощью атрибута Name для ясности.

[DataContact(Name = "Thing")]
V1.Thing

[DataContact(Name= = "newThing")]
V2.Thing

Вы можете использовать это, когда имя класса изменилось в вашем проекте, но вам нужно поддерживают существующие клиенты, которые используют «старые» имена.

Таким образом, свойства Name и Namespace управляют тем, как ваши объекты будут сериализованы и десериализованы при передаче по проводу. Когда вы их устанавливаете, вы контролируете, как клиент увидит ваши данные.

14
ответ дан Kirk Broadhurst 27 August 2018 в 21:40
поделиться

На основании другого вопроса и на:

Я не уверен, что атрибуты Name и Namespace относятся к атрибуту DataContract при вызове http: // localhost: 8081 / user / register например?

Я предлагаю вам использовать службу REST. Когда вы вызывали службу без установки пространства имен в пустую строку, вы определяли User XML с пространством имен xmlns = "http://tempuri.org"? Если вы не отправили для обслуживания другой / неизвестный тип данных, и это, вероятно, причина для возвращенной ошибки.

0
ответ дан Ladislav Mrnka 27 August 2018 в 21:40
поделиться

В дополнение к другим ответам, я попытаюсь добавить то, что знаю в этой теме. Короче говоря, они оба заменяют имя и пространство имен по умолчанию [DataContract] и [DataMember] (Name) тем, что вы предоставили этим свойствам. Согласно документации MS для свойства DataContractAttribute.Namespace (они называются свойствами атрибута, а не атрибута), в разделе «Совет» указывается ссылка ». Для того чтобы данные были успешно переданы, имя данных в контракте данных должно быть одинаковым как для клиента, так и для сервера. Проекты Visual Basic по умолчанию добавляют префикс к пространству имен, определенному в каждом файле (называемому «корневым пространством имен», названным в честь проекта) Добавление этого префикса приводит к тому, что пространства имен клиента и сервера будут отличаться для одного и того же типа. Решение состоит в том, чтобы установить для свойства Namespace значение «" или явно задать пространство имен контрактов данных в этом свойстве ». Из того, что я понял, для атрибута DataContract можно сериализовать / десериализовать данные, данные должны иметь соответствующее пространство имен как на стороне клиента, так и на стороне сервера, что всегда может быть не в реальной ситуации. Например, ваши данные на стороне сервера, если они называются читаемым и разумным способом, могут находиться под пространством имен, которое имеет имя, похожее на «NameOfTheSolution.Server.NameOfTheProject», тогда как на стороне клиента это может быть что-то вроде «NameOfTheSolution.Server.NameOfTheProject», NameOfTheSolution.Client.NameOfTheProject «. Из-за различного пространства имен DataContracts, атрибут [DataContract] не сможет сериализовать / десериализовать данные между клиентом и сервером. Я не уверен, но это может быть причиной того, что этот метод не разрешен в вашем случае из-за несоответствующего пространства имен. В ситуации, когда пространства имен не совпадают, свойство «Namespace» может использоваться при использовании атрибута [DataContract] и предоставлять классу с каждой стороны (клиент / сервер) те же пространства имен, хотя они физически лежат в разных пространствах имен.

[DataContract (Namespace = “Whatever you want, usually uri”)]
public class User
{}

Что касается свойства 'Name' атрибута [DataContract], оно переопределяет имя вашего datacontract с именем, которое вы предоставили этому свойству. Одно его использование в контексте атрибута DataMember - это перегрузка метода в рамках контракта данных. DataContract не позволяет использовать два имени DataMember с таким же именем, поэтому в таком сценарии полезно использовать свойство Name.

1
ответ дан NoSaidTheCompiler 27 August 2018 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: