Что добавляет имя и пространство имен в DataContract?

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

User Register(User user)
{
    return user;
}

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

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

[DataContract]
public class User
{
   // Properties
}

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

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

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

Ответы

Ответ 1

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

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

Ответ 2

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

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

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

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

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

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

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

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

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

Ответ 3

Ответ Иоганна, ИМО - правильный.

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

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

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 Оптимизация версий контрактов данных = > http://msdn.microsoft.com/en-us/library/ms733832.aspx

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

Ответ 4

В дополнение к другим ответам я попытаюсь добавить то, что знаю в этой теме. Короче говоря, они оба заменяют имя и пространство имен по умолчанию [DataContract] и [DataMember] (Name) тем, что вы предоставили этим свойствам. Согласно документации MSs для свойства 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.

Ответ 5

Основываясь на другом вопросе и на:

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

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