[asp.net mvc] SOAP / HTTP POST notifications

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Flapmo
  • Registratie: April 2000
  • Laatst online: 12:22

Flapmo

and back is gigi!

Topicstarter
Voor een huidige werkgever moet ik een systeem koppelen aan de website dat gebruikt maakt van Hosted Payment Pages om betalingen die verzonden naar dit systeem af te handelen. Na elke betaling die je vanuit je eigen webapp zend naar het externe systeem, zend dit systeem een notificatie. Als gebruiker van het systeem kan je in de backend instellen of je deze notificatie via SOAP of HTTP POST wil afhandelen. In de backend kan je ook instellen naar welke server dit bericht verzonden moet worden. Het systeem heeft een WSDL file beschikbaar indien SOAP gebruikt wordt (die de gebruikte specificatie geeft). Elke ontvangen notificatie moet beantwoord worden met een Response met value "accepted".

Nu heb ik nog nooit te maken gehad met web services en ben ik op zoek naar goede tutorials / guides / informatie over hoe ik dit moet aanpakken. Na een aantal uren doorgebracht te hebben met google doorspitten loop ik toch vast.

Ik lees verschillende oplossingen. De ene oplossing vermeld mij dat ik een WCF service moet aanmaken en begint vervolgens heel WCF services uit te leggen.

Een ander meldt mij dat ik de WSDL als een "web reference" kan toevoegen aan mijn asp.net mvc project. Dit genereerd inderdaad een aantal stubclasses waaronder een NotificationRequestItem die inderdaad de properties heeft die meegestuurd worden met een Notificatie. Deze kan per 1 of meer in een Notificatie zitten. In een stub Notification zit een Notification.sendNotification(NotificationRequest r). In de WSDL file staat onder andere ook een stukje:

code:
1
2
3
4
5
6
7
8
9
10
11
<wsdl:message name="sendNotificationResponse">
    <wsdl:part name="parameters" element="tns:sendNotificationResponse" />
  </wsdl:message>

....

<wsdl:operation name="sendNotification">
      <wsdl:input name="sendNotificationRequest" message="tns:sendNotificationRequest" />
      <wsdl:output name="sendNotificationResponse" message="tns:sendNotificationResponse" />
      <wsdl:fault name="ServiceException" message="tns:ServiceException" />
    </wsdl:operation>


conclusie
Ik ben alleen volledig de draad kwijt hoe ik nu moet communiceren met de externe web service. Kan dit direct vanuit mijn (asp.net mvc) web applicatie direct (vanuit de controller) met gebruik van de WSDL die je importeert via add web reference of moet ik toch een aparte service hosten op mijn IIS? De vraag is dus vooral hoe ik een SOAP / HTTP POST response (of request for that matter) kan sturen naar de externe web service.

Ik vermoed dat ik een aparte WCF service moet aanmaken en die de koppeling laten leggen?

Een voorbeeld in php is:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php 
 
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache 

class NotificationRequest {
    public $notificationItems; 
    public $live; 
}

class NotificationRequestItem {
    public $amount;
}

class Amount {
    public $currency;
    public $value;
}

function sendNotification($request) { 

  if($request->live) {
    $fp = fopen('/tmp/out_live.txt', 'w');
  } else {
    $fp = fopen('/tmp/out_test.txt', 'w');
  }
  
  $output = var_export($request,true);
  fprintf($fp, '%s', "BEGIN\n". $output . "\nEND\n");

  # For some reason NotificationRequestItem is an array for multiple notifications
  # and a scalar for a single notification (rather than an array with length = 1) 
  if (is_array($request->notification->notificationItems->NotificationRequestItem)) {
    foreach( $request->notification->notificationItems->NotificationRequestItem as $item) {
      storeItem($item, $fp);
    }
  } else {
    $item = $request->notification->notificationItems->NotificationRequestItem;
      storeItem($item, $fp);
  }

  return array("notificationResponse" => "accepted");
} 

/* 
   Store the notification here. 
   We don't attempt to process them here, leave that for an offline process which 
   can deal with processing errors for individual notificatons.
 */
function storeItem($item, $fp) { 

  $output = $output . "\nNotification: \n" . 
    "Amount = " . $item->amount->currency . " " . $item->amount->value . "\n" .
    
    "Available Operations: \n";

    if(is_array($item->operations->string)) {
      foreach($item->operations->string as $operation) {
        $output = $output . "\t" . $operation . "\n" ;
      }
    } else {
      $output = $output . "\t" . $item->operations->string . "\n" ;
    }

    $output = $output . "\n\nAdditional Data:\n";
    if(is_array($item->additionalData->entry)) {
      foreach($item->additionalData->entry as $entry) {
        $output = $output . "\t" . $entry->key ."=".$entry->value."\n" ;
      }
    } else {
      $output = $output . "\t" . $item->additionalData->entry->key ."=".$item->additionalData->entry->value."\n" ;
    }

    $output = $output . "\n";

    fprintf($fp, '%s', $output);
}
 
$classmap = array('NotificationRequest' => 'NotificationRequest', 
    'NotificationRequestItem' => 'NotificationRequestItem',
    'Amount' => 'Amount');

# Use a locally cached version of the Notification.wsdl to guarantee service uptime
# However, Notification.wsdl should be regularly updated from here: 
#      https://url-to-wsdl/xx?wsdl

$server = new SoapServer("Notification.wsdl", array('classmap' => $classmap)); 
$server->addFunction("sendNotification"); 
$server->handle();

?>

"The purpose of computing is insight, not numbers." -- Richard Hamming


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 12-09 23:23

Guldan

Thee-Nerd

Ik zou persoonlijk gewoon de webreference gebruiken, omdat die alles voor je regelt qua klassen. Echter kan ik niet zo goed helpen met het terugsturen van die request. Als het in je WSDL opgenomen is en je hebt er een methode voor dan zou je het gewoon kunnen testen.

Ik weet niet precies wat je bedoeld met een WPF service. Maar als ik google dan lijkt mij dat een generieke laag waarmee verschillen dingen kunnen communiceren. En dat uiteindelijk uitkomt in je webservice. Is het nodig dat die webservice nog generieker is dan dat hij nu al is? Als dat niet het geval is dan zou ik hem als reference toevoegen.

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Je kan de WSDL als WebReference meegeven, maar dan moet je ook een URL opgeven waar de webservice die aan die WSDL gekoppeld zit draait.

Als je zelf nog een webservice (implementatie) moet schrijven, maar je hebt alleen een WSDL file die de 'contract' bevat moet je zelf nog een (WCF) Webservice project schrijven.

Ik heb zelf voor school een project gehad dat ook WebServices bevat, alleen gebruikt ASP.NET MVC daar niet de WebService zelf. (ASP.NET MVC wordt zelf wel gebruikt)

Het is redelijk uitgebreid maar je kan even kijken wat je er aan hebt: http://www.assembla.com/code/storewars/git/nodes?rev=master

Acties:
  • 0 Henk 'm!

  • Flapmo
  • Registratie: April 2000
  • Laatst online: 12:22

Flapmo

and back is gigi!

Topicstarter
@Guldan, WPF moest WCF zijn, typefout.
@ HMS, bedankt, ik ga er na het weekend eens naar kijken.

"The purpose of computing is insight, not numbers." -- Richard Hamming


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 12-09 23:23

Guldan

Thee-Nerd

Flapmo dus de oplossing met een service is dat je er een (web)service tussen gaat knopen die gaat communiceren met de uiteindelijke webservice?
code:
1
[app]<--> [wcf service] <--> [webservice]

Dat lijkt mij ook wat omslachtig... OF moet je de webservice nog wel zelf schrijven zoals HMS als noemt?

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • Flapmo
  • Registratie: April 2000
  • Laatst online: 12:22

Flapmo

and back is gigi!

Topicstarter
Indien je SOAP gebruikt vermoed ik dat je toch de webservice nog zelf moet schrijven omdat de WDSL wel een sendNotification heeft maar dat is vermoed ik wat zij gebruiken. Er bestaat alleen een Notification (die binnenkomt) maar ik zag in die WDSL geen enkele mogelijkheid om een response te sturen als antwoord dat ik het ontvangen had. Als ik vervolgens een simpele SOAP response wil sturen waarvan ik de opmaak al weet moet ik volgens mij als nog een hele service aanmaken om dat SOAP bericht te sturen of niet?

Indien dit niet het geval is zoek ik een goede bron die uitleg geeft hoe je vanuit .net een SOAP respons kan aanmaken en versturen.

Een makkelijkere mogelijkheid lijkt mij, nu ik las dat ze HTTP POST ook accepteren, om een HTTP POST respons te sturen. Dit kan wel direct vanuit een ASP.net MVC controller zover ik weet. Ik moet dit nog wel implementeren maar dit lijkt mij eenvoudiger dan een SOAP respons sturen.

Maar correct me if I'm wrong :).

"The purpose of computing is insight, not numbers." -- Richard Hamming


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS


Acties:
  • 0 Henk 'm!

Verwijderd

Als ik je post goed begrijp is het scenario dat jij iets verstuurd naar een extern systeem en dat dat systeem een notification terugstuurd naar jouw website als het request is afgehandeld. Een callback dus.

In dat geval heb je er niets aan om een webreference te maken obv die wsdl. Web references genereren simpelweg een proxyklasse die het consumeren van een externe webservice vereenvoudigd. In dit scenario moet jij zelf een webservice schrijven die de notification die wordt verzonden vanuit het externe systeem kan verwerken. De wsdl is simpelweg het contract waaraan die webservice zich moet houden qua methoden en typen. Dus: (C#)

[WebMethod]
public sendNotificationResponse sendNotification(sendNotificationRequest request)

Het externe systeem knalt gewoon die notification naar de url die is ingesteld en verwacht dat de webservice die daar wordt gehost dat bericht snapt en weet wat er mee te doen. Wat je als response waarde teruggeeft is een waarde van type sendNotificationResponse. zoiets.

Hier heb je ook WCF niet voor nodig, het schrijven van een webservice is ook niet zo moeilijk. Zorg ervoor dat de methoden en klassen die je in je webservice gebruikt qua datatypen en method signatures zich houdt aan die wsdl. Als je niet weet je een webservice moet schrijven google dan ff dat is nl. heel eenvoudig.

En die webservice host je dan in IIS.
Pagina: 1