Два запроса, которые вы показали (один для контрольной точки UPnP и один для тестового клиента WCF) не эквивалентны . Пространство имен дочерних элементов элемента Browse в первом (UPnP) является пустым ("") пространством имен, тогда как во втором запросе (WCF TC) это "urn: schemas-upnp-org: service: ContentDirectory: 1" - пустой префикс привязывается к пустому пространству имен, если только он не связан с другим пространством имен, и он восстанавливается в запросе WCF, но не в запросе UPnP.
Теперь, если вы хотите, чтобы пространство имен параметров операции отличалось от пространства имен самой операции, вам нужно будет использовать контракт сообщения - который получит запрос, отправленный WCF, эквивалентным ( по префиксу по модулю) к запросу, отправленному контрольной точкой UPnP. Приведенный ниже код показывает, как будет определен контракт сообщения для генерации запроса, эквивалентного тому, который вы показали для контрольной точки.
public class StackOverflow_2495195
{
[MessageContract(WrapperName="Browse", WrapperNamespace="urn:schemas-upnp-org:service:ContentDirectory:1", IsWrapped=true)]
public class BrowseRequest
{
[MessageBodyMember(Namespace = "", Order = 0)]
public string ObjectID;
[MessageBodyMember(Namespace = "", Order = 1)]
public string BrowseFlag;
[MessageBodyMember(Namespace = "", Order = 2)]
public string Filter;
[MessageBodyMember(Namespace = "", Order = 3)]
public ulong StartingIndex;
[MessageBodyMember(Namespace = "", Order = 4)]
public ulong RequestedCount;
[MessageBodyMember(Namespace = "", Order = 5)]
public string SortCriteria;
}
[MessageContract(WrapperName = "BrowseResponse", WrapperNamespace = "urn:schemas-upnp-org:service:ContentDirectory:1", IsWrapped = true)]
public class BrowseResponse
{
[MessageBodyMember(Namespace = "", Order = 0)]
public string Result;
[MessageBodyMember(Namespace = "", Order = 1)]
public ulong NumberReturned;
[MessageBodyMember(Namespace = "", Order = 2)]
public ulong TotalMatches;
[MessageBodyMember(Namespace = "", Order = 3)]
public ulong UpdateID;
}
[ServiceContract(Namespace = "urn:schemas-upnp-org:service:ContentDirectory:1")]
public interface IContentDirectory
{
[OperationContract(Action = "urn:schemas-upnp-org:service:ContentDirectory:1#Browse")]
//void Browse(string ObjectID, string BrowseFlag, string Filter, ulong StartingIndex, ulong RequestedCount, string SortCriteria, out string Result, out ulong NumberReturned, out ulong TotalMatches, out ulong UpdateID);
BrowseResponse Browse(BrowseRequest request);
}
public class Service : IContentDirectory
{
//public void Browse(string ObjectID, string BrowseFlag, string Filter, ulong StartingIndex, ulong RequestedCount, string SortCriteria, out string Result, out ulong NumberReturned, out ulong TotalMatches, out ulong UpdateID)
//{
// Result = null;
// NumberReturned = 0;
// TotalMatches = 0;
// UpdateID = 0;
//}
public BrowseResponse Browse(BrowseRequest request)
{
return new BrowseResponse { NumberReturned = 0, Result = null, TotalMatches = 0, UpdateID = 0 };
}
}
static Binding GetBinding()
{
return new CustomBinding(
new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8),
new HttpTransportBindingElement());
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IContentDirectory), GetBinding(), "");
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<IContentDirectory> factory = new ChannelFactory<IContentDirectory>(GetBinding(), new EndpointAddress(baseAddress));
IContentDirectory proxy = factory.CreateChannel();
//string result;
//ulong ul1, ul2, ul3;
//proxy.Browse(null, null, null, 0, 0, null, out result, out ul1, out ul2, out ul3);
proxy.Browse(new BrowseRequest { BrowseFlag = null, Filter = null, ObjectID = null, RequestedCount = 0, SortCriteria = null, StartingIndex = 0 });
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
Теперь запрос, отправляемый WCF, эквивалентен XML, но префиксы все еще разные. Это, как отметил Джон Сондерс, это не должно иметь значения, поэтому в WCF нет простой ручки, позволяющей установить префикс для элементов, записанных в сообщениях WCF. Вы можете, однако, использовать пользовательский кодировщик, чтобы сделать именно это. Некоторое время назад я писал об этом на http://blogs.msdn.com/b/carlosfigueira/archive/2010/06/13/changing-prefixes-in-xml-responses.aspx - вы можете использовать этот пример для создания пользовательского кодировщика, который установит префиксы в ожидаемые значения.