Passing list of int to Web API from RestSharp Client - c#

When I use code below from REST Sharp I am not able to pass listOfSelectedTicketsIds it always null.
Request of Rest Sharp .net Client
var _stDeveloperApi = new RestClient("http://127.0.0.1/");
var url = string.Format("api/v1/SignalR/MultiClickMode");
var listOfSelectedTicketsIds = new List<int> { 2, 3 };
var request = new RestRequest(url, Method.GET);
request.AddParameter("listOfSelectedTicketsIds", listOfSelectedTicketsIds, ParameterType.GetOrPost);
var response = _stDeveloperApi.Execute(request);
Web API Method
[HttpGet]
public HttpResponseMessage MultiClickMode(List<int> listOfSelectedTicketsIds)
{
var response = new HttpResponseMessage();
try
{
}
catch (Exception ex)
{
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
}
return response;
}

Change your client code like this.
var _stDeveloperApi = new RestClient("http://127.0.0.1/");
var url = string.Format("api/v1/SignalR/MultiClickMode");
var listOfSelectedTicketsIds = new List<int> { 2, 3 };
var request = new RestRequest(url, Method.GET);
listOfSelectedTicketsIds.ForEach(t =>
request.AddParameter(
"listOfSelectedTicketsIds", t, ParameterType.GetOrPost));
var response = _stDeveloperApi.Execute(request);
Change the web API action method signature like this.
public HttpResponseMessage MultiClickMode(
[FromUri]List<int> listOfSelectedTicketsIds)

Related

Postman form-data: How to program it inside a HttpRequestMessage?

I am doing a request through postman to a specific url but I set the form-data type in order to get data to the site like this:
Now I want to program this request inside C# but everything I tried so far is returning a 400 Bad Request response. This is what I tried:
public async Task<CheckAccessTokenModel> CheckAccessTokenAsync(string accessToken)
{
string uriString = "someurl";
var uri = new Uri(uriString);
try
{
using(var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = uri
};
var ClientId = ConfigurationAccessor.Configuration["WebCredentials:ClientId"];
var Secret = ConfigurationAccessor.Configuration["WebCredentials:Secret"];
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ClientId}:{Secret}"));
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent("token"), accessToken);
request.Content = content;
var response = await httpClient.SendAsync(request);
var checkTokenResponseData = await response.Content.ReadAsStringAsync();
//return new CheckAccessTokenModel { Active = true, Exp = 1647431224233 };
return JsonConvert.DeserializeObject<CheckAccessTokenModel>(checkTokenResponseData);
}
}
catch
{
return null;
}
}
I am doing it with the MultipartFormDataContent Object as suggested by many others here but it still won't work.
What can be the problem here?
EDIT: Wrong picture replaced
You can simply
request.Content = new StringContent($"token={accessToken}");
With form data I think it's something like this:
var data = new Dictionary<string, string>
{
{"token", acccessToken}
};
using var content = new FormUrlEncodedContent(data);
request.Content = content;

.Net Core 5 Web Api - Swagger POST ok Xunit POST Error

I'm using XUnit to test my WebApi, GET requests are working ok. But when testing a POST through XUnit I received a 404 Bad Request while Swagger returns 200 OK
Teste
[Theory]
[InlineData("POST")]
public async Task ContestCreateTest(string method)
{
var _httpClient = new Setup().httpClient;
var request = new HttpRequestMessage(new HttpMethod(method), "/v1/Contest");
var contestObject = new
{
title = "Concurso automatizado",
description = "Concurso automatizado",
submissionDeadLineInit = TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(1), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"),
submissionDeadLineEnd = TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(2), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"),
ratingDeadLineInit = TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(3), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"),
ratingDeadLineEnd = TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(4), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"),
closingDate = TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(5), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"),
useDistritoRules = true,
rules = ""
};
string contestJson = JsonConvert.SerializeObject(contestObject);
request.Content = new StringContent(contestJson, Encoding.UTF8, "multipart/form-data");
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
As the image shows your API accepts form but you're sending data in json format.
var formDataContent = new MultipartFormDataContent
{
{ new StringContent("Concurso automatizado", Encoding.UTF8), "title"},
{ new StringContent("Concurso automatizado", Encoding.UTF8), "description")},
{ new StringContent(TimeZoneInfo.ConvertTime(DateTime.UtcNow.AddDays(1), TZConvert.GetTimeZoneInfo("America/Sao_Paulo")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'", Encoding.UTF8), "submissionDeadLineInit" },
...
};
// Act
var response = await _client.PostAsync("/v1/Contest", formDataContent);

Simplest way to call REST

I have call to REST service from jscript that works fine:
post('/MySite/myFunct', { ID:22 })
How to make this call from C# in most native c# way?
UPD:
I need HTTPS solution also.
UPD:
And I need to use cookies
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{ "ID", "22" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com", content);
var responseString = await response.Content.ReadAsStringAsync();
Old traditional way is using HttpClient / HttpWebRequest.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/api/Test/TestPostData");
request.Method = "POST";
SampleModel model = new SampleModel();
model.PostData = "Test";
request.ContentType = "application/json";
JavaScriptSerializer serializer = new JavaScriptSerializer();
using (var sw = new StreamWriter(request.GetRequestStream()))
{
string json = serializer.Serialize(model);
sw.Write(json);
sw.Flush();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Apart from this I prefer more Restclient /Restsharp from nuget.
A simple example of post request will be like this
using RestSharp;
using RestTest.Model;
private void button1_Click(object sender, EventArgs e)
{
var client = new RestClient();
var request = new RestRequest();
request.BaseUrl = "http://carma.org";
request.Action = "api/1.1/searchPlants";
request.AddParameter("location", 4338);
request.AddParameter("limit", 10);
request.AddParameter("color", "red");
request.AddParameter("format", "xml");
request.ResponseFormat = ResponseFormat.Xml;
var plants = client.Execute<PowerPlantsDTO>(request);
MessageBox.Show(plants.Count.ToString());
}
You can use HTTP Verbs directly from call
A Post example:
public void Create(Product product)
{
var request = new RestRequest("Products", Method.POST); < ----- Use Method.PUT for update
request.AddJsonBody(product);
client.Execute(request);
}
A Delete Example
public void Delete(int id)
{
var request = new RestRequest("Products/" + id, Method.DELETE);
client.Execute(request);
}
For adding header in request
request.AddHeader("data", "test");
A Get Request
private RestClient client = new RestClient("http://localhost:8080/api/");
RestRequest request = new RestRequest("Products", Method.GET);
RestResponse<YourDataModel> response = client.Execute<YourDataModel>(request);
var name = response.Data.Name;

RestClient returns universal response

I have some code:
public Task<IRestResponse> SendRequest(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest();
request.RequestFormat = DataFormat.Json;
request.Method = Method.POST;
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
client.ExecuteAsync(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
response contains all but not the answer from url (response doesnt' contain Data object). When I specify object for ExecuteAsync:
public Task<IRestResponse<MyClass>> SendRequest(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest();
request.RequestFormat = DataFormat.Json;
request.Method = Method.POST;
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse<MyClass>>();
client.ExecuteAsync<MyClass>(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
public class MyClass
{
public bool ResultCheck { get; set; }
public string Message { get; set; }
}
in response I can find object Data (response.Data) which contains fields with values from url.
For example I receive response with Data: { ResultCheck=true, Message="Result!" }
How can I receive filled Data from url with any object without specifiing type - MyClass. I wan't to receive response with any number of fields for different urls. I want to receive some anonymous object.
One way would be to use Generics and dynamic objects. This should allow you to specify any object type to be converted to a response.
You can therefore change the method to
public Task<IRestResponse<T>> SendRequest<T>(string url, string bodyJson)
{
var client = new RestClient(url);
var request = new RestRequest
{
RequestFormat = DataFormat.Json;
Method = Method.POST;
};
request.AddBody(bodyJson);
var taskCompletionSource = new TaskCompletionSource<IRestResponse<T>>();
client.ExecuteAsync<T>(request, response =>
{
taskCompletionSource.SetResult(response);
});
return taskCompletionSource.Task;
}
Then we can create temp object using dynamic. We can then fill this will all the information we need
// Create temp obj
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
finally at the call site we state the type is dynamic. Hopefully the rest api can forward this onto the client and they can retrieve the object as type dynamic.
SendRequest<dynamic>(url, JsonConvert.SerialiseObject(employee));
The client can then do something like
dynamic response = GetResponse(...);
var name = response.Name;

How to reconstruct return type object in web api

Given that I have the following web api method in my controller
public HttpResponseMessage PostGrantAccess(GrantAccessRequest grantAccessRequest)
{
var deviceId = grantAccessRequest.DeviceId;
var grantAccessResponse = new GrantAccessResponse()
{
Status = "OK"
};
var response = Request.CreateResponse<GrantAccessResponse>(HttpStatusCode.OK, grantAccessResponse);
return response;
}
Client calling code:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:55208/");
var request = new GrantAccessRequest { DeviceId = "bla" };
var response = client.PostAsJsonAsync("api/accesspanel", request).Result;
if (response.IsSuccessStatusCode)
{
var uri = response.Headers.Location;
}
}
How do I get back GrantAccessResponse at the client?
response.Content.ReadAsAsync<GrantAccessResponse>()

Categories