Интересно, что ни один из ответов на этой странице не упоминает два крайних случая, надеюсь, никто не возражает, если я их добавлю:
Родовые словари в .NET не являются потокобезопасными, а иногда могут бросать NullReference
или даже (чаще) a KeyNotFoundException
при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае является довольно ошибочным.
Если код NullReferenceException
задан кодом unsafe
, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero
или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.
(Еще одна причина для небезопасного использования небезопасного кода, если вам это нужно)
Эти свойства управляют пространством имен и именем элемента в WSDL. Важной частью вашего кода является Namespace=""
: это переопределит пространство имен по умолчанию (http://tempuri.org) и установит его значение в пустой URL.
В конце концов, класс User будет переименован в WSDL из http://tempuri.org/User просто пользователю.
Ответ 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
Надеюсь, это поможет.
В дополнение к другим ответам пространство имен в 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 управляют тем, как ваши объекты будут сериализованы и десериализованы при передаче по проводу. Когда вы их устанавливаете, вы контролируете, как клиент увидит ваши данные.
На основании другого вопроса и на:
Я не уверен, что атрибуты Name и Namespace относятся к атрибуту DataContract при вызове http: // localhost: 8081 / user / register например?
blockquote>Я предлагаю вам использовать службу REST. Когда вы вызывали службу без установки пространства имен в пустую строку, вы определяли User XML с пространством имен xmlns = "http://tempuri.org"? Если вы не отправили для обслуживания другой / неизвестный тип данных, и это, вероятно, причина для возвращенной ошибки.
В дополнение к другим ответам, я попытаюсь добавить то, что знаю в этой теме. Короче говоря, они оба заменяют имя и пространство имен по умолчанию [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.