Что делает добавление Name и Namespace в DataContract? - PullRequest
17 голосов
/ 28 сентября 2010

Я попытался вызвать метод WebInvoke с именем Register, который возвращает принимает объект User и сразу же возвращает этот объект. Это выглядит следующим образом:

User Register(User user)
{
    return user;
}

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

Причина, по которой я спрашиваю, заключается в том, что мой класс изначально был украшен атрибутом DataContract, например:

[DataContract]
public class User
{
   // Properties
}

Когда я открыл Fiddler и отправил запрос Post, он сказал, что метод не разрешен, но когда я изменил DataContract на:

[DataContract(Name="User", Namespace="")]

Это сработало.

Ответы [ 5 ]

14 голосов
/ 01 октября 2010

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

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

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

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

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

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

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

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

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

10 голосов
/ 30 сентября 2010

Ответ Иоганна, 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/en-us/library/ms734767.aspx Версии Контракта данных BestПрактики => http://msdn.microsoft.com/en-us/library/ms733832.aspx

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

7 голосов
/ 28 сентября 2010

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

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

1 голос
/ 28 декабря 2013

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

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

Что касается свойства ‘Name’ атрибута [DataContract], оно переопределяет имя вашего datacontract на имя, которое вы указываете этому свойству. Одним из его применений в контексте атрибута DataMember является перегрузка метода в контракте данных. DataContract не допускает двух DataMember с одинаковыми именами, поэтому в таком случае полезно использовать свойство «Имя».

0 голосов
/ 28 сентября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...