Reputation: 53
i have an object "ApplicantDetail" with list of objects in ApplicantController and i want to send Post Request to Personaldetails Api On To save into database and get response back
// POST: api/ApplicantDetail
[HttpPost]
[Route("~/api/ApplicantDetail")]
public IActionResult Post([FromBody] Personaldetail ApplicantDetail)
{
Personaldetail personaldetail = new Personaldetail
{
Name = ApplicantDetail.Name,
Cnic = ApplicantDetail.Cnic,
Phone = ApplicantDetail.Phone
};
List<Address> addresses = new List<Address>();
List<Employee> employees = new List<Employee>();
List<Bank> banks = new List<Bank>();
addresses.AddRange(ApplicantDetail.Address);
employees.AddRange(ApplicantDetail.Employee);
banks.AddRange(ApplicantDetail.Bank);
var response = *//How to Call Personaldetail Post APi of PersonaldetailController Controller From Here and Get
response back//*
return null;
}
// POST: api/Personaldetails
[HttpPost]
public async Task<IActionResult> PostPersonaldetail([FromBody] Personaldetail personaldetail)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Personaldetail.Add(personaldetail);
await _context.SaveChangesAsync();
return CreatedAtAction("GetPersonaldetail", new { id = personaldetail.ApplicantId }, personaldetail);
}
Upvotes: 4
Views: 13446
Reputation: 395
I could see that your target method (PostPersonaldetail) on controller2 (Personaldetail Controller) is an asynchronous method. While we are calling it we need to use the await keyword with async applied to the method (POST: api/ApplicantDetail) as we can't use await keyword in a method with out making the method as async. Alternatively we can apply wait on the method call too.
Controllers are nothing but classes, we can create an instance and call methods defined in it, however it's not a good practice. Using dependency injection we can get references to other services/controllers with in the application and use it to call methods defined on them.
Approach 1:
public async IActionResult Post([FromBody] Personaldetail ApplicantDetail)
{
var response = await new controller2().PostPersonaldetail(persondetails);
}
Approach 2:
public IActionResult Post([FromBody] Personaldetail ApplicantDetail)
{
var response = new controller2().PostPersonaldetail(persondetails).Wait();
}
The following links can be helpful.
Upvotes: 0
Reputation: 17658
If this is within the same process it's unwise to call a controller from another controller.
It's more common to create a class, usually called a service, in which you put your logic to apply the task at hand.
This will have some benifits:
E.g.:
The service:
public class YourService
{
public void YourMethod(parameters)
{
//do your stuff
}
}
The usage:
public class Controller1 : Controller
{
public void YourAction1()
{
//controller specific stuff like model validation
//shared logic
var service = new YourService();
service.YourMethod();
}
}
public class Controller2 : Controller
{
public void YourAction2()
{
//controller specific stuff like model validation
//shared logic
var service = new YourService();
service.YourMethod();
}
}
Alternativly you can use a DI framework to resolve your service.
Upvotes: 3
Reputation: 364
I don't think you want to new up an instance because it could be missing dependencies. You can do something like:
var controller = DependencyResolver.Current.GetService<PostPersonaldetail>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);
Then make the call.
You could also use dependency injection and just have a reference in the controller:
class ApplicantController : ControllerBase
{
public ApplicantController(ControllerB controllerb)
{
_contollerB = controllerB;
}
you may have to add a call to add the transient service:
services.AddTransient<ControllerB>();
Upvotes: -1
Reputation: 239300
You should create a service class to represent the personal details API. In this class, you would inject HttpClient
, and then set up IHttpClientFactory
with a strongly-typed client:
public class PersonalDetailsService
{
private readonly HttpClient _client;
public PersonalDetailsService(HttpClient client)
{
_client = client;
}
// methods here to interact with API via `_client`
}
Then, in ConfigureServices
:
services.AddHttpClient<PersonalDetailsService>(c =>
{
c.BaseAddress = new Uri(Configuration["PersonalDetailsAPIUrl"]);
// configure anything else you need to on the `HttpClient`
});
Finally, in your controller, you inject PersonalDetailsService
:
[ApiController]
[Route("api/ApplicantDetail")]
public class ApplicantController
{
private readonly PersonalDetailsService _personalDetailsService;
public ApplicantController(PersonalDetailsService personalDetailsService)
{
_personalDetailsService = personalDetailsService;
}
[HttpPost("")]
public async Task<IActionResult> Post([FromBody] Personaldetail ApplicantDetail)
{
...
var response = await _personalDetailsService.SomeMethodAsync(someParam);
return null;
}
}
Upvotes: 5