WCF 以编程方式设置标头

WCF Set Headers Programmatically

提问人:bit 提问时间:11/1/2023 更新时间:11/2/2023 访问量:42

问:

每当我调用 wcf 服务时,我都需要以编程方式设置标头, 在我的示例中,我必须设置身份节点的所有节点(Identity、AppName、AppKey、UserId、IdentityProvider)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://.../services">
   <soapenv:Header>
<Identity xmlns="http://.../">
<AppName>test1</AppName>
<AppKey>test2</AppKey>
<UserId>test3</UserId>
<IdentityProvider>test4</IdentityProvider>
</Identity>
</soapenv:Header>
   <soapenv:Body>

我读过这篇文章如何将自定义 HTTP 标头添加到每个 WCF 调用? 但它似乎不完整,我正在寻找完整的示例。

WCF .net-核心

评论


答:

0赞 QI You 11/2/2023 #1

使用下面的代码

 public class UserInf
 {
     public string AppName { get; set; }
     public string AppKey { get; set; }
     public string UserId { get; set; }
     public string IdentityProvider { get; set; }

 }


UserInf credentials = new UserInf();

 credentials.AppName = "Test1";
 credentials.AppKey = "Test2";
 credentials.UserId = "Test3";
 credentials.IdentityProvider = "Test4";
 MessageHeader myHeader0 = MessageHeader.CreateHeader(
        "Identity", "http:asd.com", credentials);

 OperationContext.Current.OutgoingMessageHeaders.Add(myHeader0);

如果是响应对象,则将其添加到 WCF 的接口代码中:

public class Service1 : IService1
{
    public string GetData(int value)

{
    UserInf credentials = new UserInf();

 credentials.AppName = "Test1";
 credentials.AppKey = "Test2";
 credentials.UserId = "Test3";
 credentials.IdentityProvider = "Test4";
 MessageHeader myHeader0 = MessageHeader.CreateHeader(
        "Identity", "http:asd.com", credentials);

 OperationContext.Current.OutgoingMessageHeaders.Add(myHeader0);

    return string.Format("You entered: {0}", value);
}

enter image description here

如果是请求对象,请将以下代码添加到客户端调用中:

WS.ServiceClient myclient = new WS.ServiceClient();

 
using (OperationContextScope scope=new OperationContextScope(myclient.InnerChannel))
        {
         UserInf credentials = new UserInf();

 credentials.AppName = "Test1";
 credentials.AppKey = "Test2";
 credentials.UserId = "Test3";
 credentials.IdentityProvider = "Test4";
 MessageHeader myHeader0 = MessageHeader.CreateHeader(
        "Identity", "http:asd.com", credentials);

 OperationContext.Current.OutgoingMessageHeaders.Add(myHeader0);
    myclient.GetData(1); 
    }

至于如何删除里面的命名空间,我看了一下它的只读属性。

enter image description here

您可以修改代码以尝试删除命名空间。

评论

0赞 bit 11/2/2023
它无法工作,因为 Identity 节点是 AppName、AppKey 等的根元素......
0赞 bit 11/2/2023
感谢您的重播,但是通过我的实现,您不需要对需要相同标头的其他服务终结点的每次调用都使用 OperationContext.Current.OutgoingMessageHeaders。
0赞 bit 11/2/2023 #2

我已经通过实现 IClientMessageInspector 接口解决了这个问题,这要归功于帖子如何将自定义 HTTP 标头添加到每个 WCF 调用? 通过应用其他一些内容,例如:

// IClientMessageInspector  Impl..
 public object BeforeSendRequest(ref Message request, IClientChannel channel)
 { 
     request.Headers.Add(new ProcessHeader());

     return null;
 }



public class ProcessGuidHeader : MessageHeader
 {

     private string _name = "Identity";
     private string _elementName = "AppName";
     private string _namespace = "http://...site..com/";


     public override string Name
     {
         get { return _name; }
     }

     public override string Namespace
     {
         get { return _namespace; }
     }

     protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
     {

         XmlReader r1 = XmlReader.Create(new StringReader("<AppName>test</AppName>"));
         r1.MoveToContent();
         writer.WriteNode(r1, false);

         XmlReader r2 = XmlReader.Create(new StringReader("<AppKey>test</AppKey>"));
         r2.MoveToContent();
         writer.WriteNode(r2, false);

         XmlReader r3 = XmlReader.Create(new StringReader("<UserId>test</UserId>"));
         r3.MoveToContent();
         writer.WriteNode(r3, false);

         XmlReader r4 = XmlReader.Create(new StringReader("<IdentityProvider>test</IdentityProvider>"));
         r4.MoveToContent();
         writer.WriteNode(r4, false);
     }