Home > Blockchain >  Accepting simple x-www-form-urlencoded POST webhook call via ASP.NET
Accepting simple x-www-form-urlencoded POST webhook call via ASP.NET

Time:01-07

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: enter image description here

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);
  • Related