You can also find all 100 answers here π Devinterview.io - ASP.NET Web API
ASP.NET Web API is a lightweight, framework that's integrated with ASP.NET MVC to create RESTful HTTP services, reaching a broad range of client devices. Utilizing ASP.NET Web API is an adept selection to serve the specific needs of your web application.
- Data Services: It's perfect for applications that need to expose and manipulate data over the web.
- Mobile Applications: Ideal for back-end support of multi-platform applications, especially REST APIs.
- Single Page Applications (SPAs): Effortlessly integrate with modern JavaScript frameworks for SPAs.
- Real-time Applications: Services like signalR provides real-time communication. Web API can be used to build a real-time API, which apps can consume for real-time data.
- Ease of Development: Utilizes familiar features from ASP.NET, rendering it simpler to develop.
- Loose Coupling: Supports HTTP services, forming a loosely coupled framework.
- Robust Routing: Employs in-depth routing mechanisms for HTTP requests.
- Content Negotiation: Automatically selects the most fitting response format.
- Model Binding: Directly binds incoming HTTP requests to the specified model or action parameters.
- Action Results: Provides numerous kinds of action results for handling different responses.
- Authentication: Offers multiple levels of data access security.
- Testing: Facilitates direct testing of the API in a dedicated test client.
The standard GET operation for a Web API controller to retrieve a product list from a server:
publicIEnumerable<Product>GetProducts(){returnproductsRepository.All;}
The code snippet below displays the creation of an ASP.NET Web API controller.
publicclassProductsController:ApiController{publicIEnumerable<Product>GetProducts(){returnproductsRepository.All;}publicProductGetProductById(intid){returnproductsRepository.Find(id);}publicHttpResponseMessagePostProduct(Productproduct){productsRepository.Add(product);varresponse=Request.CreateResponse(HttpStatusCode.Created,product);stringuri=Url.Link("DefaultApi",new{id=product.Id});response.Headers.Location=newUri(Request.RequestUri,uri);returnresponse;}publicvoidPutProduct(intid,Productproduct){product.Id=id;if(!productsRepository.Update(product)){thrownewHttpResponseException(HttpStatusCode.NotFound);}}publicvoidDeleteProduct(intid){productsRepository.Remove(id);}}
- ASP.NET Web API, an adaptable framework, excels in developing RESTful services for a wide array of consumer devices, applications, and platforms.
- Its robust protocol support and manifold libraries ensure the best possible service for developers who seek to implement modern web service principles.
ASP.NET Web API, WCF, and ASP.NET MVC are all web frameworks with distinct purposes and target audiences.
- Purpose: Designed for building HTTP services accessed by various clients, including browsers and mobile devices.
- Data Format: Typically deals with JSON, offering flexibility in handling data formatting. It can convey data through XML as well.
- Routing: Emphasizes RESTful services; routes often mirror the structure of resources.
- State Management: Functions independently of View State, implementing statelessness.
- Purpose: Intended for web application development, targeting browsers as the primary client.
- Data Format: Directs data flow to Views, which typically receive data in ViewModel classes. While it can implement AJAX for JSON, it is more oriented toward HTML,
- Routing: Capable of supporting both RESTful routing and more traditional URL-based routing.
- State Management: Utilizes View State for maintaining state during requests.
- Purpose: Focused on building distributed systems using various communication protocols, of which HTTP is just one.
- Data Format: Offers diversified data encodings and supports data contracts for tailoring message formats.
- Routing: Provides more extensive routing capabilities, suitable for diverse communication strategies.
- State Management: Features comprehensive state management tools, such as session handling.
When it comes to building modern, HTTP-centric applications, ASP.NET Web API is usually the go-to platform. For scenarios necessitating robust message-level control and support for numerous communication protocols, WCF is the better choice. If your aim is to construct web applications that primarily interact with browsers and emphasize data-driven Views, ASP.NET MVC remains a strong contender.
ASP.NET Web API acts as a communication bridge between clients and servers through RESTful services, offering a web-friendly framework for data manipulation.
REST establishes a set of constraints that focus on stateless connections and standardized operations across resources. Services are accessed via the standard HTTP methods:
- GET: Retrieve data.
- POST: Submit new data.
- PUT: Update existing data.
- DELETE: Remove data.
Resources such as APIs are identified by Uniform Resource Identifiers (URIs), serving as unique "addresses" for each resource.
Standard HTTP verbs define basic operations. GET retrieves data, POST creates new records, PUT updates them, and DELETE removes them.
Data within a service is represented in a format, such as JSON or XML.
- Attribute-Based Routing: The framework lets developers define URI structures through attributes.
- Model Binding: Automatically extracts parameters from the request, enhancing ease of use.
- Content Negotiation: Allows for dynamic response formatting based on client needs, enabling multiple output formats like JSON or XML.
- ActionResult: A flexible return type that simplifies response handling, e.g., returning different HTTP status codes.
In this example, a music library supports all standard CRUD (Create, Read, Update, Delete) operations.
publicclassMusicController:ApiController{privateList<Music>musics=newList<Music>();// GET: api/MusicpublicIEnumerable<Music>GetAll(){returnmusics;}// GET: api/Music/5publicMusicGet(intid){returnmusics.FirstOrDefault(m =>m.Id==id);}// POST: api/MusicpublicIHttpActionResultPost(Musicmusic){musics.Add(music);returnCreatedAtRoute("DefaultApi",new{id=music.Id},music);}// PUT: api/Music/5publicvoidPut(intid,Musicmusic){varexisting=musics.FirstOrDefault(m =>m.Id==id);if(existing!=null){existing=music;}}// DELETE: api/Music/5publicIHttpActionResultDelete(intid){varmusic=musics.FirstOrDefault(m =>m.Id==id);if(music!=null){musics.Remove(music);returnOk();}returnNotFound();}}publicclassMusic{publicintId{get;set;}publicstringTitle{get;set;}publicstringArtist{get;set;}publicintDuration{get;set;}}
Note: This is a highly simplified example. In a production scenario, a service like this would be backed by an actual data store or database.
Here is the ASP.NET Razor form:
publicIActionResultIndex(){returnView();}
- For GET, detail of all music objects can be obtained from the service by calling
GET: /api/Music
. - For POST, new
Music
objects can be added by callingPOST: /api/Music
with the details of the object in the request body. - For PUT, the ID of the existing
Music
object is specified in the URL, and the updatedMusic
object is sent in the request body, using URI path segment (/api/music/5
) and the HTTP methodPUT
. - For DELETE, the ID of the
Music
object to be deleted is specified in the URL, using the URI path segment and the HTTP methodDELETE
.
The ApiController
s actions are automatically routed based on the HTTP method and the structure of the requested URI.
For example, if a client sends an HTTP GET request to /api/music/5
, the framework will invoke the Get
action method on the MusicController
, passing the id
value of 5
from the request URI. Similarly, if a client sends a POST request to /api/music
, the framework will invoke the Post
method, and so on.
HTTP Verbs, also known as methods, dictate the type of action to be taken on a resource by a web server or Web API. They convey semantical meanings and operate on standard CRUD operations.
- GET: Fetches one or more resources.
- POST: Creates new resources, often with server-defined IDs.
- PUT: Updates an existing resource or creates a new one.
- PATCH: Partially updates an existing resource.
- DELETE: Removes the specified resource.
Here is the C# code:
usingSystem.Net;usingSystem.Web.Http;publicclassProductsController:ApiController{// GET /api/productspublicIHttpActionResultGet(){// Retrieve and return all products.}// GET /api/products/5publicIHttpActionResultGet(intid){// Retrieve and return the product with the specified ID.}// POST /api/productspublicIHttpActionResultPost(Productproduct){// Create a new product using POST data and return its location.returnCreatedAtRoute("DefaultApi",new{id=product.Id},product);}// PUT /api/products/5publicIHttpActionResultPut(intid,Productproduct){if(id!=product.Id)returnBadRequest("ID mismatch");// Update the product with the specified ID.}// PATCH /api/products/5publicIHttpActionResultPatch(intid,Delta<Product>product){// Apply partial updates to the product with the specified ID.}// DELETE /api/products/5publicIHttpActionResultDelete(intid){// Delete the product with the specified ID.}}
To create a Web API controller, you need to follow these steps:
Use the Right Class Attribute The
ApiController
attribute is essential to differentiate a regular controller from a Web API controller.Define Class and Methods Use methods like
Get
,Post
,Put
, andDelete
to map HTTP verbs to controller actions.Code Example: Web API Controller
Here is the C# code:
usingSystem.Collections.Generic;usingSystem.Web.Http;publicclassProductsController:ApiController{// GET: api/ProductspublicIEnumerable<string>Get(){returnnewstring[]{"product1","product2"};}// GET: api/Products/5publicstringGet(intid){return"product with ID "+id;}// POST: api/ProductspublicvoidPost([FromBody]stringvalue){// add a product}// PUT: api/Products/5publicvoidPut(intid,[FromBody]stringvalue){// update a product}// DELETE: api/Products/5publicvoidDelete(intid){// delete a product}}
Routing in ASP.NET Web API enables you to map HTTP requests to specific Controller and Action methods, much like traditional MVC routing. It typically uses the WebApiConfig
and benefits from attribute-based routing.
Controller Route: The route to the entire controller. This is set up in the
WebApiConfig.cs
file.Example:
api/{controller}/{id}
. In URI it would look like:/api/products/10
.Action Route: The route specific to an action method. This is configured via attributes on the action methods.
Example:
[HttpGet("action/{id}")]
. In URI it would look like/api/products/action/10
.HTTP Verb & Route: Both the HTTP Verb and the route need to match for the request to be dispatched to the corresponding action.
Example:
[HttpGet("specificAction/{id}")]
.Default Values: They are useful for providing defaults for route parameters and differentiating the route from others.
Example:
[HttpGet("actionWithDefault/{id:int=5}")]
.Additional Constraints: These can be added to route parameters for value pattern matching and are especially useful for avoiding ambiguity between different routes.
Example:
[Route("{id:int:range(1, 10)}")]
.Route Prefix: This is used via the
[RoutePrefix]
attribute at the controller level. It allows you to set up a common route prefix for all action methods within the controller. This is often used for versioning.Example:
[RoutePrefix("api/V2/products")].
- Default: All action methods within the controller will use this default route.
- Custom: You can use the
[Route]
attribute to specify a custom route for the entire controller.
- Custom: Assign a custom route to the action method by using the
[Route]
attribute. - Override: Using the
[Route]
attribute provides the ability to override any route conventions set at the controller level.
Here are the code examples:
Controller class:
[RoutePrefix("api/products")]publicclassProductsController:ApiController{//Matches GET api/products/1[Route("{id:int:min(1)}")]publicHttpResponseMessageGetProduct(intid){}//Matches GET api/products/category/123[Route("category/{id}")]publicHttpResponseMessageGetByCategory(stringid){}[HttpGet]publicList<Product>GetAllProducts(){}}
WebApiConfig.cs
:
publicstaticclassWebApiConfig{publicstaticvoidRegister(HttpConfigurationconfig){config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name:"DefaultApi",routeTemplate:"api/{controller}/{id}",defaults:new{id=RouteParameter.Optional});}}
In ASP.NET Web API, actions are identified using combination of HTTP method and request URL.
Web API action selection occurs in two stages:
- Mapping to Resource: The request URL, including query string, if any, is used to route to a particular resource.
- Mapping to Action: The HTTP verb (GET, POST, etc.) of a request further directs the routing to a specific action on the resource.
This two-tiered approach is designed to mirror the RESTful resource structure and the HTTP method semantics.
Web API leverages the powerful ASP.NET routing engine to parse the request URL and match the URL against a Route Table to identify the relevant resource.
Web API supports both attribute-based and conventional routes for mapping URL segments to actions and controllers.
- Attribute Routing: Methods are adorned with
[Route]
attributes, explicitly defining the URL template. - Conventional Routing: URL paths are matched using a set of conventions.
While Attribute Routing provides more granular control, Conventional Routing is often simpler to set up.
Here is the C# code:
publicclassEmployeesController:ApiController{[Route("api/employees/{id}")]publicEmployeeGetEmployee(intid){// Retrieve employee based on ID}[Route("api/employees")]publicIEnumerable<Employee>GetEmployees(){// Retrieve all employees}[Route("api/employees")]publicIHttpActionResultPostEmployee(Employeeemployee){// Add new employee}}
Content negotiation and media type formatter together allow ASP.NET Web API to serve multiple responses based on the requesting client's preferences. Content negotiation also permits matching requested media types to the configured formatters and serializing the response data accordingly.
You can choose between two approaches for content negotiation: media type mapping and accept headers.
This straightforward method associates a media type with its corresponding JsonFormatter
or XmlFormatter
:
- Pros
- It's simple and explicit.
- Useful when clients cannot or do not provide
Accept
headers.
- Cons
- It can't handle complex client requests that involve
q-values
(quality values indicating client preferences).
- It can't handle complex client requests that involve
This approach uses HTTP Accept
headers sent by the client:
- Pros
- It can handle more advanced client preferences.
- Cons
- Requires client support.
Here is the C# code:
The MapHttpRoute
method specifies:
- routeTemplate: The URI to handle (
api/products/{id}
) - defaults object: the route's default values, including the controller (
Products
).
The config.Formatters.JsonFormatter
and config.Formatters.XmlFormatter
lines handle media type formatting for JSON and XML, respectively.
publicstaticvoidRegister(HttpConfigurationconfig){// Web API configuration and servicesconfig.MapHttpRoute(name:"DefaultApi",routeTemplate:"api/{controller}/{id}",defaults:new{id=RouteParameter.Optional});// Remove the XML formatterconfig.Formatters.Remove(config.Formatters.XmlFormatter);}
ASP.NET Web API primarily operates with JSON and XML data formats. While JSON is more common due to its lighter-weight and growing popularity, both formats offer distinct advantages.
- Simplicity: Ideal for fast and straightforward data transfer.
- Data-Type Flexibility: Values can be strings, numbers, arrays, or objects.
- Readability: Human-readable and easily parsed.
- Data Structure: Especially suited for intricate data hierarchies due to its tree-like structure.
- Data Verification: XML supports schemas for automatic data verification.
- Support for Unstructured Data: XML can handle unstructured datasets better than JSON.
Ensuring security for your Web API is crucial for safeguarding the data and resources it exposes.
Authentication: Verify the identity of the client making the API request. Common methods include:
- HTTP Basic Authentication: Employing a username and password, but it's less secure as credentials travel with every request.
- Token-based Authentication: Using a short-lived token (such as JWT) that the client presents with each request. This is preferred for stateless and mobile applications. The token can be obtained through a separate authentication process.
- Auth0, IdentityServer, or Custom Providers: Advanced platforms or custom solutions that offer various authentication methods and workflows.
Authorization: After authenticating the client, ensure they have the necessary permissions to access specific resources. Common strategies include:
- Role-Based Access Control (RBAC): Define roles such as 'admin', 'user', and 'guest'. Each role has specific permissions.
- Attribute-Based Access Control (ABAC): Access is determined based on attributes (such as user age or region) rather than predefined roles.
Data Protection: Ensure the confidentiality and integrity of the data transmitted. This can be achieved using HTTPS.
IP Whitelisting: For added security, limit API access to specific IP addresses or IP ranges.
publicvoidConfigureServices(IServiceCollectionservices){services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{options.TokenValidationParameters=newTokenValidationParameters{ValidateIssuer=true,ValidateAudience=true,ValidateLifetime=true,ValidateIssuerSigningKey=true,ValidIssuer=Configuration["Jwt:Issuer"],ValidAudience=Configuration["Jwt:Audience"],IssuerSigningKey=newSymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))};});}[Authorize][ApiController][Route("api/[controller]")]publicclassValuesController:ControllerBase{// Controller actions}
In this example, the [Authorize]
attribute specifies that only authenticated requests are allowed. The AddJwtBearer
method configures JWT token validation parameters.
When it comes to hosting an ASP.NET Web API application, the main options include IIS, Self-Hosting, and Cloud Platforms.
- Benefits: Easy to Secure, Well-Integrated with Windows Identity Foundation, and Offers GUI Management Tools.
- Considerations: Requires Admin Rights, Only Available on Windows Servers, May Have Performance Overhead.
- How?: Simply create a Web API application using Visual Studio and then deploy it on an IIS server. Configure web.config settings based on the server environment.
- Benefits: Can Be Hosted on Non-Windows Platforms, Such as Linux, or Embedded Systems, Does Not Require Admin Rights.
- Considerations: Manual Management Needed, Requires Sufficient System Resources for Ensured Uptime, a Bit Risky for Production Environments.
- How?: Use
Owin
orWebListener
to self-host. The application can be kept running through theHttpSelfHostServer
. Ensure server resources are sufficient to keep the application running without interruptions.
- Benefits: Scalability, High Availability, Reduced Maintenance, Multi-Region Deployment for Global Accessibility.
- Considerations: May Increase Dependency on Provider, Data Location and Compliance Issues, Requires Internet Connectivity.
- How?: Deploy on cloud platforms such as Microsoft Azure or AWS by creating cloud services or using container technologies like Kubernetes and Docker. Cloud platforms often have integration with VS for easy deployments. Just select the Cloud platform in Visual Studio Publishing wizard and it will handle the deployment steps.
OWIN (Open Web Interface for .NET) is a standard for creating web servers and web applications. Unlike traditional web servers, OWIN applications are decoupled from the server hosting them.
Katana is the OWIN-compliant middleware from Microsoft that enables web applications and hosts to communicate using standard interfaces.
- Middleware: Core OWIN component that processes HTTP requests.
- Application: Comprises the middleware pipeline and processes these requests.
- Server: Listens for HTTP requests and passes them to the OWIN application.
- Flexibility: Middleware is interchangeable, allowing for ecosystem freedom.
- Scalability: Performant servers and web applications are possible due to OWIN's streamlined interface.
OWIN empowers Web API with modularity and more streamlined request handling.
Web API 2 and ASP.NET Identity benefit from OWIN integration.
- Simplified configuration thanks to OWIN startup classes.
- Enhanced request/response pipeline control via middlewares.
While OWIN is the interface specification, Katana is a concrete implementation by Microsoft. It most notably introduces several OWIN components :
- Microsoft.Owin.dll: Provides OWIN core libraries.
- Microsoft.Owin.Hosting.dll: Enables hosting in different environments.
- Microsoft.Owin.Host.HttpListener.dll: A simple self-hosting option using the
HttpListener
class.
Here is the C# code:
usingOwin;publicclassStartup{publicvoidConfiguration(IAppBuilderapp){app.UseWelcomePage();}}
When deploying a Web API, you have the option of self-hosting it using a custom application or using the more common IIS hosting. Each approach has its unique advantages and considerations.
In this approach, you bypass IIS and run the Web API through a custom process.
- Platform Independence: It can be run on any host supporting the .NET framework.
- Complete Control: You can perform finer configuration and monitoring tailored to your application.
- Portability: Useful for packing up an application into a private, self-executable unit.
- Maintenance Responsibility: You are accountable for the application's lifetime and resource management.
- Missing IIS Features: Some services offered by IIS, such as load balancing, aren't available.
- Security Configuration: You need to manage security context for the application manually.
Here is the C# code:
publicclassProgram{staticvoidMain(){using(WebApp.Start<Startup>("http://localhost:9000")){Console.WriteLine("Web API hosted on http://localhost:9000/");Console.ReadLine();}}}publicclassStartup{publicvoidConfiguration(IAppBuilderappBuilder){varconfig=newHttpConfiguration();config.Routes.MapHttpRoute("default","{controller}/{id}",new{id=RouteParameter.Optional});appBuilder.UseWebApi(config);}}
In IIS hosting, the Web API runs as part of the IIS worker process. This means it's managed by IIS in several ways.
- Enhanced Security: IIS takes care of security features, allowing you to concentrate on developing API logic.
- Configurable: Configuration settings, such as load balancing and scaling, can be easily managed through IIS.
- IIS Dependency: This restricts the environment to Windows servers with IIS installed.
- Less Customization: Fine-tuned customizations, especially for monitoring, can be more complex.
C# Code for Web API:
[Route("api/[controller]")][ApiController]publicclassValuesController:ControllerBase{[HttpGet]publicIEnumerable<string>Get(){returnnewstring[]{"value1","value2"};}}
Configure IIS for Web API:
- Create a new website in IIS.
- Point the website to the Web API project's root folder.
- Ensure the Application Pool selected for the API is at least .NET 4.5 Integrated.
Cross-Origin Resource Sharing (CORS) is essential for secure, client-server communication in web applications, especially when dealing with resources from different origins.
In the context of ASP.NET Web API, enabling CORS involves a few steps.
Install the
Microsoft.AspNet.WebApi.Cors
NuGet package to your project if not already installed.Install-Package Microsoft.AspNet.WebApi.Cors
Configure CORS in Web API: You can do this in either WebApiConfig.cs or directly in the controller.
Here is the C# code:
publicstaticclassWebApiConfig{publicstaticvoidRegister(HttpConfigurationconfig){varcors=newEnableCorsAttribute("http://localhost:8080","*","*");config.EnableCors(cors);// Other Web API configuration code...}}
or directly in the controller:
[EnableCors(origins:"http://example.com",headers:"*",methods:"*")]publicclassYourController:ApiController{// Controller methods...}
Let me know if you are looking for a specific one.
Test Your CORS Configuration: After making necessary changes, consider testing the server's CORS configuration using a web client such as Postman, cURL, or a browser console.
Attribute routing enables you to define Web API routes directly in the controller with attributes, giving you a more tailored, readable, and maintainable Web API infrastructure.
Traditional Web API route configuration relies on centralized route mapping, typically defined in a separate RouteConfig
file or within the WebApiConfig
file.
While this approach is both familiar and easy to set up, it can become cumbersome as your application scales. Attribute routing offers improved flexibility, granular control, and maintenance simplicity by allowing for route-to-action mapping at the method level, directly within the controller, using intuitive and dedicated attributes.
- RoutePrefix: Serves as a prefix for all routes defined within a specific controller. This makes it easy to group related actions under a shared route segment.
- Route: Marks individual actions with specific route templates.
Here is the controller code:
[RoutePrefix("api/books")]publicclassBooksController:ApiController{// Route will be: api/books[Route("")]publicIHttpActionResultGetBooks(){/* ... */}// Route will be: api/books/5[Route("{id:int}")]publicIHttpActionResultGetBookById(intid){/* ... */}// Route will be: api/books/5/author[Route("{id:int}/author")]publicIHttpActionResultGetBookAuthor(intid){/* ... */}// Route will be: api/books[Route("")]publicIHttpActionResultPostBook([FromBody]Bookbook){/* ... */}// Route will be: api/books/5[Route("{id:int}")]publicIHttpActionResultPutBook(intid,[FromBody]Bookbook){/* ... */}// Route will be: api/books/5[Route("{id:int}")]publicIHttpActionResultDeleteBook(intid){/* ... */}}
In the above example:
- The
RoutePrefix
attribute, on theBooksController
, declares a common prefix for all methods withinBooksController
. - The
Route
attributes, on individual methods, define specific route templates relative to the prefix set byRoutePrefix
.
You can use both attribute routing and conventional routing in the same application, but it's generally preferred to stick to one method for consistency and to avoid potential confusion.
Explore all 100 answers here π Devinterview.io - ASP.NET Web API
