Ticket API issues

I am developing an app that integrates with Freshdesk to create tickets, so I am using the Freshdesk API to make requests.

  • The app is built in C# (.NET Core 3.1) using the HttpClient library.
  • I am creating tickets with attachments and built the code following the structure described on your sample app

Unlike your sample code which is manually constructed, the HttpClient library constructs the request automatically and we have little control over this.

I have had some issues making requests using the HttpClient library (which I think most people will). Essentially the request structure requirements are too strict.
Please refer to the sample code below for more info.

  • The ‘Content-Disposition’ header too strict
    • Array names formatted like name="tags[0]" doesn’t work but name="tags[]" does (see ‘TODO: (1)’)
    • The ‘name’ field always needs to be quoted (not part of the RFC) (see ‘TODO: (2)’)
  • Request is rejected if ‘Content-Type’ header is added to each form part (see ‘TODO: (3)’)
private HttpContent GetHttpContent(CreateTicketPayload payload)
{
    HttpContent content;
    var dispositionType = "form-data";

    content = new MultipartFormDataContent();
    var multiContent = content as MultipartFormDataContent;

    foreach (var attachment in payload.Attachments)
    {
        multiContent.Add(new ByteArrayContent(attachment.Data)
        {
            Headers =
            {
                ContentType = MediaTypeHeaderValue.Parse(attachment.ContentType),
                ContentDisposition = new ContentDispositionHeaderValue(dispositionType)
                {
                    Name = "attachments[]",
                    FileName = attachment.FileName,
                    CreationDate = attachment.CreationDate,
                }
            }
        });
    }

    // TODO: (1) Breaks Freshdesk - Freshdesk Content-Disposition header too strict: 
    //                              BROKEN:  Content-Disposition: form-data; name="tags[0]"
    //                              WORKS:   Content-Disposition: form-data; name="tags[]"
    // NOTE: "payload.ToDictionary()" returns a Dictionary<string,string>() representing the payload data -- e.g. { "subject": "sub", "tags[0]": "tag1", "tags[1]": "tag2" }
    foreach (var item in payload.ToDictionary())
    {
        multiContent.Add(new ByteArrayContent(System.Text.Encoding.ASCII.GetBytes(item.Value))
        {
            Headers =
            {

                ContentDisposition = new ContentDispositionHeaderValue(dispositionType)
                {
                    // TODO: (2) Breaks Freshdesk - because Freshdesk needs all values to be quoted. Manually using 'Parameters' instead
                    //Name = item.Key, 
                    Parameters =
                    {
                        new NameValueHeaderValue("name", $"\"{item.Key}\"")
                    }
                },
                // TODO: (3) Breaks Freshdesk
                // ContentType = new MediaTypeHeaderValue("text/plain")
                // {
                //     CharSet = "utf-8"
                // }
            }
        });
    }

    return content;
}

Sample (broken) request ‘content’:

--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Type: message/rfc822
Content-Disposition: form-data; name="attachments[]"; filename="39f7f39a-bd17-4ab8-3eb5-cc46b5868195.eml"; creation-date="Wed, 30 Sep 2020 23:51:46 GMT"

MIME-Version: 1.0
Date: Thu, 1 Oct 2020 00:51:40 +0100
Message-ID: <12345+abFCBUE@mail.gmail.com>
Subject: m-freshdesk
From: example <example@gmail.com>
To: example <example@gmail.com>
Content-Type: multipart/alternative; boundary="0000000000001af1d105b09095b1"

--0000000000001af1d105b09095b1
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: base64

MjAg3J+Xjw0L
--0000000000001af1d105b09095b1
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: base64

PGRpdiBkaXI911xciI+MjDCiaCfmY88L9Rpdw4NCg==
--0000000000001af1d105b09095b1--

--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=status

2
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=priority

1
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=email

example@example.com
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=subject

Ticket subject
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=description

<p>Ticket description here</p>
<p>Freshdesk test</p>
<p>Should include attachments</p>
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=type

Type
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name="tags[0]"

RandomTag
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name="tags[1]"

AnotherTag
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=fr_due_by

2020-10-01T00:46:50.9872764Z
--71b0658e-2982-47a9-964e-ef177b87ca2c
Content-Disposition: form-data; name=due_by

2020-10-01T03:21:50.9892658Z
--71b0658e-2982-47a9-964e-ef177b87ca2c--

Hi @squidlid,

We do not have experts of C# language to help you at the moment.
We recommend to contact Freshdesk support (support@freshdesk.com) while waiting for response from the other community members.

Thank you!

Thank you for your response, however this is not an issue with C# but with how your API interprets requests. I could be wrong but I don’t think your API fully complies with RFC specifications which is why certain requests fail as detailed above.