Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SAP .NET Connector: How To implement RFC Server with destination type Start

512 views
Skip to first unread message

Sascha Beltz

unread,
Apr 28, 2004, 5:21:36 AM4/28/04
to
Hi all,

I would like to implement a RFC Server in C# using the SAP .NET
Connector. This server should be started on the frontend workstation
(user's computer). So I have set up a TCP/IP destination of type
"Start" in SAP and configured it to start my RFC Server on the
client's machine. The problem is that the parameters passed to the RFC
server by SAP are not in the format the .NET Connector expects them to
be. In C you would have to call "RfcAccept" and afterwards a kind of
"dispatch". But there are no such methods in the SAP .NET Connector.
Does anybody know how to solve this?

Any help would be really appreciated!

Thanks in advance
Sascha

Christoph

unread,
Apr 28, 2004, 6:40:39 AM4/28/04
to
Hallo,
In dem Namespace SAP.Connector befindet sich eine Klasse
SAPClient. Schreibt eine Klasse und leite sie von
SAPClient ab.

public class SAPProxy : SAPClient
{
}

Im Konstruktor kannst du die Connection aufbauen z.B.:

public class SAPProxy : SAPClient
{
public SAPProxy(string t_conn) : base(t_conn){}
}

t_conn hat folgendes format (Alle informationen in
SAPGUI - Configuration) :
ASHOST=xyz01 SYSNR=0 CLIENT=200 USER=TEST PASSWD=Hugo

jetzt brauchst du nur in deine SAPProxy die methoden (SAP-
FUNKTIONEN) zu definieren, hier beispiel für
BAPI_BUPA_STATUS_GETDETAIL:

public class SAPProxy : SAPClient
{
public SAPProxy(string t_conn) : base(t_conn){}

[RfcMethod(AbapName = "BAPI_BUPA_STATUS_GETDETAIL")]
[SoapDocumentMethodAttribute
("http://tempuri.org/BAPI_BUPA_STATUS_GETDETAIL",
RequestNamespace = "urn:sap-
com:document:sap:rfc:functions",
RequestElementName = "BAPI_BUPA_STATUS_GETDETAIL",
ResponseNamespace = "urn:sap-
com:document:sap:rfc:functions",
ResponseElementName
= "BAPI_BUPA_STATUS_GETDETAIL.Response")]
public void Bapi_Bupa_Status_Getdetail (

[RfcParameter(AbapName
= "BUSINESSPARTNER",RfcType=RFCTYPE.RFCTYPE_CHAR, Optional
= false, Direction = RFCINOUT.IN, Length = 10, Length2 =
20)]
[XmlElement("BUSINESSPARTNER", IsNullable=false)]
string Businesspartner,
[RfcParameter(AbapName
= "RETURN",RfcType=RFCTYPE.RFCTYPE_ITAB, Optional = true,
Direction = RFCINOUT.INOUT)]
[XmlArray("RETURN", IsNullable=false)]
[XmlArrayItem("BAPIRET2", IsNullable=false)]
ref BAPIRET2Table Return,
[RfcParameter(AbapName
= "STATUS",RfcType=RFCTYPE.RFCTYPE_ITAB, Optional = false,
Direction = RFCINOUT.INOUT)]
[XmlArray("STATUS", IsNullable=false)]
[XmlArrayItem("BAPIBUS1006_CRM_JEST_GET",
IsNullable=false)]
ref BAPIBUS1006_CRM_JEST_GETTable Status)
{
object[]results = null;
results = this.SAPInvoke
("Bapi_Bupa_Status_Getdetail",new object[] {

Businesspartner,Return,Status });
Return = (BAPIRET2Table) results[0];
Status = (BAPIBUS1006_CRM_JEST_GETTable) results
[1];

return;
}
}

Fertig !.


>-----Originalnachricht-----

>.
>

Sascha Beltz

unread,
Apr 28, 2004, 11:15:08 AM4/28/04
to
Hallo Christoph,

danke für deine schnelle Antwort.

Ich bin mir aber nicht sicher, ob ich damit mein Problem lösen kann.
Deine Becshreibung unten sieht mir nach einer SAP Client Anwendung
aus, die sich am SAP anmeldet. Ich will aber einen RFC Server
schreiben, der quasi als eine Art SAP-Extension direkt aus dem SAP
aufgerufen werden kann. Der .NET Connector generiert auch den Server
Stub, aber die Sample Main, die erstellt wird kann mit dem Format der
internen Kommandozeilenparameter nichts anfangen. Zumindest ist das
der Fall, wenn ich in der TCP/IP Destination angebe, dass die
Anwendung auf dem Rechner gestartet werden soll auf dem auch die SAP
GUI läuft. Da bekommt man dann den ASHost, Gatewayservice, eine Nummer
(10 stellig) und "IDX=0". Mit diesen Infos muss es irgendwie möglich
sein dem SAP zu signaliseren, dass der RFC Server gestartet ist und
entsprechend Aufrufe entegennimmt. Das ist das, was ich mit RFCAccept
meinte. Leider weiß ich nicht wie das funktioniert.

Aber vielleicht hast du (oder jemand anderes) ja dazu auch noch eine
Idee ;-)

Sascha

"Christoph" <anon...@discussions.microsoft.com> wrote in message news:<569401c42d0d$3f44e140$a101...@phx.gbl>...


> Hallo,
> In dem Namespace SAP.Connector befindet sich eine Klasse
> SAPClient. Schreibt eine Klasse und leite sie von
> SAPClient ab.
>
> public class SAPProxy : SAPClient
> {
> }
>
> Im Konstruktor kannst du die Connection aufbauen z.B.:
>
> public class SAPProxy : SAPClient
> {

> public SAPProxy(string t conn) : base(t conn){}
> }
>
> t conn hat folgendes format (Alle informationen in

> SAPGUI - Configuration) :
> ASHOST=xyz01 SYSNR=0 CLIENT=200 USER=TEST PASSWD=Hugo
>
> jetzt brauchst du nur in deine SAPProxy die methoden (SAP-

> FUNKTIONEN) zu definieren, hier beispiel f r
> BAPI BUPA STATUS GETDETAIL:
>
> public class SAPProxy : SAPClient
> {
> public SAPProxy(string t conn) : base(t conn){}
>
> [RfcMethod(AbapName = "BAPI BUPA STATUS GETDETAIL")]
> [SoapDocumentMethodAttribute
> ("http://tempuri.org/BAPI BUPA STATUS GETDETAIL",


> RequestNamespace = "urn:sap-
> com:document:sap:rfc:functions",

> RequestElementName = "BAPI BUPA STATUS GETDETAIL",


> ResponseNamespace = "urn:sap-
> com:document:sap:rfc:functions",
> ResponseElementName

> = "BAPI BUPA STATUS GETDETAIL.Response")]
> public void Bapi Bupa Status Getdetail (
>
> [RfcParameter(AbapName
> = "BUSINESSPARTNER",RfcType=RFCTYPE.RFCTYPE CHAR, Optional

> = false, Direction = RFCINOUT.IN, Length = 10, Length2 =
> 20)]
> [XmlElement("BUSINESSPARTNER", IsNullable=false)]
> string Businesspartner,
> [RfcParameter(AbapName

> = "RETURN",RfcType=RFCTYPE.RFCTYPE ITAB, Optional = true,

> Direction = RFCINOUT.INOUT)]
> [XmlArray("RETURN", IsNullable=false)]
> [XmlArrayItem("BAPIRET2", IsNullable=false)]
> ref BAPIRET2Table Return,
> [RfcParameter(AbapName

> = "STATUS",RfcType=RFCTYPE.RFCTYPE ITAB, Optional = false,

> Direction = RFCINOUT.INOUT)]
> [XmlArray("STATUS", IsNullable=false)]

> [XmlArrayItem("BAPIBUS1006 CRM JEST GET",
> IsNullable=false)]
> ref BAPIBUS1006 CRM JEST GETTable Status)


> {
> object[]results = null;
> results = this.SAPInvoke

> ("Bapi Bupa Status Getdetail",new object[] {


>
> Businesspartner,Return,Status });
> Return = (BAPIRET2Table) results[0];

> Status = (BAPIBUS1006 CRM JEST GETTable) results

Christoph

unread,
Apr 29, 2004, 6:51:02 AM4/29/04
to
Hallo,

du kennst die Beispiele wie man z.B. Microsoft Word aus
SAP aufrufen kann. Ja da mußt du eine .NET Dll schreiben
und als COM registrieren. In SAP (ABAP) hier Word Beispiel.

DATA:
word_object TYPE ole2_object.

CREATE OBJECT word_object ,Word.Application'. *oder
MyNamespace.MyClass

SET PROPERTY OF word_object ,Visible' = 1. *oder MyProperty
CALL FUNCTION ,FLUSH'.

CALL METHOD word_object ,EineMethode'.

FREE OBJECT word_object.

//Christoph.

>-----Originalnachricht-----

>.
>

Sascha Beltz

unread,
Apr 29, 2004, 10:02:28 AM4/29/04
to
Hallo,

das scheint ein Weg zu sein, den man gehen könnte. Aber ich möchte
eigentlich ungern den Weg über COM Interop gehen. Ich bin mir auch
nicht sicher, ob hier das Marshalling der Parameter aus SAP nach .NET
und zurück sauber funktioniert, wenn ich auch noch über die COM-Grenze
muss...
Ich habe mittlerweile die Meldung von SAP, dass der eigentliche Weg
(RFC-Server, der von SAP gestartet wird, wie früher im RFCSDK
verfügbar) im SAP .NET Connector nicht funktioniert. Sie wollen
hierfür aber bei Gelegenheit einen Patch zur Verfügung stellen. Bin ja
mal gespannt wie lange das dauert ;-)
In der Zwischenzeit haben wir einen guten Workaround gefunden, der die
Sache auch noch stabiler machen wird.

Trotzdem vielen Dank für deine Antworten.

Bis später - Sascha


"Christoph" <anon...@discussions.microsoft.com> wrote in message news:<5cf001c42dd7$dd5d6300$a401...@phx.gbl>...


> Hallo,
>
> du kennst die Beispiele wie man z.B. Microsoft Word aus

> SAP aufrufen kann. Ja da mu t du eine .NET Dll schreiben

> und als COM registrieren. In SAP (ABAP) hier Word Beispiel.
>
> DATA:

> word object TYPE ole2 object.
>
> CREATE OBJECT word object ,Word.Application'. *oder
> MyNamespace.MyClass
>
> SET PROPERTY OF word object ,Visible' = 1. *oder MyProperty
> CALL FUNCTION ,FLUSH'.
>
> CALL METHOD word object ,EineMethode'.
>
> FREE OBJECT word object.
>
> //Christoph.
>
> >-----Originalnachricht-----
> >Hallo Christoph,
> >
> >danke f r deine schnelle Antwort.

> >
> >Ich bin mir aber nicht sicher, ob ich damit mein Problem

> l sen kann.


> >Deine Becshreibung unten sieht mir nach einer SAP Client
> Anwendung
> >aus, die sich am SAP anmeldet. Ich will aber einen RFC
> Server
> >schreiben, der quasi als eine Art SAP-Extension direkt
> aus dem SAP
> >aufgerufen werden kann. Der .NET Connector generiert auch
> den Server
> >Stub, aber die Sample Main, die erstellt wird kann mit
> dem Format der
> >internen Kommandozeilenparameter nichts anfangen.
> Zumindest ist das
> >der Fall, wenn ich in der TCP/IP Destination angebe, dass
> die
> >Anwendung auf dem Rechner gestartet werden soll auf dem
> auch die SAP

> >GUI l uft. Da bekommt man dann den ASHost,

> Gatewayservice, eine Nummer
> >(10 stellig) und "IDX=0". Mit diesen Infos muss es

> irgendwie m glich


> >sein dem SAP zu signaliseren, dass der RFC Server
> gestartet ist und
> >entsprechend Aufrufe entegennimmt. Das ist das, was ich
> mit RFCAccept

> >meinte. Leider wei ich nicht wie das funktioniert.

u.sc...@sap.com

unread,
May 9, 2014, 9:44:38 AM5/9/14
to
Am Donnerstag, 29. April 2004 16:02:28 UTC+2 schrieb Sascha Beltz:
> Hallo,
>
> das scheint ein Weg zu sein, den man gehen könnte. Aber ich möchte
> eigentlich ungern den Weg über COM Interop gehen. Ich bin mir auch
> nicht sicher, ob hier das Marshalling der Parameter aus SAP nach .NET
> und zurück sauber funktioniert, wenn ich auch noch über die COM-Grenze
> muss...
> Ich habe mittlerweile die Meldung von SAP, dass der eigentliche Weg
> (RFC-Server, der von SAP gestartet wird, wie früher im RFCSDK
> verfügbar) im SAP .NET Connector nicht funktioniert. Sie wollen
> hierfür aber bei Gelegenheit einen Patch zur Verfügung stellen. Bin ja
> mal gespannt wie lange das dauert ;-)
> In der Zwischenzeit haben wir einen guten Workaround gefunden, der die
> Sache auch noch stabiler machen wird.
>
> Trotzdem vielen Dank für deine Antworten.
>
> Bis später - Sascha
>

Hallo Sascha,
von welchem SAP .NET Connector redest Du, Version 2.0 oder 3.0?
Denn in Version 3.0 geht das, was Du willst, eigentlich schon. Wer hat Dir da bei SAP gesagt, dafür wäre ein Patch erforderlich??

Hier ein paar Zeilen Code, wie ein angestarteter RFC Server mit NCo 3.0 aussehen würde:

using SAP.Middleware.Connector;

static void Main(string[] args){
Type[] handlers = new Type[1] { typeof(MyRFCServerImp) };
RfcServer server = RfcServerManager.GetServer("serverName", handlers);
server.Repository = ... // Hier mußt Du Dir was überlegen. Entweder ein hard-codiertes Repository anlegen, was die gewünschten FuBas enthält, oder mit User/Passwd eine Client-Destination anlegen und desssen Repository hier mitgeben, so daß die nötigen Metadaten für reinkommende FuBa-Aufrufe zur Laufzeit aus dem ABAP DDIC gelesen werden können.

server.Start(args);
}

Das ist im Prinzip schon alles. Du Mußt natürlich noch die angegebene Klasse "MyRFCServerImp" implementieren, welche die "Business Logik" für die FuBas enthält, welche Dein Server anbieten soll.

Noch eine Anmerkung zu Christophs Beitrag vom 28.4.:
das Coding sieht mir danach aus, daß es den .NET Connector 2.0 verwendet. Diese Version sollte nicht mehr verwendet werden, da sie zum einen nur mit Microsoft .NET Framework 1.1 funktioniert (mit aktuelleren .NET Frameworks ist es nicht stabil. Man kann Glück haben -- muß es aber nicht...) und zum anderen von SAP eh schon seit einigen Jahren nicht mehr gewartet wird.
(Mal abgesehen davon, daß das Beispiel einen *RFC Client* beschreibt, während Du ja das Gegenteil, einen *RFC Server* willst... :-))

Viele Grüße, Ulrich
0 new messages