Keywords: ASP.NET MVC | Web API | Controller Invocation
Abstract: This article explores best practices for calling Web API within an ASP.NET MVC project, focusing on the trade-offs between direct invocation and HTTP requests. By refactoring code structure to extract business logic into separate classes, unnecessary serialization overhead and HTTP call latency are avoided. It details optimizing ApiController design using HttpResponseMessage and IEnumerable<QDocumentRecord> return types, with examples of directly invoking business logic from HomeController. Additionally, alternative approaches using HttpClient for asynchronous HTTP requests are provided to help developers choose appropriate methods based on specific scenarios.
Introduction
In projects integrating ASP.NET MVC and Web API, developers often need to call Web API methods from MVC controllers. This article addresses a typical scenario: calling the GetAllRecords method from DocumentsController in HomeController to retrieve a file list for a Razor view. By analyzing the best answer, we explore how to optimize architectural design to avoid unnecessary HTTP calls and serialization overhead.
Problem Analysis
In the original code, DocumentsController returns an HttpResponseMessage containing a JSON-serialized file list. HomeController attempts to fetch this JSON via an HTTP request and deserialize it into a List<QDocumentRecord>. This approach introduces extra overhead, as the Web API and MVC controller are in the same assembly, making direct invocation of business logic more efficient.
Optimization Solution: Refactoring Business Logic
The best practice is to extract file retrieval logic into a separate class, preventing controllers from containing business code. For example:
public class FileService
{
public IEnumerable<QDocumentRecord> GetAllRecords()
{
// File retrieval logic
return listOfFiles;
}
}This allows both DocumentsController and HomeController to call FileService, ensuring code reuse and separation of concerns.
Improving ApiController Design
If an ApiController must be used, optimize the return type. Avoid manual JSON serialization by leveraging Web API's built-in features:
public class DocumentsController : ApiController
{
public HttpResponseMessage GetAllRecords()
{
var listOfFiles = new FileService().GetAllRecords();
return Request.CreateResponse<IEnumerable<QDocumentRecord>>(HttpStatusCode.OK, listOfFiles);
}
}Or directly return IEnumerable<QDocumentRecord>, letting the framework handle serialization:
public IEnumerable<QDocumentRecord> GetAllRecords()
{
return new FileService().GetAllRecords();
}MVC Controller Implementation
In HomeController, directly invoke FileService to avoid HTTP requests:
public class HomeController : Controller
{
public ActionResult Index()
{
var files = new FileService().GetAllRecords();
return View(files);
}
}This method simplifies code, improves performance, and enhances maintainability.
Alternative Approach: HTTP Request Invocation
If the Web API is deployed as a separate service, use an HTTP client. For example, use HttpClient for asynchronous calls:
public async Task<ActionResult> Index()
{
string apiUrl = "http://localhost:58764/api/documents";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(apiUrl);
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
var files = JsonConvert.DeserializeObject<List<QDocumentRecord>>(json);
return View(files);
}
}
return View(new List<QDocumentRecord>());
}This method suits distributed systems but adds latency and complexity.
Performance and Architectural Considerations
Direct invocation of business logic classes is significantly faster than HTTP requests, as it avoids network latency and serialization overhead. In monolithic applications, shared service classes are recommended; in microservices architectures, HTTP calls may be more appropriate. Developers should choose based on project requirements.
Conclusion
By refactoring code to extract business logic into separate classes, Web API functionality can be efficiently called from MVC controllers. Optimizing ApiController design simplifies serialization using framework features. For cross-service communication, use HttpClient for asynchronous HTTP requests. These strategies enhance code maintainability, performance, and scalability.