Eksempelkode

I dette kapitlet vil det bli gitt eksempler på oppkobling mot Reseptformidleren via WebService
Koden er fra intern test-tool hos Direktoretet for e-helse og tilbys med alle mulige forbehold om eventuelle feil.
De to kallene baserer seg på ferdige XML filer med data i hodemeldingen for det aktuelle apotek. Disse modifiseres med data fra en GUI for å kunne gjøre kallene.
En endelig løsning bør basere seg på et dynamisk oppbygget XML-dokument med dertil egnet verktøy.
Kode for parsing av resultatmeldingene for ekstraksjon av data-elementene er fjernet fra eksempelkoden.
Feilhåndtering er bare delvis implementert her.

Den viktige forskjellen mellom vanlige apotekmeldinger på «UtlevererWebService» og Nettapotek er parameteren «DefaultAlgorithmSuite». Det er strengere krav til kryptering og signering i nettapotek.
asbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256;

Se mer om dette her:
http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/ws-securitypolicy-1.2-spec-os.html

public List<String> getNARespetliste(String idkunde, String idpasient, String[] refnummer) { List<String> reseptliste = new List<string>(); antallResepterM9NA2 = -1; var asbe = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement( System.ServiceModel.MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, true); asbe.SecurityHeaderLayout = SecurityHeaderLayout.Lax; asbe.SetKeyDerivation(false); // we don't use the default (SignBeforeEncryptAndEncryptSignature) since the signature is not encrypted asbe.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; asbe.LocalClientSettings.DetectReplays = false; asbe.LocalServiceSettings.DetectReplays = false; // asbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15; // http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/ws-securitypolicy-1.2-spec-os.html asbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256; // NY FOR NETTAPOTEK Sha256 AES256 asbe.IncludeTimestamp = false; // use soap1.1 with utf-8 encoding var tme = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8); var quotas = tme.ReaderQuotas; quotas.MaxArrayLength = Int32.MaxValue; quotas.MaxBytesPerRead = Int32.MaxValue; quotas.MaxDepth = Int32.MaxValue; quotas.MaxNameTableCharCount = Int32.MaxValue; quotas.MaxStringContentLength = Int32.MaxValue; // use http transport with no security var http = new HttpTransportBindingElement { MaxReceivedMessageSize = int.MaxValue, KeepAliveEnabled = false }; CustomBinding cbind = new CustomBinding(asbe, tme, http); EndpointAddress address; address = (testFromInternet) ? new EndpointAddress(new Uri("http://139.112.129.5/NA/NAWebServiceSoapHttpPort"), EndpointIdentity.CreateDnsIdentity("Helsedirektoratet")) : // internet new EndpointAddress(new Uri("http://139.116.132.22/NA/NAWebServiceSoapHttpPort"), EndpointIdentity.CreateDnsIdentity("Helsedirektoratet")); //NHN NettapotekForm.NettapotekWebService.NAWebClient naW = new NAWebClient(cbind, address); naW.ClientCredentials.ClientCertificate.Certificate = clientCert; naW.ClientCredentials.ServiceCertificate.DefaultCertificate = serviceCert; // NB: Oppbyggingen av xml-dokumentet er her svært enkel, og kun for testing. Det forutsettes at nettapoteksystemene bygger XML med egnet kode XmlDocument xd = new XmlDocument(); xd.Load("m9na1-2016-06-06.xml"); XmlNamespaceManager nsmgr1 = new XmlNamespaceManager(xd.NameTable); nsmgr1.AddNamespace("na1", "http://www.kith.no/xmlstds/eresept/m9na1/2016-06-06"); nsmgr1.AddNamespace("mh", "http://www.kith.no/xmlstds/msghead/2006-05-24"); XmlNode M9NA1 = xd.SelectSingleNode("//na1:M9NA1", nsmgr1); XmlNode msgid = xd.SelectSingleNode("//mh:MsgId", nsmgr1); XmlNode msginfo = xd.SelectSingleNode("//mh:MsgInfo", nsmgr1); XmlNode genDate = xd.SelectSingleNode("//mh:GenDate", nsmgr1); if (msgid != null) { String msgIdString = System.Guid.NewGuid().ToString(); msgid.InnerText = msgIdString; genDate.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzzzzz"); if (msgIdFirstM9na1.Length > 0) // Do we have a conversation? { XmlNode ConvRef = xd.CreateNode(XmlNodeType.Element, "ConversationRef", nsmgr1.LookupNamespace("mh")); XmlNode RefToParent = xd.CreateNode(XmlNodeType.Element, "RefToParent", nsmgr1.LookupNamespace("mh")); RefToParent.InnerText = msgIdFirstM9na1; ConvRef.AppendChild(RefToParent); XmlNode RefToConv = xd.CreateNode(XmlNodeType.Element, "RefToConversation", nsmgr1.LookupNamespace("mh")); RefToConv.InnerText = msgIdFirstM9na1; ConvRef.AppendChild(RefToConv); msginfo.InsertAfter(ConvRef, msgid); } else { msgIdFirstM9na1 = msgIdString; } msgIdLastM9na1 = msgIdString; } XmlNodeList kunde = xd.GetElementsByTagName("IdKunde"); if (kunde.Count > 0) { XmlNode kundeid = kunde[0].FirstChild; if (kundeid != null) { kundeid.InnerText = idkunde; } } // Add referansenummer om det er oppgitt if (M9NA1 != null && refnummer != null) { foreach (String refn in refnummer) { if (refn.Length != 0) { XmlNode refnummerNode = xd.CreateNode(XmlNodeType.Element, "RefNr", "http://www.kith.no/xmlstds/eresept/m9na1/2016-06-06"); refnummerNode.InnerText = refn.Trim(); M9NA1.AppendChild(refnummerNode); } } } XmlNodeList patient = xd.GetElementsByTagName("Patient"); if (patient.Count > 0) { XmlNode patientId = patient[0].FirstChild.FirstChild; if (patientId != null) { patientId.InnerText = idpasient; } } lastLogFileName = "log\\M9NA1_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, xd.OuterXml); M9na1 m9na1 = new M9na1(); m9na1.dokument = Encoding.UTF8.GetBytes(xd.DocumentElement.OuterXml); String retstring = ""; try { M9na2 m9na2 = naW.NAWebService_m9na1(m9na1); // Her er kallet mot webservice byte[] retval = (byte[])m9na2.dokument; retstring = System.Text.Encoding.UTF8.GetString(retval); XmlDocument m9na2Doc = new XmlDocument(); m9na2Doc.LoadXml(retstring); lastLogFileName = "log\\M9NA2_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, retstring); XmlNamespaceManager nsmgr = new XmlNamespaceManager(m9na2Doc.NameTable); nsmgr.AddNamespace("na2", "http://www.kith.no/xmlstds/eresept/m9na2/2016-06-06"); nsmgr.AddNamespace("mh", "http://www.kith.no/xmlstds/msghead/2006-05-24"); XmlNode nodeMsgId = m9na2Doc.SelectSingleNode("//mh:MsgId", nsmgr); if (nodeMsgId != null) msgIdLastM9na2 = nodeMsgId.InnerText; XmlNode nodeAntall = m9na2Doc.SelectSingleNode("//na2:Antall", nsmgr); if (nodeAntall != null) int.TryParse(nodeAntall.InnerText, out antallResepterM9NA2); XmlNodeList resepter = m9na2Doc.SelectNodes("//na2:Reseptinfo", nsmgr); for ( int node = 0; node< resepter.Count; node++ ) { // Kode for parsing av enkeltelementer er utelatt } int i = retval.Length; } catch (FaultException<NettapotekForm.NettapotekWebService.AppRecFault> appRec) { NettapotekForm.NettapotekWebService.AppRecFault af = appRec.Detail; byte[] retval = (byte[])af.dokument; retstring = System.Text.Encoding.UTF8.GetString(retval); errorMessage = "AppRec: "; lastLogFileName = "log\\Apprec_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, retstring); XmlDocument appRecDoc = new XmlDocument(); appRecDoc.LoadXml(retstring); XmlNamespaceManager nsmgr = new XmlNamespaceManager(appRecDoc.NameTable); nsmgr.AddNamespace("apprec", "http://www.kith.no/xmlstds/apprec/2004-11-21"); // Finn Id, Status og Error XmlNode status = appRecDoc.SelectSingleNode("//apprec:Status", nsmgr); if (status != null) { errorMessage += Environment.NewLine + "Status: " + status.Attributes["DN"].Value; errorMessage += " (" + status.Attributes["V"].Value + ")"; } XmlNode error = appRecDoc.SelectSingleNode("//apprec:Error", nsmgr); if (error != null) { errorMessage += Environment.NewLine + "Error: " + error.Attributes["DN"].Value; errorMessage += " (" + error.Attributes["V"].Value + ")"; } return null; } catch (Exception excp) { errorMessage = excp.Message + Environment.NewLine ; if (excp.InnerException != null) errorMessage += Environment.NewLine + excp.InnerException.Message; return null; } return reseptliste; }



public String getNARespetDetajer(String idKunde, String idPasient, String reseptID) { String detaljer = String.Empty; var asbe = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement( System.ServiceModel.MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, true); asbe.SecurityHeaderLayout = SecurityHeaderLayout.Lax; asbe.SetKeyDerivation(false); // we don't use the default (SignBeforeEncryptAndEncryptSignature) since the signature is not encrypted asbe.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; asbe.LocalClientSettings.DetectReplays = false; asbe.LocalServiceSettings.DetectReplays = false; // http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/ws-securitypolicy-1.2-spec-os.html asbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256; // NY FOR NETTAPOTEK Sha256 AES256 asbe.IncludeTimestamp = false; // use soap1.1 with utf-8 encoding var tme = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8); var quotas = tme.ReaderQuotas; quotas.MaxArrayLength = Int32.MaxValue; quotas.MaxBytesPerRead = Int32.MaxValue; quotas.MaxDepth = Int32.MaxValue; quotas.MaxNameTableCharCount = Int32.MaxValue; quotas.MaxStringContentLength = Int32.MaxValue; // use http transport with no security var http = new HttpTransportBindingElement { MaxReceivedMessageSize = int.MaxValue, KeepAliveEnabled = false }; CustomBinding cbind = new CustomBinding(asbe, tme, http); EndpointAddress address; address = (testFromInternet) ? new EndpointAddress(new Uri("http://139.112.129.5/NA/NAWebServiceSoapHttpPort"), EndpointIdentity.CreateDnsIdentity("Helsedirektoratet")) : // internet new EndpointAddress(new Uri("http://139.116.132.22/NA/NAWebServiceSoapHttpPort"), EndpointIdentity.CreateDnsIdentity("Helsedirektoratet")); //NHN NettapotekForm.NettapotekWebService.NAWebClient naW = new NAWebClient(cbind, address); naW.ClientCredentials.ClientCertificate.Certificate = clientCert; naW.ClientCredentials.ServiceCertificate.DefaultCertificate = serviceCert; // NB: Oppbyggingen av xml-dokumentet er her svært enkel, og kun for testing. Det forutsettes at nettapoteksystemene bygger XML med egnet kode XmlDocument xd = new XmlDocument(); xd.Load("m9na3-2016-06-06.xml"); XmlNamespaceManager nsmgr3 = new XmlNamespaceManager(xd.NameTable); nsmgr3.AddNamespace("na3", "http://www.kith.no/xmlstds/eresept/m9na3/2016-06-06"); nsmgr3.AddNamespace("mh", "http://www.kith.no/xmlstds/msghead/2006-05-24"); XmlNode M9NA1 = xd.SelectSingleNode("//na3:M9NA3", nsmgr3); XmlNode msgid = xd.SelectSingleNode("//mh:MsgId", nsmgr3); XmlNode msginfo = xd.SelectSingleNode("//mh:MsgInfo", nsmgr3); XmlNode genDate = xd.SelectSingleNode("//mh:GenDate", nsmgr3); msgIdLastM9na3 = System.Guid.NewGuid().ToString(); if (msgid != null) msgid.InnerText = msgIdLastM9na3; if (genDate != null) genDate.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzzzzz"); if (msgIdFirstM9na1.Length > 0) // Do we have a conversation? { XmlNode ConvRef = xd.CreateNode(XmlNodeType.Element, "ConversationRef", nsmgr3.LookupNamespace("mh")); XmlNode RefToParent = xd.CreateNode(XmlNodeType.Element, "RefToParent", nsmgr3.LookupNamespace("mh")); RefToParent.InnerText = msgIdLastM9na2; ConvRef.AppendChild(RefToParent); XmlNode RefToConv = xd.CreateNode(XmlNodeType.Element, "RefToConversation", nsmgr3.LookupNamespace("mh")); RefToConv.InnerText = msgIdFirstM9na1; ConvRef.AppendChild(RefToConv); msginfo.InsertAfter(ConvRef, msgid); } XmlNode kunde = xd.SelectSingleNode("//na3:IdKunde", nsmgr3); if (kunde!=null) { XmlNode kundeid = kunde.FirstChild; if (kundeid != null) { kundeid.InnerText = idKunde; } } XmlNodeList patient = xd.GetElementsByTagName("Patient"); if (patient.Count > 0) { XmlNode patientId = patient[0].FirstChild.FirstChild; if (patientId != null) { patientId.InnerText = idPasient; } } XmlNodeList rID = xd.GetElementsByTagName("ReseptId"); if (rID.Count > 0) rID[0].InnerText = reseptID; lastLogFileName = "log\\M9NA3_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, xd.OuterXml); M9na3 m9na3 = new M9na3(); M9na4 m9na4 ; m9na3.dokument = Encoding.UTF8.GetBytes(xd.DocumentElement.OuterXml); String retstring = ""; try { m9na4 = naW.NAWebService_m9na3(m9na3); // Her er kallet mot webservice byte[] retval = (byte[])m9na4.dokument; retstring = System.Text.Encoding.UTF8.GetString(retval); XmlDocument m9na4Doc = new XmlDocument(); m9na4Doc.LoadXml(retstring); lastLogFileName = "log\\M9NA4_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, retstring); XmlNamespaceManager nsmgr = new XmlNamespaceManager(m9na4Doc.NameTable); nsmgr.AddNamespace("na4", "http://www.kith.no/xmlstds/eresept/m9na4/2016-06-06"); nsmgr.AddNamespace("mh", "http://www.kith.no/xmlstds/msghead/2006-05-24"); nsmgr.AddNamespace("fel", "http://www.kith.no/xmlstds/felleskomponent1"); // Kode for ekstraksjon av data er ikke utfyllende og kun for test! XmlNode nodeMsgId = m9na4Doc.SelectSingleNode("//mh:MsgId", nsmgr); if (nodeMsgId != null) msgIdLastM9na4 = nodeMsgId.InnerText; XmlNode reseptid = m9na4Doc.SelectSingleNode("//na4:ReseptId", nsmgr); if (reseptid != null) detaljer += "ReseptId: " + reseptid.InnerText+ Environment.NewLine; else detaljer += "ReseptId: <null>"; XmlNode status = m9na4Doc.SelectSingleNode("//na4:Status", nsmgr); if (status != null) detaljer += "Status: " + status.Attributes["DN"].Value + Environment.NewLine; else detaljer += "Status: <null>"; // Noe kode fjernet XmlNodeList utleveringer = m9na4Doc.SelectNodes("//na4:Utlevering", nsmgr); for (int node = 0; utleveringer != null && node < utleveringer.Count; node++) { XmlNode resept = utleveringer.Item(node); XmlNode nfs; string utleveringsInfo = ""; // Kun utvalgte elementer er hentet ut her! nfs = resept.SelectSingleNode("na4:NavnFormStyrke", nsmgr); if (nfs != null) { utleveringsInfo += " NavnFormStyrke: " + nfs.InnerText + Environment.NewLine; } nfs = resept.SelectSingleNode("na4:AntallPakningerUtlevertTotalt", nsmgr); if (nfs != null) { utleveringsInfo += "AntallPakningerUtlevertTotalt: " + nfs.InnerText + Environment.NewLine; ; } detaljer += utleveringsInfo; } int i = retval.Length; } catch (FaultException<NettapotekForm.NettapotekWebService.AppRecFault> appRec) { NettapotekForm.NettapotekWebService.AppRecFault af = appRec.Detail; byte[] retval = (byte[])af.dokument; retstring = System.Text.Encoding.UTF8.GetString(retval); errorMessage = "AppRec: "; lastLogFileName = "log\\Apprec_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".xml"; File.WriteAllText(lastLogFileName, retstring); XmlDocument appRecDoc = new XmlDocument(); appRecDoc.LoadXml(retstring); XmlNamespaceManager nsmgr = new XmlNamespaceManager(appRecDoc.NameTable); nsmgr.AddNamespace("apprec", "http://www.kith.no/xmlstds/apprec/2004-11-21"); // Finn Id, Status og Error XmlNode status = appRecDoc.SelectSingleNode("//apprec:Status", nsmgr); if (status != null) { errorMessage += Environment.NewLine + "Status: " + status.Attributes["DN"].Value; errorMessage += " (" + status.Attributes["V"].Value + ")"; } XmlNode error = appRecDoc.SelectSingleNode("//apprec:Error", nsmgr); if (error != null) { errorMessage += Environment.NewLine + "Error: " + error.Attributes["DN"].Value; errorMessage += " (" + error.Attributes["V"].Value + ")"; } return null; } catch (Exception excp) { errorMessage = excp.Message + Environment.NewLine + excp.InnerException.Message; return null; } return detaljer; }