ASP.NET authorization using RestSharp - asp.net-web-api

On the site "example.net" I have standart api method to take access token (which i can call /Token) and if I make POST request using Fiddler to example.net/Token with parameters in request body
And all is OK. Status code 200 and in the response access token and other info.
But if I do this request from other site using RestSharp - 500 Internal Server Error. I tried to AddParameter, AddBody, AddObject. Make parameters as a JSON string, to change DataFormat, to AddHeader of Content-Type. This is my last version of request.
request = new RestRequest(URL, Method.POST);
//request.AddHeader("Content-Type", ContentType);
string UrlEncoded = "";
//I parse Parameters to format like I use in request body in Fiddler.
if (Parameters.Count != 0)
foreach (var param in Parameters)
UrlEncoded = param.ParamToUrlEncoded(UrlEncoded);
request.AddBody(UrlEncoded);
IRestResponse response = client.Execute(request);
var content = response.Content;
Do i need to set any more attributes on the request or something?
Thank you.

Related

Is there a way to map local in proxyman based off of parameters attached to the body of a url?

I have a url:
https://cn.company.com/appv2/search
and want to have a different map local depending on the request coming with a different parameter in the body (i.e. it is NOT attached to the url like https://cn.company.com/appv2/search?cursor=abc. Instead it is in the body of the request { cursor: abc }.
Any idea on if this can be done in proxyman?
I basically want to be able to stub pagination through the proxy without waiting on a server implementation. So I'd have no cursor on the first request, server would return a cursor and then use that on the next request and get a different response from server on the request so that I can test out the full pagination flow.
Yes, it can be solved with the Scripting from Proxyman app.
Use Scripting to get the value of the request body
If it's matched, use Scripting to mimic the Map Local (Mock API also supports)
Here is the sample code and how to do it:
Firstly, call your request and make sure you can see the HTTPS Response
Right-Click on the request -> Tools -> Scripting
Select the Mock API checkbox if you'd like a Mock API
Use this code
/// This func is called if the Response Checkbox is Enabled. You can modify the Response Data here before it goes to the client
/// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string)
///
async function onResponse(context, url, request, response) {
// get the value from the body request
var cursorValue = request.body["cursor"];
// Use if to provide a map local file
if (cursorValue === "abc") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_A.json";
} else if (cursorValue === "def") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_B.json";
}
// Done
return response;
}
Reference
Map Local with Scripting: https://docs.proxyman.io/scripting/snippet-code#map-a-local-file-to-responses-body-like-map-local-tool-proxyman-2.25.0+

.net core 3 status code 405 in response when using httpClient and Fiddler?

Why am I getting status code 405 in response when using httpClient or Fiddler?
I am getting a status code 405 response when tyring to access a net core 3.1 wepapi action method that accepts json string sent in the body as shown below.
The status code 405 occurs when the request is sent in a net core 3.1 console app using httpClient.
In Fiddler the request works fine.
The webapi action code is
[RequireHttps]
[HttpPut("setkdatainformation/{id:int:min(0):max(5)}/{info}")]
[Authorize(Roles = "Admin")]
public async Task<string> SetKDataInformation(int id, string info, [FromBody] string kinfo)
{
The request is sent from a .net core 3.1 console app using http client as shown below
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue($"application/json"));
var dData = $"{q}kdata test{q}";
var content = new StringContent(dData, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PutAsync(${url}api/v1.0/KDataServer/setkdatainformation/{connectionId}/{headerLoginName}", content);
The status code 405 occurs when the request is sent in a net core 3.1 console app using httpClient.
I did a test based on the code snippet you shared, which work well on my side. If possible, you can try to create a new project and create controller with only this action method then test if it can work well.
var q = "\"";
var connectionId = 2;
var headerLoginName = "test";
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue($"application/json"));
var dData = $"{q}kdata test{q}";
var content = new StringContent(dData, System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PutAsync($"https://xxxx/setkdatainformation/{connectionId}/{headerLoginName}", content);
In Fiddler the request works fine
You mentioned the request could be processed fine if you make it via fiddler, to troubleshoot the issue, you can capture the request that you sent from console app using fiddler, then compare the request url, header(s) and body etc with that working one you sent through fiddler and make sure you are making request(s) to same endpoint from both fiddler and console app.

How i can make a http get request in genexus?

I'm trying to make a http get request in genexus, but in the object httpclient i can't find the property that have the answer and the method Execute() don't return the response of the request.
I need to copulate the json response in one SDT.
I try something like:
&httpClient = new()
&httpClient.BaseUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + &LocalLatitudeA + ',' + &LocalLongitudeA + '&key=xxxxxxxxxxxxx'
&httpClient.Execute('GET', &httpClient.BaseUrl)
You can do this to retrieve data from an HTTP endpoint and load a SDT with the result:
&HttpClient.Execute(!"GET", !"https://reqres.in/api/users?page=2")
&Users.FromJson(&HttpClient.ToString())
&HttpClient.ToString() returns the response as a string, and &Users.FromJson() loads the &Users SDT with the received data.

How to retrieve all requested params in .NET Web API 2?

If I want to konw what has been sent through my service, how can I get all the request parameters in Web Api2 Controller as what Request.Form.ToString() get in aspx or ashx?
The Request object is just not the Httpcontext.Request...
public HttpResponseMessage Post(HttpRequestMessage req)
{
var content = req.Content.ReadAsStringAsync().Result;
return null;
}
Also note that the request body is a non-rewindable stream; it can be read only once, you can't call ReadAsStringAsync() multiple times.

Do Get request with a complex type parameter in the request body with web api

I want to do an integration test for the below action.
How can I pass my requestDto object in the integration test?
Neither the GetAsync nor SendAsync method has an overload parameter to pass a custom object to the server.
[Route("{startDate:datetime}")]
[HttpGet]
public HttpResponseMessage Get(DateTime startDate, [FromBody]LessonplannerGetRequest request)
{
request.StartDate = startDate;
var lessonplannerResponse = _service.GetPeriodsByWeekStartDate(request);
return Request.CreateResponse<LessonplannerResponse>(HttpStatusCode.OK, lessonplannerResponse);
}
[Test]
public void Get_Lessons_By_Date()
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");
var myRequestDto = new LessonplannerGetRequest();
// Act => QUESTION: HOW do I pass the myRequestDto ???
var response = _client.SendAsync(request, new CancellationToken()).Result;
// Assert
Assert.That(response.StatusCode == HttpStatusCode.OK);
}
UPDATE
As Darrel Miller said:"Technically HTTP says you can send a body, it just says the body doesn't mean anything and cannot be used. HttpClient won't let you send one."
I post here my integration test with HttpClient doing a Get request with complex type + FromBody:
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");
var myRequestDto = new LessonplannerGetRequest{ FirstDayOfWeek = DayOfWeek.Sunday, SchoolyearId = 1, StartDate = DateTime.Today};
request.Content = new ObjectContent<LessonplannerGetRequest>(myRequestDto, new JsonMediaTypeFormatter());
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Act
var response = _client.SendAsync(request, new CancellationToken()).Result;
// Assert
Assert.That(response.StatusCode == HttpStatusCode.OK);
Of course is this is not the Http way some might consider doing it differentlly sending complex type via FromUri/query string.
HTML specifications says you cannot send a GET with a body.
HTTP specs allows it.
WebAPI allows it, because it is a service/REST and implements HTTP but not HTML, but many clients and browser won't allow it because they implement both specs and try to be strict.
As for the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) itself, it states:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
(e.g. if you do a <form> with GET, it will parse all the form params and set them in the query string ?a=b).
In term of pure HTTP and in the context of REST services, nothing prevents that behavior, but not all clients will be able to handle it. It's mostly a best-practice advise when it comes to REST/WebAPI to not handle body data from HttpGet, only URI data (the opposite, POST /action?filter=all is usually tolerated for metadata/action qualifiers, but that's another discussion).
So yeah, it's at your own risk, even if used only internally. As not all clients handle it (e.g. HttpRequestMessage), so you might run into trouble like you have.
You should NOT pass a GET body with HTTPClient.

Resources