I want to accept a simple x-www-form-urlencoded POST webhook call via ASP.NET from Mollie. So basically the other party is calling my webhook.
This is the webhook in question:
Here's my code:
iTest.vb
Imports System.ServiceModel
Imports System.Web
Imports System.IO
Imports System.Runtime.Remoting.Activation
Imports System.Collections.Generic
Imports System.ServiceModel.Web
<ServiceContract()>
Public Interface Itest
<OperationContract()>
<Web.WebInvoke(Method:="POST", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.WrappedRequest,
UriTemplate:="webhook_mollie")>
Function Webhook(ByVal whook As GlobalFunctions.webhookData) As Boolean
End Interface
tst.svc.vb
Public Class tst
Implements Itest
Public Function Webhook(ByVal whook As GlobalFunctions.webhookData) As Boolean Implements Itest.Webhook
Return True
End Function
End Class
Public Class webhookData
Private _id As String
<Runtime.Serialization.DataMember>
Public Property id() As String
Get
Return _id
End Get
Set(ByVal value As String)
_id = value
End Set
End Property
End Class
The "/api" part in the postman request work for my other API requests due to this rewrite rule in web.config:
<rule name="RemoveSvcExtension" stopProcessing="true">
<match url="^(.*)api/(.*)$"/>
<action type="Rewrite" url="{R:1}tst.svc/{R:2}" logRewrittenUrl="true"/>
</rule>
I also tried a direct Postman request URL: https://www.example.com/tst.svc/webhook_mollie, but with the same timeout result.
UPDATE 1
Ok, am one step further. I now get this error:
The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service. The exception message is 'The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'.
I changed my definition to:
<OperationContract()>
<Web.WebInvoke(Method:="POST", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,UriTemplate:="webhook_mollie")>
But with the same error.
This post seems the most relevant, but it has a totally different webservice definition format.
How can I redefine my current OperationContract
to accept requests of Content-Type: application/x-www-form-urlencoded
?
CodePudding user response:
I get the Mollie Webhook post by reading the stream and getting the name-value pairs.
public async void Webhook(Stream stream)
{
var collection = new NameValueCollection();
string mollieID = "";
//check the stream
if (stream == null)
{
return;
}
//get the posted data from the stream
try
{
using (var reader = new StreamReader(stream))
{
collection = HttpUtility.ParseQueryString(HttpUtility.UrlDecode(reader.ReadToEnd()));
}
mollieID = collection["id"];
}
catch (Exception ex)
{
//log error
}
//check if there is a mollie id
if (string.IsNullOrEmpty(mollieID))
return;
//check the payment status
await CheckPaymentStatus(mollieID);
}
VB below (used a converter so it may not be 100% accurate)
Public Async Sub Webhook(ByVal stream As Stream)
Dim collection = New NameValueCollection()
Dim mollieID As String = ""
If stream Is Nothing Then
Return
End If
Try
Using reader = New StreamReader(stream)
collection = HttpUtility.ParseQueryString(HttpUtility.UrlDecode(reader.ReadToEnd()))
End Using
mollieID = collection("id")
Catch ex As Exception
//log error
End Try
If String.IsNullOrEmpty(mollieID) Then Return
Await CheckPaymentStatus(mollieID)
End Sub
And in the interface default RequestFormat
and BodyStyle
.
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "mollie")]
void Webhook(Stream stream);