Laden...

SAP RFC Webservice mit C#

Erstellt von schuppsl vor 8 Jahren Letzter Beitrag vor 6 Jahren 12.579 Views
S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren
SAP RFC Webservice mit C#

Hallo Zusammen,

wir haben einen SAP RFC Webservice, dem ich mit einem C# Programm Daten entlocken sollte.
Das soll später eine Windowsanwendung sein, im Moment ist es eine Konsolenanwendung.

Nach einem Mittag versuchen und gefühlte 1000 Webseiten durchforschen bin ich langsam am verzweifeln.

Der Webservice ist per Webbrowser erreichbar.
Der Webservice ist per Nintex Workflow im SharePoint erreichbar und er kommuniziert auch. Also der Webservice ist definitiv in Ordnung.
Nun gibt es 100 verschiedene Möglichkeiten einen Webservice einzubinden und ich habe auch schon in vergangenen Projekten u.a. eigen programmierte Webservices angesprochen.

Nur hier komme ich nicht weiter.

Hier meine Web.config:



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="WsCall.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>


  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpEndpunkt" >
          <security mode="None"></security>
        </binding>
      </netTcpBinding>
      <wsDualHttpBinding>
        <binding name="HttpEndpunkt" ></binding>
      </wsDualHttpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://xxxxxx:8000/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/sap/bc/srt/rfc/sap/zkn_select/100/zkn_select/zkn_select?sap-client=100" binding="netTcpBinding" bindingConfiguration="NetTcpEndpunkt" contract="ServiceReference1.ZKN_SELECT" name="NetTcpendpunkt" />
    </client>
  </system.serviceModel>
  
  
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    
  <system.net>
    <defaultProxy enabled="false"></defaultProxy>
  </system.net>
  <applicationSettings>
    <WsCall.Properties.Settings>
      <setting name="WsCall_refZKN_SELECT_ZKN_SELECT" serializeAs="String">
        <value>[URL]http://xxxxxxxx:8000/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/sap/bc/srt/rfc/sap/zkn_select/100/zkn_select/zkn_select?sap-client=100[/URL]</value>
      </setting>
    </WsCall.Properties.Settings>
  </applicationSettings>
</configuration>




Und hier die Programmierung:

 System.Net.NetworkCredential cr = new System.Net.NetworkCredential("user", "passw");

                refZKN_SELECT.ZknSelect ws = new refZKN_SELECT.ZknSelect();
                refZKN_SELECT.ZKN_SELECT ff = new refZKN_SELECT.ZKN_SELECT();
                ff.Credentials = cr;

                ff.Url = "http://xxxxxx:8000/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/sap/bc/srt/rfc/sap/zkn_select/100/zkn_select/zkn_select?sap-client=100";
                ff.UseDefaultCredentials = true;

                refZKN_SELECT.ZknSelectResponse res = new refZKN_SELECT.ZknSelectResponse();

                ws.Lifnr = "100000";
              


                ff.ZknSelect(ws);

Die aktuelle Fehlermeldung lautet:

Fehlermeldung:
Die zugrunde liegende Verbindung wurde geschlossen: Die Verbindung mit dem Remoteserver kann nicht hergestellt werden..

Den Service habe ich mit dem Wizard von Visual Studio 2013 eingefügt, hier habe ich die Adresse zum Test erneut eingefügt.
Wir haben hier in der Firma einen Proxy, die URL(xxxxxx) ist aber als Ausnahme eingefügt und wie gesagt, per Webbrowser und Testclient problemlos erreichbar

Was läuft hier falsch?
Ich hoffe sehr, mir kann jemand helfen, da es ein wichtiges Projekt darstellt und die Zeit natürlich drängt...

Vielen Dank!

16.807 Beiträge seit 2008
vor 8 Jahren

Ich versteh nicht wirklich, wer die Fehlermeldung wirft oder wo diese auftritt...
Zudem hab ich nicht den Hauch einer Ahnung, was refZKN_SELECT.ZKN_SELECT() sein soll...

Aber zumindest beim WebClient/HttpRequest sollte man einen Proxy (und wenn es der DefaultProxy ist) eigentlich bekannt machen.
Das einzige, was Du machst, ist den DefaultProxy gekonnt zu ignorieren

  <system.net>
    <defaultProxy enabled="false"></defaultProxy>
  </system.net>

und die Zeit natürlich drängt...

Davon abgesehen, dass sowas in einem Forum meist das Gegenteil bewirkt (keiner Antwortet Dir (schneller), weil Du in Zeitdruck bist), solltest Du auch genug Informationen zur Verfügung stellen, wenn Du eine entsprechende Antwort erwartest 😃

T
327 Beiträge seit 2006
vor 8 Jahren

Also wenn ich Webservices, die SAP direkt zur Verfügung stellt, in meine Anwendungen einbinde, dann läuft das so:

  • Unsere SAP Entwickler erstellen einen RFC Baustein und generien in SAP einen entsprechenden Endpoint
  • Ich kriege von den SAP Entwicklerm ein WSDL File, das die Definition des Webservices emthält (wird glaub ich aus einer Transaktion SOAMANAGER raus generiert aber ich hab mit SAP so leider nix am Hut 😉)
  • Das WSDL-File binde ich bei mir in Visual Studio ganz normal ein. Wichtig dabei ist, dass die Services wirklich SOAP Webservices und keine WCF Services sind (Deine config sieht mir nach WCF aus).

Wie's mit der Authentifizierung aussieht kann ich dir jetzt nicht sagen, das liegt dran ob ihr expliziten Login macht (Da kann der Username + PW via NetworkCredentials mitgegeben werden) oder irgendwas anderes (Denke da gibt's auch noch SAP Logon Tokens etc.)

Beim Aufruf der Webmethoden sind je nach Art der Parameter (Table, Import, Export, Changing) und der SAP Typen noch ein paar Sachen zu beachten (z.B. bzgl. Initialisierung von Strukturen vor dem Aufruf; Lustig wird's z.B. bei Date/Time Typen, da muss man die WSDL z.T. manuell anpassen bevor's funktioniert).

-> Wenn das ein wichtiges Projekt ist das drängt und du noch nie mit SAP Webservices gearbeitet hast wär's evtl. einfacher mit dem SAP .Net Connector 3.0 oder über ERPConnect direkt den RFC aufzurufen (Nachteil ist dann, dass der SAP GUI auf dem Client vorhanden sein muss bzw. die librfc32.dll + entprechende Einstellungen in ein paar Systemfiles).

Ein Tipp noch: Wenn der Webservice Aufruf mal grundaätzlich klappt aber z.B. auf SAP Seite nicht in die richtigen Typen konvertiert werden können ist die Transaktion SRT_UTIL eine gute Anlaufstelle.

Viel Erfolg (und Glück) 😉

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Hallo telnet, vielen Dank für die ausführliche Antwort.
Ich muss mich hier erst einfuchsen, habe früher viel mit Webservices gemacht, das ist aber ne Weile her und das holt mich jetzt wieder ein.

Im soamanager ist die SOAP Version 1.1 und 1.2.

Mit dem WSDL File habe ich es auch schon versucht, keine Chance, zumal der Assisten im Visual Studio nicht die korrekten Verbindungseinstellungen generiert (irgendwo gelesen).

Mit einem Freewaretool ist es überhaupt kein Problem den Webservice anzusprechen und mit ihm zu kommunizieren, also der Funktioniert grundsätzlich.

Also ich muss wohl einiges nachholen 😃

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Also ich weiss überhaupt nicht wo ich was einstellen muss.

Habe nochmal ein neues Projekt erstellt und den SAP Webservice als Dienstverweis hinzugefügt.

So sieht die Original automatisch erstellte App.config aus:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <client>
            <endpoint address="http://serveradress:8000/sap/bc/srt/rfc/sap/zkn_select_lifnr_altkn/100/zkn_select_lifnr_altkn/zkn_select_lifnr_altkn"
                binding="customBinding" bindingConfiguration="ZKN_SELECT_LIFNR_ALTKN"
                contract="ServiceReference2.ZKN_SELECT_LIFNR_ALTKN" name="ZKN_SELECT_LIFNR_ALTKN" />
            <endpoint address="http://serveradress:8000/sap/bc/srt/rfc/sap/zkn_select_lifnr_altkn/100/zkn_select_lifnr_altkn/zkn_select_lifnr_altkn"
                binding="customBinding" bindingConfiguration="ZKN_SELECT_LIFNR_ALTKN_soap12"
                contract="ServiceReference2.ZKN_SELECT_LIFNR_ALTKN" name="ZKN_SELECT_LIFNR_ALTKN_soap12" />
        </client>
        <bindings>
            <customBinding>
                <binding name="ZKN_SELECT_LIFNR_ALTKN">
                    <!--    WsdlImporter ermittelte unerkannte Richtlinienassertionen in ServiceDescription "urn:sap-com:document:sap:soap:functions:mc-style":    -->
                    <!--    <wsdl:binding name='ZKN_SELECT_LIFNR_ALTKN'>    -->
                    <!--        <sapattahnd:Enabled xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">..</sapattahnd:Enabled>    -->
                    <mtomMessageEncoding messageVersion="Soap11WSAddressing10" />
                    <httpsTransport authenticationScheme="Basic" />
                </binding>
                <binding name="ZKN_SELECT_LIFNR_ALTKN_soap12">
                    <!--    WsdlImporter ermittelte unerkannte Richtlinienassertionen in ServiceDescription "urn:sap-com:document:sap:soap:functions:mc-style":    -->
                    <!--    <wsdl:binding name='ZKN_SELECT_LIFNR_ALTKN_soap12'>    -->
                    <!--        <sapattahnd:Enabled xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">..</sapattahnd:Enabled>    -->
                    <mtomMessageEncoding />
                    <httpsTransport authenticationScheme="Basic" />
                </binding>
            </customBinding>
        </bindings>
      
    </system.serviceModel>
</configuration>

Und mein Aufruf:


 WindowsFormsApplication2.ServiceReference2.ZKN_SELECT_LIFNR_ALTKNClient soap = new ServiceReference2.ZKN_SELECT_LIFNR_ALTKNClient();

            soap.ClientCredentials.UserName.UserName = "user";
            soap.ClientCredentials.UserName.Password = "passw";
        
            WindowsFormsApplication2.ServiceReference2.ZknSelectLifnrAltkn req = new ServiceReference2.ZknSelectLifnrAltkn();
            WindowsFormsApplication2.ServiceReference2.ZknSelectLifnrAltknResponse response = new ServiceReference2.ZknSelectLifnrAltknResponse();


            req.Altkn = "100000";
            try
            {
                response = soap.ZknSelectLifnrAltkn(req);
            }catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + ex.InnerException);
            }

ZKNSelect... ist einfach einj kleiner Echo Service, ich gebe was mit und bekomme was zurück.

Starte ich das Ganze dann, kommt als erstes die Meldung:

Fehlermeldung:
Zusätzliche Informationen: Ein Endpunktkonfigurationsabschnitt für Vertrag "ServiceReference2.ZKN_SELECT_LIFNR_ALTKN" konnte nicht geladen werden, da mehr als eine Endpunktkonfiguration für diesen Vertrag gefunden wurde. Geben Sie den bevorzugten Endpunktkonfigurationsabschnitt mit Namen an.

Dann entferne ich einen endpoint, dann die das so aus:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <client>
           <!-- <endpoint address="http://serveradress:8000/sap/bc/srt/rfc/sap/zkn_select_lifnr_altkn/100/zkn_select_lifnr_altkn/zkn_select_lifnr_altkn"
                binding="customBinding" bindingConfiguration="ZKN_SELECT_LIFNR_ALTKN"
                contract="ServiceReference2.ZKN_SELECT_LIFNR_ALTKN" name="ZKN_SELECT_LIFNR_ALTKN" />-->
            <endpoint address="http://serveradress:8000/sap/bc/srt/rfc/sap/zkn_select_lifnr_altkn/100/zkn_select_lifnr_altkn/zkn_select_lifnr_altkn"
                binding="customBinding" bindingConfiguration="ZKN_SELECT_LIFNR_ALTKN_soap12"
                contract="ServiceReference2.ZKN_SELECT_LIFNR_ALTKN" name="ZKN_SELECT_LIFNR_ALTKN_soap12" />
        </client>
        <bindings>
            <customBinding>
                <binding name="ZKN_SELECT_LIFNR_ALTKN">
                    <!--    WsdlImporter ermittelte unerkannte Richtlinienassertionen in ServiceDescription "urn:sap-com:document:sap:soap:functions:mc-style":    -->
                    <!--    <wsdl:binding name='ZKN_SELECT_LIFNR_ALTKN'>    -->
                    <!--        <sapattahnd:Enabled xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">..</sapattahnd:Enabled>    -->
                    <mtomMessageEncoding messageVersion="Soap11WSAddressing10" />
                    <httpsTransport authenticationScheme="Basic" />
                </binding>
                <binding name="ZKN_SELECT_LIFNR_ALTKN_soap12">
                    <!--    WsdlImporter ermittelte unerkannte Richtlinienassertionen in ServiceDescription "urn:sap-com:document:sap:soap:functions:mc-style":    -->
                    <!--    <wsdl:binding name='ZKN_SELECT_LIFNR_ALTKN_soap12'>    -->
                    <!--        <sapattahnd:Enabled xmlns:sapattahnd="http://www.sap.com/710/features/attachment/">..</sapattahnd:Enabled>    -->
                    <mtomMessageEncoding />
                    <httpsTransport authenticationScheme="Basic" />
                </binding>
            </customBinding>
        </bindings>
      
    </system.serviceModel>
</configuration>

Dann kommt die Meldung:> Fehlermeldung:

Das bereitgestellte URI-Schema http ist ungültig; erwartet wurde "https".
Parametername: via

Danach ändere ich httpstransport zu httptransport.

Dann bekomme ich die Fehlermeldunghttp://www.mycsharp.de/wbb2/images/bbcode_csharp.adler.gif:

Fehlermeldung:
Fehler beim Erstellen des Webproxys, der Im Konfigurationsabschnitt System.net/defaultProxy angegben ist.
...Socketexception usw...

Mit dem Tool SoapUI geht es einfandfrei.
Wo ist denn der Fehler? Was muss ich wo angeben?

Edit:
Setze ich das hier ein, kommt wieder die Meldung:> Fehlermeldung:

Die zugrunde liegende Verbindung wurde geschlossen: Die Verbindung mit dem Remoteserver kann nicht hergestellt werden


<system.net>
     <defaultProxy enabled ="false">
       <proxy autoDetect ="True"/>
     </defaultProxy>
   </system.net>

 
16.807 Beiträge seit 2008
vor 8 Jahren

Und wieso gibst Du nicht einfach direkt die nötigen Proxyinformationen (Url, Authetifizierung, Typ) an?
AutoDetect ist nicht immer die beste Entscheidung....

Dein Freeware Tool funktioniert, weil das den Proxy richtig behandelt.
Und wenn SAP hier HTTPS will, dann musst Du dies eben auch korrekt implementieren und behandeln.

Es bringt übrigens nichts, wenn Du den wichtigen Teil einer Exception hier im Forum mit "etc..." ersetzt und wir das relevante gar nicht sehen....

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

...und hier das etc:

Fehlermeldung:
Die zugrunde liegende Verbindung wurde geschlossen: Die Verbindung mit dem Remoteserver kann nicht hergestellt werden..
System.Net.Sockets.SocketException (0x80004005): Ein ungültiges Argument wurde angegeben
bei System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
bei System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
bei System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
bei System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest)

16.807 Beiträge seit 2008
vor 8 Jahren

Ich denke es ist ein Kombinationsproblem aus HTTPS und dem Proxy.

Erst mal schauen, ob HTTPS nötig ist oder nicht. Einfach was ändern, ohne zu prüfen, macht kein Sinn.
Danach entsprechend HTTPS integrieren, wie es gewünscht ist.

Anschließend kann man sich um den Proxy kümmern.

Du hast ja gemeint, dass das Ding für euch wichtig ist.
Umso mehr würde ich mich damit ab den Grundlagen beschäftigen, damit Du auch zukünftige Laufzeitprobleme verstehst und schnell beheben kannst.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Also Https ist definitiv nicht notwendig, wir haben den Webservice mit dem Consultant zum Test extra ohne aufgesetzt.

Ja, es sind Grundlagen die fehlen.
Aber ich denke wenn ich schon einen so tolle Wizard habe, warum muss ich dann noch selbst Hand anlegen?

Egal.
Ich habe verschiedene Dinge durchprobiert und es steht i.d.R. nirgends etwas über einen Proxy und wie man diesen angibt.
Zudem ist der SAP Server im Proxy als Ausnahme drin, d.h. hier wird kein Proxy benötigt.

16.807 Beiträge seit 2008
vor 8 Jahren

Naja, wie so vieles sind nicht alle GUI Elemente auch die, die man für produktive Umgebungen nutzen sollte....

Ich würde zB nie einen Endpunkt ZKN_SELECT_LIFNR_ALTKN nennen, auch wenn mir durchaus die Namensconventionen von SAP bekannt sind.
Man sollte auch als Entwickler immer wissen, was dahinter steckt.

Wenn HTTPS nicht notwendig ist, dann würde ich jetzt noch den Proxy analysieren.
Dieser macht evtl dann hier Mucken.

Versuch doch mal nen normalen WebClient von Hand aufzurufen und Daten des Endpunkts zu lesen; und wenn es nur nen Serverfehler ist.
Dann weißt Du doch wenigstens, ob Du durch kommst............

W
955 Beiträge seit 2010
vor 8 Jahren

Kannst du nicht ein SAP Consultant um Rat fragen? Ihr müsst doch einen haben der dir sagt welche Funktionsbausteine du anfassen sollst. Der kann dir doch auch von der SAP-support-site vllt ein paar Programmierbeispiele / HOWTOs runterladen.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Also als Rückmeldung:
Inzwischen klappt es einwandfrei...manchmal muss man einfach nur etwas Zeit verstreichen lassen 😃

Vielen Dank an alle.

W
1 Beiträge seit 2017
vor 6 Jahren

Guten Morgen Schuppsl,

kannst du mir evtl. verraten, was du gemacht hast, um das Problem zu lösen?

Ich stehe aktuell vor dem gleichen Problem und weiß nicht mehr weiter.

Vielen Dank im Voraus!

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 6 Jahren

Hallo Walda,

ich nutze inzwischen den SAP .NET Connector. Den kannst Du Dir im SAP Marketplace herunterladen.
Das funktioniert einwandfrei.

Hier ein Beispiel:

SAP .NET Connect

Bei Fragen kannst Dich gerne nochmals melden.