Hallo,
ich bin dabei ein Frankierprogramm zu erstellen, das auf Briefen mit Hilfe des Webservice der DeutschenPost Internetmarke eine elektronische Briefmarke auf Briefen drucken soll.
Ich hab im VisualStudio den Link https://internetmarke.deutschepost.de/OneClickForApp/?WSDL als Dienstverweis hinzugefügt und diesen Code ausgeführt.
OneClickForAppPortTypeClient client = new OneClickForAppPortTypeClient();
AuthenticateUserRequestType user = new AuthenticateUserRequestType();
user.username = "";
user.password = "";
client.Open();
client.authenticateUser(user);
Wenn ich mich mit dem OneClickForAppPortTypeClient und authenticateUser anmelden möchte, bekomme ich die Fehlermeldung > Fehlermeldung:
Failed to invoke end componentFailed to invoke methodInvalid signature hash!
Leider ist pdf Doku die ich bei der Post angefordert habe, nicht wirklich Aussagekräftig. Hat schon mal jemand die Internetmarke in c# zum Laufen gebracht? Was bedeutet der Fehler - was mache ich falsch?
Wie kann ich diesen soap Header an jeden soap Request anhängen?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:onec="http://oneclickforpartner.dpag.de">
<soapenv:Header>
<onec:PARTNER_ID>MEINMARKTPLATZ</onec:PARTNER_ID>
<onec:REQUEST_TIMESTAMP>24082009-142621</onec:REQUEST_TIMESTAMP>
<onec:KEY_PHASE>1</onec:KEY_PHASE>
<onec:PARTNER_SIGNATURE>a0b1c2d4</onec:PARTNER_SIGNATURE>
</soapenv:Header>
<soapenv:Body>
--- Nutzinformation entfernt ---
</soapenv:Body>
</soapenv:Envelope>
Hallo,
ich glaube EndpointBehaviour und MessageInspector ist das "Zauberwort".
Die Lösung könnte dann so ähnlich ausschauen:
(Ungetestet! Bitte nicht "blind" übernehmen!)
public class CustomMessageInspector : IDispatchMessageInspector, IClientMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
MessageHeader partner = MessageHeader.CreateHeader("PARTNER", string.Empty, "MEINMARKTPLATZ");
MessageHeader requestTimestamp = MessageHeader.CreateHeader("REQUEST_TIMESTAMP", string.Empty, "24082009-142621");
MessageHeader keyPhase = MessageHeader.CreateHeader("KEY_PHASE", string.Empty, "1");
MessageHeader partnerSignature = MessageHeader.CreateHeader("PARTNER_SIGNATURE", string.Empty, "a0b1c2d4");
request.Headers.Add(partner);
request.Headers.Add(requestTimestamp);
request.Headers.Add(keyPhase);
request.Headers.Add(partnerSignature);
return null;
}
}
public class CustomBehavior : Attribute, IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
CustomMessageInspector inspector = new CustomMessageInspector();
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
Dem Client muss dann natürlich noch das Behaviour hinzugefügt werden:
client.Endpoint.Behaviors.Add(new CustomBehavior());
(Das würde natürlich auch konfigurativ, d.h. in der "app.config" gehen)
Viele Grüße
Marcel
@marcelz
Vielen Dank für Deine schnelle Hilfe, das klappt!
Damit kann ist auch meine erste Frage beantwortet.
Hallo,
@dasb
ich sitze z.Z. auch an dem Webservice der Internetmarke
und drehe mich schon Stunden um die Fehlermeldung> Fehlermeldung:
Soap request is not valid. Unknown channel: null !
hast du mal ein Beispiel von deinem Aufruf
Gruss
Martin
VS2012 FW 4.5
Hallo,
funktioniert!
hatte den Header von @marcelz so übernommen
und 1000 mal übersehen das das PARTNER_ID sein muss!
Gruss
Martin
Hallo,
ich weiß das es schon ein ältere Beitrag ist, aber vielleicht hat ja jemand ein beispiel Code?
Da ich grade auch versuche die API einzurichten.
Ich weiß einfach nicht wie ich den Header einbinde
Für Hilfe wäre ich sehr dankbar
Mein Code:
public static MarkenHeader markenHeader;
[System.Web.Services.Protocols.SoapHeader("markeHeader", Direction = System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
static void PostInternetmarke()
{
markenHeader = new MarkenHeader();
markenHeader.PARTNER_ID = "XXXX";
markenHeader.REQUEST_TIMESTAMP = DateTime.Now.ToString("ddMMyyyy-Hmmss");
markenHeader.KEY_PHASE = 1;
markenHeader.PARTNER_SIGNATURE = "XXXXXX";
de.deutschepost.internetmarke.OneClickForAppService marke = new de.deutschepost.internetmarke.OneClickForAppService();
de.deutschepost.internetmarke.AuthenticateUserRequestType user = new de.deutschepost.internetmarke.AuthenticateUserRequestType()
{
username = "XXXX",
password = "XXXX"
};
var res1 = marke.authenticateUser(user);
var test = 123;
}
Gruß
Thomas
Jetzt habe ich es doch hinbekommen. Für das beispiel muss es eine Service References sein und nicht Web References
Hier mal meine ganze Klasse ohne Fehlerbehandlung
namespace ConsoleApplication2.Klassen
{
public class BriefmarkeClass
{
[System.Web.Services.WebMethod]
[System.Web.Services.Protocols.SoapHeader("markeHeader", Direction = System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
public void PostInternetmarke()
{
OneClickForAppPortTypeClient.OneClickForAppPortTypeClient client = new OneClickForAppPortTypeClient.OneClickForAppPortTypeClient();
client.Endpoint.EndpointBehaviors.Add(new CustomBehavior());
OneClickForAppPortTypeClient.AuthenticateUserRequestType user = new OneClickForAppPortTypeClient.AuthenticateUserRequestType()
{
username = "XXXX",
password = "XXXXX"
};
client.Open();
//hier braucht man den Token 1 Tag gültig
var userSettings = client.authenticateUser(user);
var cart = new OneClickForAppPortTypeClient.ShoppingCartRequestType();
cart.userToken = userSettings.userToken.ToString();
cart.ppl = 32; //Aktuelle Version der CSV Produktpreisliste
var position = new OneClickForAppPortTypeClient.ShoppingCartPosition();
position.productCode = 1; //ProduktID Spalte 3 in CSV List
position.imageID = 0;
position.voucherLayout = OneClickForAppPortTypeClient.VoucherLayout.FrankingZone;
cart.positions = new OneClickForAppPortTypeClient.ShoppingCartPosition[] {position};
cart.total = 62; //Preis aus CSV
var marke = client.checkoutShoppingCart(cart);
using (WebClient w = new WebClient())
{
var daten = w.DownloadData(marke.link);
var saveFile = AppDomain.CurrentDomain.BaseDirectory + "briefmarke.zip";
System.IO.File.WriteAllBytes(saveFile, daten);
}
var test = 123;
}
}
public class CustomMessageInspector : IDispatchMessageInspector, IClientMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
string PARTNER_ID = "XXX";
string REQUEST_TIMESTAMP = DateTime.Now.ToString("ddMMyyyy-Hmmss");
string KEY_PHASE = "1";
string SCHLUESSEL_DPWN_MEINMARKTPLATZ = "XXXX";
string PARTNER_SIGNATURE = "";
for (; ; )
{
string berechnung = PARTNER_ID + "::" + REQUEST_TIMESTAMP + "::" + KEY_PHASE + "::" + SCHLUESSEL_DPWN_MEINMARKTPLATZ;
MD5 md5 = new MD5CryptoServiceProvider();
byte[] textToHash = Encoding.Default.GetBytes(berechnung);
byte[] result = md5.ComputeHash(textToHash);
string sresult = System.BitConverter.ToString(result).ToLower();
if (sresult.Length == 47)
{
PARTNER_SIGNATURE = sresult.Replace("-", string.Empty).Remove(8);
break;
}
}
MessageHeader partner = MessageHeader.CreateHeader("PARTNER_ID", string.Empty, PARTNER_ID);
MessageHeader requestTimestamp = MessageHeader.CreateHeader("REQUEST_TIMESTAMP", string.Empty, REQUEST_TIMESTAMP);
MessageHeader keyPhase = MessageHeader.CreateHeader("KEY_PHASE", string.Empty, KEY_PHASE);
MessageHeader partnerSignature = MessageHeader.CreateHeader("PARTNER_SIGNATURE", string.Empty, PARTNER_SIGNATURE);
request.Headers.Add(partner);
request.Headers.Add(requestTimestamp);
request.Headers.Add(keyPhase);
request.Headers.Add(partnerSignature);
return null;
}
}
public class CustomBehavior : Attribute, IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
CustomMessageInspector inspector = new CustomMessageInspector();
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
}
Wie muss ich das machen?
Für das beispiel muss es eine Service References sein und nicht Web References
Habe die ganze Zeit folgenden Fehler:
Fehlermeldung:
Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler CS0234 Der Typ- oder Namespacename "Services" ist im Namespace "System.Web" nicht vorhanden. (Möglicherweise fehlt ein Assemblyverweis)
Viele Grüße
Ralph
Wieso packst du Zitate in Code-Tags? Und wieso den Error in Code-Tags? Bitte benutze die richtigen Code-Tags [Hinweis] Wie poste ich richtig?
Hallo RalphGrad,
[FAQ] CS0234 / CS0246 - Der Typ- oder Namespacename "Foo" konnte nicht gefunden werden
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hier hat sich noch ein Fehler eingeschlichen. Das Datumsformat ist falsch, so kommt es morgens vor 10 Uhr (Da die Uhrzeit dann einstellig ist) zu einer Fehlermeldung: Hash-Falsch
Es muss heißen "ddMMyyyy-HHmmss":
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
[...]
string REQUEST_TIMESTAMP = DateTime.Now.ToString("ddMMyyyy-HHmmss");
[...]
}
}
Jetzt habe ich es doch hinbekommen. Für das beispiel muss es eine Service References sein und nicht Web References
Hier mal meine ganze Klasse ohne Fehlerbehandlung
namespace ConsoleApplication2.Klassen { public class BriefmarkeClass { [System.Web.Services.WebMethod] [System.Web.Services.Protocols.SoapHeader("markeHeader", Direction = System.Web.Services.Protocols.SoapHeaderDirection.InOut)] public void PostInternetmarke() { OneClickForAppPortTypeClient.OneClickForAppPortTypeClient client = new OneClickForAppPortTypeClient.OneClickForAppPortTypeClient(); client.Endpoint.EndpointBehaviors.Add(new CustomBehavior()); OneClickForAppPortTypeClient.AuthenticateUserRequestType user = new OneClickForAppPortTypeClient.AuthenticateUserRequestType() { username = "XXXX", password = "XXXXX" }; client.Open(); //hier braucht man den Token 1 Tag gültig var userSettings = client.authenticateUser(user); var cart = new OneClickForAppPortTypeClient.ShoppingCartRequestType(); cart.userToken = userSettings.userToken.ToString(); cart.ppl = 32; //Aktuelle Version der CSV Produktpreisliste var position = new OneClickForAppPortTypeClient.ShoppingCartPosition(); position.productCode = 1; //ProduktID Spalte 3 in CSV List position.imageID = 0; position.voucherLayout = OneClickForAppPortTypeClient.VoucherLayout.FrankingZone; cart.positions = new OneClickForAppPortTypeClient.ShoppingCartPosition[] {position}; cart.total = 62; //Preis aus CSV var marke = client.checkoutShoppingCart(cart); using (WebClient w = new WebClient()) { var daten = w.DownloadData(marke.link); var saveFile = AppDomain.CurrentDomain.BaseDirectory + "briefmarke.zip"; System.IO.File.WriteAllBytes(saveFile, daten); } var test = 123; } } public class CustomMessageInspector : IDispatchMessageInspector, IClientMessageInspector { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { return null; } public void BeforeSendReply(ref Message reply, object correlationState) { } public void AfterReceiveReply(ref Message reply, object correlationState) { } public object BeforeSendRequest(ref Message request, IClientChannel channel) { MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); request = buffer.CreateMessage(); string PARTNER_ID = "XXX"; string REQUEST_TIMESTAMP = DateTime.Now.ToString("ddMMyyyy-Hmmss"); string KEY_PHASE = "1"; string SCHLUESSEL_DPWN_MEINMARKTPLATZ = "XXXX"; string PARTNER_SIGNATURE = ""; for (; ; ) { string berechnung = PARTNER_ID + "::" + REQUEST_TIMESTAMP + "::" + KEY_PHASE + "::" + SCHLUESSEL_DPWN_MEINMARKTPLATZ; MD5 md5 = new MD5CryptoServiceProvider(); byte[] textToHash = Encoding.Default.GetBytes(berechnung); byte[] result = md5.ComputeHash(textToHash); string sresult = System.BitConverter.ToString(result).ToLower(); if (sresult.Length == 47) { PARTNER_SIGNATURE = sresult.Replace("-", string.Empty).Remove(8); break; } } MessageHeader partner = MessageHeader.CreateHeader("PARTNER_ID", string.Empty, PARTNER_ID); MessageHeader requestTimestamp = MessageHeader.CreateHeader("REQUEST_TIMESTAMP", string.Empty, REQUEST_TIMESTAMP); MessageHeader keyPhase = MessageHeader.CreateHeader("KEY_PHASE", string.Empty, KEY_PHASE); MessageHeader partnerSignature = MessageHeader.CreateHeader("PARTNER_SIGNATURE", string.Empty, PARTNER_SIGNATURE); request.Headers.Add(partner); request.Headers.Add(requestTimestamp); request.Headers.Add(keyPhase); request.Headers.Add(partnerSignature); return null; } } public class CustomBehavior : Attribute, IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { CustomMessageInspector inspector = new CustomMessageInspector(); clientRuntime.MessageInspectors.Add(inspector); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } } }
Hi,
ich bin jetzt schon länger an diesem Problem und die Post hilft einem da auch nicht wirklich. Schreiben nur, dass es bei denen klappt. Supi.
Wir haben momentan einen Testaccount erhalten, wo wir uns auch einloggen können, also die Daten sollten stimmen.
Ich habe die Routine von hier übernommen und sende folgenden Header
{<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"> </Action>
<PARTNER_ID>XXXLO</PARTNER_ID>
<REQUEST_TIMESTAMP>31052017-102012</REQUEST_TIMESTAMP>
<KEY_PHASE>1</KEY_PHASE>
<PARTNER_SIGNATURE>XXX46110</PARTNER_SIGNATURE>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AuthenticateUserRequest xmlns="http://oneclickforapp.dpag.de">
<username>XXX@YYY.webpage.t-com.de</username>
<password>XXX</password>
</AuthenticateUserRequest>
</s:Body>
</s:Envelope>}
(XXX ist natürlich hier von mir geändert...)
Es läuft sauber durch aber ich bekomme diese Antwort vom Server:> Fehlermeldung:
$exception {"Partner has no access permission for this service."} System.ServiceModel.FaultException
Und die Post schreibt mir, dass es bei denen klappt. Habe denen meinen Header gesendet aber bekomme dazu keine Antwort.
Habt ihr noch einen Tipp für mich?
TFX
Besser gut drunter als schlecht drauf 8)