Eine Hürde für .NET Entwickler ist, dass das Webservice für die Authentifizierung einen SOAP-Header im folgenden Format verlangt (spitz durch eckig ersetzt):
[env:Header]
..[wsse:Security]
....[wsse:UsernameToken]
......[wsse:Username]Testkonto[/wsse:Username]
......[wsse:Password]a1b2c3d4[/wsse:Password]
....[/wsse:UsernameToken]
...[/wsse:Security]
[/env:Header]
(wie unter Die eRechnung als XML</param>
/// <param name="test">Wenn angegeben, wird die Nachricht beim Empfänger verworfen (eine Prüfung findet statt)</param>
/// <param name="serviceUrl">Url des Webservice. Also: https://txm.portal.at/at.gv.bmf.erb/V2</param>
/// <param name="serviceUser">Benutzername für das Webservice</param>
/// <param name="servicePassword">Passwort für das Webservice</param>
public static void Send(string xml, bool test, string serviceUrl, string serviceUser, string servicePassword)
{
//Xml zu Base64 konvertieren
byte[] content = null;
try
{
content = System.Text.Encoding.UTF8.GetBytes(xml);
}
catch (Exception ex)
{
//...
}
try
{
//Nachricht (delivery) formulieren
ErbV2.DeliveryType delivery = new ErbV2.DeliveryType();
delivery.Invoice = new ErbV2.DeliveryInvoiceType();
delivery.Settings = new ErbV2.DeliverySettingsType();
//Testflag setzen
delivery.Settings.test = test;
//Inhalt zuweisen
delivery.Invoice.Value = content;
using (ErbV2.WSInvoiceDeliveryPortClient client = new ErbV2.WSInvoiceDeliveryPortClient())
{
client.Endpoint.Address = new
System.ServiceModel.EndpointAddress(serviceUrl);
//Mittels scope kann die SOAP-Nachricht manipuliert werden
using(System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(client.InnerChannel))
{
//SOAP-Header für Security-UsernameToken zugefügen
System.ServiceModel.OperationContext.Current.OutgoingMessageHeaders.Add(new SecurityHeader(serviceUser, servicePassword));
//Webservice-Aufruf
ErbV2.DeliveryResponseType response = client.deliverInvoice(delivery);
//response auswerten
// Bei Erfolg wird in Item ein ErbV2.DeliverySuccessType
// und bei Misserfolg ein ErbV2.DeliveryErrorType zurückgegeben
// ...
}
}
}
catch (Exception ex)
{
//Fehler bei Aufruf von Webservice (Authentifizierung, etc...)
}
}
#region " SOAP-Header Class für Security "
/// <summary>
/// Stellt den Soap-Header für Security bereit
/// </summary>
public class SecurityHeader : System.ServiceModel.Channels.MessageHeader
{
private readonly UsernameToken m_UsernameToken;
public SecurityHeader(string username, string password)
{
m_UsernameToken = new UsernameToken(username, password);
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
}
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
serializer.Serialize(writer, m_UsernameToken);
}
}
/// <summary>
/// Stellt den Soap-Header für UsernameToken bereit
/// </summary>
[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
private string m_Username;
private string m_Password;
public UsernameToken() { }
public UsernameToken(string username, string password)
{
m_Username = username;
m_Password = password;
}
[XmlElement()]
public string Username
{
get { return m_Username; }
set { m_Username = value; }
}
[XmlElement()]
public string Password
{
get { return m_Password; }
set { m_Password = value; }
}
}
#endregion
}
}
[env:Header]
..[wsse:Security]
....[wsse:UsernameToken]
......[wsse:Username]Testkonto[/wsse:Username]
......[wsse:Password]a1b2c3d4[/wsse:Password]
....[/wsse:UsernameToken]
...[/wsse:Security]
[/env:Header]
(wie unter Die eRechnung als XML</param>
/// <param name="test">Wenn angegeben, wird die Nachricht beim Empfänger verworfen (eine Prüfung findet statt)</param>
/// <param name="serviceUrl">Url des Webservice. Also: https://txm.portal.at/at.gv.bmf.erb/V2</param>
/// <param name="serviceUser">Benutzername für das Webservice</param>
/// <param name="servicePassword">Passwort für das Webservice</param>
public static void Send(string xml, bool test, string serviceUrl, string serviceUser, string servicePassword)
{
//Xml zu Base64 konvertieren
byte[] content = null;
try
{
content = System.Text.Encoding.UTF8.GetBytes(xml);
}
catch (Exception ex)
{
//...
}
try
{
//Nachricht (delivery) formulieren
ErbV2.DeliveryType delivery = new ErbV2.DeliveryType();
delivery.Invoice = new ErbV2.DeliveryInvoiceType();
delivery.Settings = new ErbV2.DeliverySettingsType();
//Testflag setzen
delivery.Settings.test = test;
//Inhalt zuweisen
delivery.Invoice.Value = content;
using (ErbV2.WSInvoiceDeliveryPortClient client = new ErbV2.WSInvoiceDeliveryPortClient())
{
client.Endpoint.Address = new
System.ServiceModel.EndpointAddress(serviceUrl);
//Mittels scope kann die SOAP-Nachricht manipuliert werden
using(System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(client.InnerChannel))
{
//SOAP-Header für Security-UsernameToken zugefügen
System.ServiceModel.OperationContext.Current.OutgoingMessageHeaders.Add(new SecurityHeader(serviceUser, servicePassword));
//Webservice-Aufruf
ErbV2.DeliveryResponseType response = client.deliverInvoice(delivery);
//response auswerten
// Bei Erfolg wird in Item ein ErbV2.DeliverySuccessType
// und bei Misserfolg ein ErbV2.DeliveryErrorType zurückgegeben
// ...
}
}
}
catch (Exception ex)
{
//Fehler bei Aufruf von Webservice (Authentifizierung, etc...)
}
}
#region " SOAP-Header Class für Security "
/// <summary>
/// Stellt den Soap-Header für Security bereit
/// </summary>
public class SecurityHeader : System.ServiceModel.Channels.MessageHeader
{
private readonly UsernameToken m_UsernameToken;
public SecurityHeader(string username, string password)
{
m_UsernameToken = new UsernameToken(username, password);
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
}
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
serializer.Serialize(writer, m_UsernameToken);
}
}
/// <summary>
/// Stellt den Soap-Header für UsernameToken bereit
/// </summary>
[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
private string m_Username;
private string m_Password;
public UsernameToken() { }
public UsernameToken(string username, string password)
{
m_Username = username;
m_Password = password;
}
[XmlElement()]
public string Username
{
get { return m_Username; }
set { m_Username = value; }
}
[XmlElement()]
public string Password
{
get { return m_Password; }
set { m_Password = value; }
}
}
#endregion
}
}