I have a following situation which I have never seen before. I am using code below to declare a Post action.
[HttpPost]
[Route("")]
public async Task<HttpResponseMessage> Insert(InsertRequest request)
{
var body = await Request.Content.ReadAsStringAsync();
}
Now, when I am sending request to this endpoint using Postman with Content-Type = Application/Json I get some value for request and empty string for body.
If I do PostAsJsonAsync with HttpClient to this endpoint I will get null for request and request content for body.
How is that possible?
To support POST you need to add attribute [FromBody] to the request parameter.
[HttpPost]
[Route("")]
public async Task<HttpResponseMessage> Insert([FromBody] InsertRequest request)
{
var body = await Request.Content.ReadAsStringAsync();
}
Related
I need to accept xml as request body
Here is my controller
[HttpPost]
[Route("UpdateLeaveBalance")]
[ProducesResponseType(typeof(RootLeaveBalanceDto), (int)HttpStatusCode.OK)]
public async Task<IActionResult> CreateOrUpdate([FromBody] RootLeaveBalanceDto model)
{
var result = await _leaveBalanceService.SetLeaveBalance(model);
return OkResult(result);
}
here is the program.cs
services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(GlobalModelStateValidatorAttribute));
}).AddXmlDataContractSerializerFormatters();
I tried using this code i gave but when i set debuger i got no data but the post request gives 200
I have a scenario where http POST request execute, call another get request and return response of get request. Here is my code
public class EmployeeController : ControllerBase
{
private readonly IBusControl _bus;
public EmployeeController(IBusControl bus)
{
_bus = bus;
}
[HttpPost]
public async Task<IActionResult> Emp(EmployeeModel employee)
{
Uri uri = new Uri("rabbitmq://localhost/ret_eligibility");
var endPoint = await _bus.GetSendEndpoint(uri);
await endPoint.Send(employee);
return Ok("Success");
}
[HttpGet]
[Route("getRetFund")]
public IActionResult fund()
{
Fund fund = RetFundConsumer.fund;
return Ok(fund.retfund);
}
}
I want to call getRetFund request in POST request method, So that when employee data is sent to queue using postman, it call second service which consume message and send response back. This response will be shown then in console.
I also have tried the following POST method.
[HttpPost]
public async Task<IActionResult> Emp(EmployeeModel employee)
{
Uri uri = new Uri("rabbitmq://localhost/ret_eligibility");
var endPoint = await _bus.GetSendEndpoint(uri);
await endPoint.Send(employee);
//return Ok("Success");
Fund fund = RetFundConsumer.fund;
return Ok("your retirement fund is " + fund.retfund);
}
But this throw null Exception as it call second service before executing POST request. The response would be greatly appreciated.
This would never work. You need to spend time about both Web API request handling scope and MassTransit message handling scope.
In short, both Web API and MassTransit message handling is scoped to one message. There is no way you can consume a response message, somehow magically keeping the HTTP session open. The consumer gets disposed when it finishes handling a message.
You can do it, though, but you need to use the MassTransit request/response feature.
public class EmployeeController : ControllerBase
{
private readonly IRequestClient<EmployeeModel> _client;
public EmployeeController(IClientFactory clientFactory)
=> _client = clientFactory.CreateRequestClient<EmployeeModel>(
new Uri("rabbitmq://localhost/ret_eligibility"));
[HttpPost]
public async Task<IActionResult> Emp(EmployeeModel employee)
{
var response = await _client.GetResponse<Fund>(employee);
return Ok("your retirement fund is " + fund.retfund);
}
}
Of course, you need to change your consumer accordingly to send a message back. Check the documentation referenced above for the details.
I have created a class that inherit from DelegatingHandler and overwrite the SendAsync method. I wanted to validate the request parameters and encode them with AntiXss class before passing it to the main controller. Therefore, I created this. Now when I call the respective controller via SoapUI, I successfully get into the Async method and gets the request object.
Difficulty
I am not able to fetch the request parameters from the HTTPREQUESTMESSAGE object that I passed from the soap ui. Below is the snapshot of the request
CODE
protected override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
//Encode here the request object
var requestObj= request.GetQueryNameValuePairs()
.ToDictionary(kv => kv.Key, kv => kv.Value,
StringComparer.OrdinalIgnoreCase);
// work on the request
System.Diagnostics.Trace.WriteLine(request.RequestUri.ToString());
return base.SendAsync(requestObj, cancellationToken)
.ContinueWith(task =>
{
// work on the response
var response = task.Result;
response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString());
return response;
});
}
#endregion
}
I just wanted to get the values of the parameters that I passed from the SOAP UI under the object of the HTTPRequestMessage. But not succeeded till now. Any help is appreciated.
After going through certain articles and question I finally got the solution:
var content = request.Content;
string jsonContent = content.ReadAsStringAsync().Result;
The above code worked perfectly
I send async requests to facebook. Each of those requests has field "notofication uri".
When async jobs are all done, this URI will be used to notify the caller with POST action and the id of the object.
I've wrote spring action in controller to obtain that id:
#RequestMapping(value = "/callback", method = RequestMethod.POST
public void asyncRequestSet(#RequestBody String body,
#RequestParam("offer_id") Long offerId,
#RequestParam("user_id") Long userId) {
logger.info("{}", body);
}
Example callback url: http://example.com/callback?user_id=1&offer_id=1
But the body of request is:
--------------------------9c15923bd5bc01ce
Content-Disposition: form-data; name="async_request_set_id"
5011222203926
--------------------------9c15923bd5bc01ce--
How could I get id "5011222203926" without using regex.
The HttpClient custom Client Message Handlers insert themselves in the client-side pipeline when making web api calls. This info is from this article
The author says that these message handlers go into action as the request is being sent out and also when the response is received back from the server.
I understand these client message handler's role as request is being sent out from client to the Server because the sendAsync method provides the request object. One can add custom request headers, etc.
I do not understand the usefulness of these message handlers AFTER the response is received from the server because the sendAsync method does not provide access to the response object. So, I am not sure how these client side message handlers are useful on the return journey of the request.
I am obviously missing something here.
Actually you do get access to the response message inside the message handler. For example, in the following handler, I am logging outgoing request and incoming response. Now as long as I use this instance of HttpClient, all calls made through it write traces of requests and response.
HttpClient client = new HttpClient(new LoggingHandler(new HttpClientHandler()));
public class LoggingHandler : DelegatingHandler
{
public LoggingHandler(HttpMessageHandler innerHandler)
: base(innerHandler)
{
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Console.WriteLine("Request:");
Console.WriteLine(request.ToString());
if (request.Content != null)
{
Console.WriteLine(await request.Content.ReadAsStringAsync());
}
Console.WriteLine();
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
Console.WriteLine("Response:");
Console.WriteLine(response.ToString());
if (response.Content != null)
{
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
Console.WriteLine();
return response;
}
}