Skip to content

Support -F / --form in the Multipart parameters #1744

Closed

Description

@dariusz-wozniak

I'd like to create a ticket with attachment in the Freshdesk API [API reference].

Example of the cURL for the request:

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'

When the following RestSharp code is used:

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

...Then it results with the 400 BadRequest with the following response:

{
    "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"
        }
    ]
}

The above works fine in Postman:

image

The request is to provide a proper ParameterType to handle the above scenario.

Activity

  1. changed the title [-]Support `-f` / `--form` in the Multipart parameters[/-] [+]Support `-F` / `--form` in the Multipart parameters[/+] on Feb 10, 2022
  2. alexeyzimarev commented on Feb 10, 2022

    @alexeyzimarev
    Member

    Can you explain what that -F thing does? I am a bit confused as the request in Postman looks like JSON, not a form.

  3. dariusz-wozniak commented on Feb 10, 2022

    @dariusz-wozniak
    Author

    In the Postman, the current selection is a form-data.

    There's also a Code snippet view; for RestSharp the generated code (that doesn't work) is as the following (sensitive data removed):

    var client = new RestClient("https://SENSITIVE.freshdesk.com/api/v2/tickets");
    client.Timeout = -1;
    var request = new RestRequest(Method.POST);
    request.AddHeader("Content-Type", "multipart/form-data");
    request.AddHeader("Authorization", "Basic SENSITIVE");
    request.AddHeader("Cookie", "_x_w=5_2");
    request.AlwaysMultipartFormData = true;
    request.AddParameter("email", "a@a.com");
    request.AddParameter("subject", "Test ticket");
    request.AddParameter("description", "Test ticket");
    request.AddParameter("status", "2");
    request.AddParameter("priority", "1");
    IRestResponse response = client.Execute(request);
    Console.WriteLine(response.Content);

    On the -F (source: https://curl.se/docs/manpage.html#-F):

    -F, --form <name=content>

    (HTTP SMTP IMAP) For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388.

    For SMTP and IMAP protocols, this is the means to compose a multipart mail message to transmit.

    This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.

    Tell curl to read content from stdin instead of a file by using - as filename. This goes for both @ and < constructs. When stdin is used, the contents is buffered in memory first by curl to determine its size and allow a possible resend. Defining a part's data from a named non-regular file (such as a named pipe or similar) is unfortunately not subject to buffering and will be effectively read at transmission time; since the full size is unknown before the transfer starts, such data is sent as chunks by HTTP and rejected by IMAP.

    Example: send an image to an HTTP server, where 'profile' is the name of the form-field to which the file portrait.jpg will be the input:

    curl -F profile=@portrait.jpg https://example.com/upload.cgi

  4. alexeyzimarev commented on Feb 11, 2022

    @alexeyzimarev
    Member

    Here's what I did:

    var ticket = new {
        Email       = "test@acme.org",
        Description = "description",
        Subject     = "subject",
        Status      = "status",
        Priority    = "low"
    };
    var client = new RestClient("https://enqvvdg27q3o.x.pipedream.net/");
    
    var request = new RestRequest("tickets", Method.Post)
        .AddFile("test.cs", "test.txt")
        .AddParameter("email", ticket.Email)
        .AddParameter("description", ticket.Description)
        .AddParameter("subject", ticket.Subject)
        .AddParameter("status", ticket.Status)
        .AddParameter("priority", ticket.Priority);
    
    var rs = await client.ExecuteAsync(request);

    And that's how the request looks like:

    image

    It's hard for me to guess what exactly FreshDesk is unhappy about as the request looks completely legit.

  5. alexeyzimarev commented on Feb 11, 2022

    @alexeyzimarev
    Member

    I know what is the issue with FreshDesk API and it has nothing to do with supporting multipart form data parameters as they are supported for many years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions