C# 如何向WCF ServiceContract命名空间添加前缀

C# 如何向WCF ServiceContract命名空间添加前缀,c#,.net,wcf,upnp,C#,.net,Wcf,Upnp,我正在尝试在WCF中实现一个UPnP MediaServer。我正在慢慢地到达那里,但现在我遇到了困难。我需要向ServiceContract名称空间添加前缀。现在我有以下几点: [ServiceContract(Namespace = "urn:schemas-upnp-org:service:ContentDirectory:1")] public interface IContentDirectory { [OperationContract(Action = "urn:sche

我正在尝试在WCF中实现一个UPnP MediaServer。我正在慢慢地到达那里,但现在我遇到了困难。我需要向ServiceContract名称空间添加前缀。现在我有以下几点:

[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);
}
这将侦听正确的soap消息。但是,我首先需要soap主体

<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">

WCF现在正在收听:

<Browse xmlns="urn:schemas-upnp-org:service:ContentDirectory:1">

那里的前缀怎么取?这有关系吗?或者参数没有传递到Browse方法中还有其他原因吗

更新 这里有一些额外的信息:下面的消息是由一个真正的UPnP控制点发送的。参数是而不是传递到浏览方法中

<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://XXXXX:8731/ContentDirectory</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:schemas-upnp-org:service:ContentDirectory:1#Browse</Action>
  </s:Header>
  <s:Body>
      <u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
         <ObjectID>0</ObjectID>
         <BrowseFlag>BrowseDirectChildren</BrowseFlag>
         <Filter>*</Filter>
         <StartingIndex>0</StartingIndex>
         <RequestedCount>15</RequestedCount>
         <SortCriteria />
      </u:Browse>
   </s:Body>
</s:Envelope>

http://XXXXX:8731/ContentDirectory
urn:schemas-upnp-org:service:ContentDirectory:1#浏览
0
浏览定向儿童
*
0
15
这是由WCF测试客户端生成的请求。现在,参数被传递到Browse方法中:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://XXXXXX:8731/ContentDirectory</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:schemas-upnp-org:service:ContentDirectory:1#Browse</Action>
  </s:Header>
  <s:Body>
    <Browse xmlns="urn:schemas-upnp-org:service:ContentDirectory:1">
      <ObjectID>0</ObjectID>
      <BrowseFlag>BrowseMetadata</BrowseFlag>
      <Filter>*</Filter>
      <StartingIndex>0</StartingIndex>
      <RequestedCount>0</RequestedCount>
      <SortCriteria i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
    </Browse>
  </s:Body>
</s:Envelope>

http://XXXXXX:8731/ContentDirectory
urn:schemas-upnp-org:service:ContentDirectory:1#浏览
0
浏览器元数据
*
0
0

为什么需要特定的前缀?您使用的软件是否取决于前缀


如果是这样,那么软件就坏了。就XML而言,您给出的两个“XMLN”示例是相同的。任何关心差异的软件都严重受损,需要学习XML。

您显示的两个请求(一个由UPnP控制点提出,一个由WCF测试客户端提出)并不等价。第一个(UPnP)中Browse元素的子元素的名称空间是空的(“”)名称空间,而在第二个请求(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();
    }
}
公共类StackOverflow_2495195
{
[MessageContract(WrapperName=“Browse”,WrapperNamespace=“urn:schemas-upnp-org:service:ContentDirectory:1”,IsWrapped=true)]
公共类浏览器请求
{
[MessageBodyMember(名称空间=”,顺序=0)]
公共字符串ObjectID;
[MessageBodyMember(名称空间=”,顺序=1)]
公共字符串浏览标志;
[MessageBodyMember(名称空间=”,顺序=2)]
公共字符串过滤器;
[MessageBodyMember(名称空间=”,顺序=3)]
公共乌龙启动指数;
[MessageBodyMember(名称空间=”,顺序=4)]
公共ulong请求计数;
[MessageBodyMember(名称空间=”,顺序=5)]
公共字符串分类标准;
}
[MessageContract(WrapperName=“BrowserResponse”,WrapperNamespace=“urn:schemas-upnp-org:service:ContentDirectory:1”,IsWrapped=true)]
公共类浏览器响应
{
[MessageBodyMember(名称空间=”,顺序=0)]
公共字符串结果;
[MessageBodyMember(名称空间=”,顺序=1)]
公共乌龙号已返回;
[MessageBodyMember(名称空间=”,顺序=2)]
公开比赛;
[MessageBodyMember(名称空间=”,顺序=3)]
公共图书馆;
}
[ServiceContract(Namespace=“urn:schemas-upnp-org:service:ContentDirectory:1”)]
公共接口IContentDirectory
{
[OperationContract(Action=“urn:schemas-upnp-org:service:ContentDirectory:1#Browse”)]
//无效浏览(字符串ObjectID、字符串BrowseFlag、字符串筛选器、ulong StartingIndex、ulong RequestedCount、字符串排序标准、out字符串结果、out ulong NumberReturned、out ulong TotalMatches、out ulong UpdateID);
BrowserResponse浏览(BrowserRequest请求);
}
公共类服务:IContentDirectory
{
//public void Browse(字符串ObjectID、字符串BrowseFlag、字符串筛选器、ulong StartingIndex、ulong RequestedCount、字符串排序标准、out字符串结果、out ulong NumberReturned、out ulong TotalMatches、out ulong UpdateID)
//{
//结果=空;
//NumberReturned=0;
//TotalMatches=0;
//UpdateID=0;
//}
公共浏览器响应浏览(浏览器请求请求)
{
返回新的浏览器响应{NumberReturned=0,Result=null,TotalMatches=0,UpdateID=0};
}
}
静态绑定GetBinding()
{
返回新的CustomBinding(
新的TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10,Encoding.UTF8),
新的HttpTransportBindingElement());
}
公共静态无效测试()
{
string baseAddress=“http://“+Environment.MachineName+”:8000/服务”;
ServiceHost主机=新ServiceHost(类型(服务),新Uri(基地址));
AddServiceEndpoint(typeof(IContentDirectory),GetBinding(),“”);
host.Description.Behaviors.Add(新ServiceMetadataBehavior{HttpGetEnabled=true});
host.Open();
Console.WriteLine(“主机已打开”);
ChannelFactory=newchannelfactory(GetBinding(),newendpointaddress(baseAddress));
IContentDirectory代理=factory.CreateChannel();
//字符串结果;
//ulong ul1、ul2、ul3;
//浏览(null,null,null,0,0,null,out结果,out ul1,out ul2,out ul3);
Browse(新浏览器请求{BrowseFlag=null,Filter=null,Obje