Как настроить сериализацию XML WCF

@Amadan использовал Enumerable # group_by в своем ответе. group_by и Enumerable#update (он же merge!) являются взаимозаменяемыми в том смысле, что когда один из них используется, другой может вместо него использовать обычно strike>. Я покажу, как update можно использовать здесь.

hashes.each_with_object({}) do |g,h|
  h.update(g[:id] => g.merge(source: [g[:source]])) do |_,oh,nh|
    oh.merge(source: oh[:source] + nh[:source])
  end
end.values
  #=> [{:id=>1, :value=>"something", :source=>["a", "b"]},
  #    {:id=>2, :value=>"something", :source=>["a"]},
  #    {:id=>3, :value=>"something", :source=>["c"]}] 

Во-первых, обратите внимание, что h.update(k=>v) является сокращением от h.update({ k=>v }). При этом используется форма Hash # update (он же merge!), в которой используется блок для определения значений ключей, которые присутствуют в обоих объединяемых хешах. Этот блок имеет три переменные блока: общий ключ (_), значение обновляемого хеша (oh, «o» для «старого», «h», потому что значение является хешем) и значение объединяемый хэш (nh, «n» для «нового»).

Шаги являются следующими.

e = hashes.each_with_object({})
  #=> #1, :value=>"something", :source=>"a"},
  #     {:id=>1, :value=>"something", :source=>"b"},
  #     {:id=>2, :value=>"something", :source=>"a"}, 
  #     {:id=>3, :value=>"something", :source=>"c"}
  #   ]:each_with_object({})> 

Первый элемент этого перечислителя генерируется, передается в блок и присваивается переменным блока.

g,h = e.next
  #=> [{:id=>1, :value=>"something", :source=>"a"}, {}] 
g #=> {:id=>1, :value=>"something", :source=>"a"} 
h #=> {} 

Затем выполняется вычисление блока.

h.update(g[:id]  => g.merge(source: [g[:source]]))
  #=> h.update(1 => g.merge(source: ["a"]))
  #=> h.update(1 =>{:id=>1, :value=>"something", :source=>["b"]})
  #=> {1=>{:id=>1, :value=>"something", :source=>["b"]}}

До выполнения этого слияния h было пустым, что означало, что у двух объединяемых хешей не было общих ключей. Поэтому блок разрешения значения update не был вызван.

Теперь update направляется [1125] для генерации следующего значения и передачи его в блок. Переменные блока присваиваются этому значению, и выполняется вычисление блока.

g,h = e.next
  #=> [{:id=>1, :value=>"something", :source=>"b"},
  #    {1=>{:id=>1, :value=>"something", :source=>["a"]}}] 
g #=>  {:id=>1, :value=>"something", :source=>"b"} 
h #=>  {1=>{:id=>1, :value=>"something", :source=>["a"]}} 

Обратите внимание, что h было обновлено. Теперь вычислите:

h.update(g[:id] => g.merge(source: [g[:source]])) do |_,oh,nh|
  oh.merge(source: oh[:source] + nh[:source])
end
  #=> {1=>{:id=>1, :value=>"something", :source=>["a", "b"]}} 

Как

g[:id]
  #=> 1

и

g.merge(source: [g[:source]])
  #=> g.merge(source: ["b"])
  #=> {:id=>1, :value=>"something", :source=>["b"]} 

приведенное выше выражение сокращается до

h.update(1 => {:id=>1, :value=>"something", :source=>["b"]}) do |_,oh,nh|
  oh.merge(source: oh[:source] + nh[:source])
end

, так как оба хэша являются объединенные имеют общий ключ 1, блок вызывается для определения значения 1 в объединенном хэше:

_ = 1
oh = h[1]
  #=> {:id=>1, :value=>"something", :source=>["a"]}
nh = g.merge(source: [g[:source]]) 
  #=> g.merge(source: ["b"])
  #=> {:id=>1, :value=>"something", :source=>["b"]}

Я использовал подчеркивание (действительное имя локальной переменной) для представляют общий ключ, чтобы сообщить читателю, что он не используется в расчете блока. Блок расчета следующий.

oh.merge(source: oh[:source] + nh[:source])
  #=> oh.merge(source: ["a", "b"])  
  #=> {:id=>1, :value=>"something", :source=>["a", "b"]}

Расчеты аналогичны для остальных элементов, сгенерированных e. Таким образом, мы получаем:

f = hashes.each_with_object({}) do |g,h|
  h.update(g[:id] => g.merge(source: [g[:source]])) do |_,oh,nh|
    oh.merge(source: oh[:source] + nh[:source])
  end
end
  #=> {1=>{:id=>1, :value=>"something", :source=>["a", "b"]},
  #    2=>{:id=>2, :value=>"something", :source=>["a"]},
  #    3=>{:id=>3, :value=>"something", :source=>["c"]}} 

Последний шаг - возврат f.values.

8
задан Jeroen-bart Engelen 16 March 2009 в 10:44
поделиться

1 ответ

Определите пространства имен с Сериализацией XML (или, лучше) атрибуты определения Контракта Данных.

например, с Сериализацией XML:

[Serializable, XmlRoot(namespace="http://example.com/eg1")]
public class MyClass {
  [XmlElement(ElementName = "DataString")]
  public string MyString { get; set; }
}

например, с сериализацией Контракта Данных:

[DataContract(Namespace="http://example.com/eg2")]
public class MyClass {
  [DataMember]
  public string MyString { get; set; }
}

Править

На основе первого комментария не будет работать вышеупомянутое, потому что требование состоит в том, чтобы установить пространство имен на обертке SOAP вокруг сообщения, не на самом сообщении.

OperationContractAttribute предложения никакое управление пространств имен, и я не вижу никаких других атрибутов WCF на уровне метода.

Две возможности: (1) Можно иметь достаточно контроля путем отбрасывания уровня абстракции и использования сообщения Контракт. (2) Получите текущий WSDL для сервиса (использование svcutil.exe), вручную корректируя его для получения пространств имен Вы хотите, и затем использование svcutil.exe снова сгенерировать код и посмотреть на получающийся код.

3
ответ дан 6 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

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