asp.net-coremultipartform-datarestsharpflurlfreshdesk

Flurl \ RestSharp: `\r\n` is added to each parameter of the Multipart request


I'm trying to write a call to the Freshdesk API using either Flurl or RestSharp library.

The API call I'm trying to write is Creating a Ticket: https://developers.freshdesk.com/api/#create_ticket

An example of cURL:

curl -v -u yourapikey:X -F "attachments[]=@/path/to/attachment1.ext" -F "attachments[]=@/path/to/attachment2.ext" -F "email=example@example.com" -F "subject=Ticket Title" -F "description=this is a sample ticket" -X POST 'https://domain.freshdesk.com/api/v2/tickets'

Note params are passed by -F (i.e. --form) flag.

With the following code calling Flurl:

var rs = await url.WithBasicAuth(_configuration.ApiKey, _configuration.Password)
                  .PostMultipartAsync(mp =>
                  {
                      mp.AddString("email", ticket.Email);
                      mp.AddString("subject", ticket.Subject);
                      mp.AddString("status", ticket.Status.ToString());
                      mp.AddString("priority", ticket.Priority.ToString());
                      mp.AddString("description", ticket.Description);
                  });

...Or the following code calling RestSharp:

var request = new RestRequest("tickets", Method.Post);
request.AlwaysMultipartFormData = true;
request.AddParameter("email", ticket.Email);
request.AddParameter("description", ticket.Description);
request.AddParameter("subject", ticket.Subject);
request.AddParameter("status", ticket.Status);
request.AddParameter("priority", ticket.Priority);

var rs = await client.ExecuteAsync(request);

...I'm receiving 400 BadRequest with the following information (in both cases):

{
    "description": "Validation failed",
    "errors": [
        {
            "code": "invalid_field",
            "field": "email\r\n",
            "message": "Unexpected/invalid field in request"
        },
        {
            "code": "invalid_field",
            "field": "subject\r\n",
            "message": "Unexpected/invalid field in request"
        },
        {
            "code": "invalid_field",
            "field": "status\r\n",
            "message": "Unexpected/invalid field in request"
        },
        {
            "code": "invalid_field",
            "field": "priority\r\n",
            "message": "Unexpected/invalid field in request"
        },
        {
            "code": "invalid_field",
            "field": "description\r\n",
            "message": "Unexpected/invalid field in request"
        }
    ]
}

Note that:

Update 1

Postman screenshot (working example):

enter image description here

Update 2

I tried to use Tiny.RestClient which has cURL listener and it came with the following cURL generated:

curl -X POST [...] -d "--1c3acb07-77bd-494d-bc56-21290dcd5088
Content-Type: text/plain
Content-Disposition: form-data; name=email

a@a.com
[...]

Perhaps, Flurl and RestSharp uses the same way to proceed with parameters and thus, the \r\n in fields.


Solution

  • It's the FreshDesk API issue. They want, for some reason, for multipart form-data parameter names to be enclosed in quotation marks. It's not a requirement per HTTP standards. RestSharp and Flurl use MultipartFormDataContent, and it adds uses parameter names as provided.

    Following up on your issue, I added this property to RestRequest:

    /// <summary>
    /// When set to true, parameters in a multipart form data requests will be enclosed in
    /// quotation marks. Default is false. Enable it if the remote endpoint requires parameters
    /// to be in quotes (for example, FreshDesk API). 
    /// </summary>
    public bool MultipartFormQuoteParameters { get; set; }
    

    It is available in RS 107.3.0.

    You can also make it work by adding parameters like this:

    request.AddParameter("\"status\"", ticket.Status);