it-swarm.com.de

Hinzufügen eines benutzerdefinierten HTTP-Headers für den C # Web Service-Client, der den Axis 1.4-Webdienst verwendet

Ich versuche, einen Webservice-Client in c # zu schreiben, der Webservice ist Java Axis 1.4 . Der Axis-Dienst erfordert den Authorization: Basic-Wert Base64EncodedToken in den HTTP-Headern. Ich kann keinen Weg finden, diesen Header auf herkömmliche Art und Weise zu setzen, um Web-Services in Visual Studio.net zu verwenden, wie normale WSDL-generierte Referenzen oder WSE3.0

Ich kann WCF nicht verwenden, da das Projekt mit .net 2.0 entwickelt wird.

Gibt es eine Möglichkeit, dies zu tun?

43
UmutKa

Es scheint, dass der ursprüngliche Autor seine Lösung gefunden hat. Für alle anderen Benutzer, die hierher kommen, um benutzerdefinierte Kopfzeilen hinzuzufügen, können Sie GetWebRequest überschreiben, wenn Sie Zugriff auf den generierten Protokollcode haben.

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
  System.Net.WebRequest request = base.GetWebRequest(uri);
  request.Headers.Add("myheader", "myheader_value");
  return request;
}

Stellen Sie sicher, dass Sie das Attribut DebuggerStepThroughAttribute entfernen, wenn Sie einen Schritt ausführen möchten.

45
user334291

Sprechen wir hier über WCF? Ich hatte Probleme, bei denen die Serviceaufrufe nicht die HTTP-Autorisierungsheader hinzufügten. Durch das Einschließen von Anrufen in diese Anweisung wurde mein Problem behoben.

  using (OperationContextScope scope = new OperationContextScope(RefundClient.InnerChannel))
  {
            var httpRequestProperty = new HttpRequestMessageProperty();
            httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " +
            Convert.ToBase64String(Encoding.ASCII.GetBytes(RefundClient.ClientCredentials.UserName.UserName + ":" +
            RefundClient.ClientCredentials.UserName.Password));
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

            PaymentResponse = RefundClient.Payment(PaymentRequest);
   }

Dies führte SOAP -Aufrufe an IBM ESB über .NET mit grundlegender Berechtigung über http oder https aus.

Ich hoffe, das hilft jemandem, weil ich massive Probleme hatte, online eine Lösung zu finden.

25
Simon RC

Wenn Sie einen benutzerdefinierten HTTP-Header (keinen SOAP -Header) senden möchten, müssen Sie die HttpWebRequest-Klasse verwenden. Der Code würde folgendermaßen aussehen:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);

Sie können keine HTTP-Header mit dem von Visual Studio generierten Proxy hinzufügen, was sehr schmerzhaft sein kann.

7
John Hunter

Anstatt den automatisch generierten Code zu modifizieren oder jeden Aufruf in doppeltem Code einzuhüllen, können Sie Ihre benutzerdefinierten HTTP-Header einfügen, indem Sie einen benutzerdefinierten Meldungsinspektor hinzufügen. Dies ist einfacher als es klingt:

public class CustomMessageInspector : IClientMessageInspector
{
    readonly string _authToken;

    public CustomMessageInspector(string authToken)
    {
        _authToken = authToken;
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var reqMsgProperty = new HttpRequestMessageProperty();
        reqMsgProperty.Headers.Add("Auth-Token", _authToken);
        request.Properties[HttpRequestMessageProperty.Name] = reqMsgProperty;
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    { }
}


public class CustomAuthenticationBehaviour : IEndpointBehavior
{
    readonly string _authToken;

    public CustomAuthenticationBehaviour (string authToken)
    {
        _authToken = authToken;
    }
    public void Validate(ServiceEndpoint endpoint)
    { }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    { }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector(_authToken));
    }
}

Wenn Sie Ihre Client-Klasse instanziieren, können Sie sie einfach als Verhalten hinzufügen:

this.Endpoint.EndpointBehaviors.Add(new CustomAuthenticationBehaviour("Auth Token"));

Dadurch wird bei jedem ausgehenden Dienstaufruf der benutzerdefinierte HTTP-Header festgelegt.

6
Saeb Amini

Ich finde diesen Code und ist mein Problem beheben.

http://arcware.net/setting-http-header-autorization-for-web-services/

protected override WebRequest GetWebRequest(Uri uri)
{
    // Assuming authValue is set from somewhere, such as the config file
    HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
    request.Headers.Add("Authorization", string.Format("Basic {0}", authValue));
    return request;
}
5

die Antwort von user334291 war für mich ein Lebensretter. Ich möchte nur hinzufügen, wie Sie hinzufügen können, wozu das OP ursprünglich gedacht war (was ich am Ende verwendet habe):

Überschreiben der GetWebRequest-Funktion für den generierten Webservice-Code:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
    System.Net.WebRequest request = base.GetWebRequest(uri);          
    string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(this.Credentials.GetCredential(uri, "Basic").UserName + ":" + this.Credentials.GetCredential(uri, "Basic").Password));
    request.Headers.Add("Authorization", auth);
    return request;
}

und die Anmeldeinformationen festlegen, bevor der Webservice aufgerufen wird:

  client.Credentials = new NetworkCredential(user, password);       
1
Tiago Martins

Folgendes hat für mich funktioniert: 

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
        HttpWebRequest request;
        request = (HttpWebRequest)base.GetWebRequest(uri);
        NetworkCredential networkCredentials =
        Credentials.GetCredential(uri, "Basic");
        if (networkCredentials != null)
        {
            byte[] credentialBuffer = new UTF8Encoding().GetBytes(
            networkCredentials.UserName + ":" +
            networkCredentials.Password);
            request.Headers["Authorization"] =
            "Basic " + Convert.ToBase64String(credentialBuffer);
            request.Headers["Cookie"] = "BCSI-CS-2rtyueru7546356=1";
            request.Headers["Cookie2"] = "$Version=1";
        }
        else
        {
            throw new ApplicationException("No network credentials");
        }
        return request;
}

Vergessen Sie nicht, diese Eigenschaft festzulegen: 

service.Credentials = new NetworkCredential("username", "password");  

Cookie und Cookie2 werden im Header festgelegt, da der Java-Dienst die Anforderung nicht angenommen hat und ich einen nicht autorisierten Fehler erhalten habe.

0
Attiq Rehman