Search code examples
c#jsonserializationxamarin.formsrefit

How do I serialize my class to send it as urlencoded with refit


Hi there I'm trying to send a POST method with refit, using postman so far I can say it's working, if I send the data with the x-www-form-encoded option, the json I send looks like this

{
  "apt": "APT",
  "apartment": "A103",
  "author": "Someone",
  "is_public": "True",
  "is_complaint": "True",
  "show_name": "True",
  "title": "fhj",
  "details": "vvkko"
}

I constructed my class in visual studio and my model to match it pasting that to json

namespace App.Models
{
    public class ManyComplaints
    {
        public SingleComplaint data { get; set; }
    }
    public class SingleComplaint
    {
        public string apt { get; set; }
        public string apartment { get; set; }
        public string author { get; set; }
        public string is_public { get; set; }
        public string is_complaint { get; set; }
        public string show_name { get; set; }
        public string title { get; set; }
        public string details { get; set; }
    }

}

Here I'm not sure if I did right it's my api caller

 [Headers("Content-Type: application/x-www-form-urlencoded")]
 [Post("/api/complaints/")]
 Task SubmitComplaint([Body(BodySerializationMethod.UrlEncoded)]SingleComplaint complaint);

And in this is the code that's sending the data

public async Task Post()
{
    SingleComplaint data = new SingleComplaint 
    {
        is_public = ShowPost,
        is_complaint = Complaint,
        show_name = ShowName,
        author = Preferences.Get("UserName", null),
        apt0 = Preferences.Get("Apt", null),
        apartment = Preferences.Get("Apartment", null),
        title = TitleEntry.Text,
        details = DetailsEntry.Text
    };

    try
    {                
        var myApi = RestService.For<IApiService>(Constants.webserver);
        var serialized = JsonConvert.SerializeObject(data);
        ManyComplaints complaint = await myApi.SubmitComplaint(data);
        await DisplayAlert("Thanks", "Your message has been succesfully delivered", "Ok");
    }
    catch (Exception ex)
    {
        await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "Ok");
    }
}

Tried to use the line as string complaint = await myApi.SubmitComplaint(serialized); and also change that as string instead of the ManyComplaints class, also tried to change the model as just the singlecomplaints but I couldn't get it to work, what I'm I missing or how do I make it work?


Solution

  • This answer might have come very late. But recently I was working on a similar use case. And the below code worked for me.

    API Declaration (using Refit)

    [Headers("Content-Type: application/x-www-form-urlencoded")]
    [Get("")]
    public HttpResponseMessage GetData([Body(BodySerializationMethod.UrlEncoded)] FormUrlEncodedContent content);
    

    Calling the API

    List<KeyValuePair<string, string>> contentKey = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("apt", "APT"),
        new KeyValuePair<string, string>("apartment", "A103"),
        new KeyValuePair<string, string>("author", "Someone")
    };
    
    FormUrlEncodedContent content = new FormUrlEncodedContent(contentKey);
    
    HttpResponseMessage response = someClass.GetData(content);