Extension Methods in C#

Extension Methods  allows us to add new methods into a class without editing the source code of the class.

Extension methods can be used as an approach to extending the functionality of a class in the future if the source code of the class is not available or we don’t have any permission in making changes to the class.

Before extension methods, inheritance is an approach that used for extending the functionality of a class i.e. if we want to add any new members into an existing class without making a modification to the class, we will define a child class to that existing class and then we add new members in the child class.

In the case of an extension method, we will extend the functionality of a class by defining the methods, we want to add into the class in a new class and then bind them to an existing class.


Points to Remember while working with C# Extension methods:

1. Extension methods must be defined only under the static class. 

2. As an extension method is defined under a static class, compulsory that the method should be         defined  as static whereas once the method is bound with another class, the method changes into non-     static.

3. The first parameter of an extension method is known as the binding parameter which should be the     name of the class to which the method has to be bound and the binding parameter should be prefixed   with this keyword.

4. An extension method can have only one binding parameter and that should be defined in the first   place of the parameter list.

5. If required, an extension method can be defined with a normal parameter also starting from the   second place of the parameter list.

Integrate AutoMapper In ASP.NET Core Web API

 AutoMapper is a component that helps to copy data from one type of object to another type of object. It is more like an object-object mapper.

AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type.

Why do we need to use AutoMapper?

When we have to map two different objects we can use AutoMapper. One of the problems is, while building the application we have some entities which are dealing with DB (forex DTO’s) and for some entities we are dealing with a client. So we have to map those DTO’s to the entities dealing with clients.

How AutoMapper works?

AutoMapper internally uses the concept called Reflection. Reflection in C# is used to retrieve metadata on types at runtime. With the help of Reflection, we can dynamically get a type of existing object and invoke its methods or access its fields and properties.

We can implement AutoMapper using the following steps : -

1. Install AutoMapper Nuget Package

Open Package Manager Console and run below command - 

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection 

2. Configure AutoMapper for our ASP.NET Core Web API. 

So open the Startup.cs class and add the below code into ConfigureServices method.

public void ConfigureServices(IServiceCollection services)  

{  

    services.AddControllers();  

    services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());  

}  

3. Create two classes called Student.cs and StudentDTO.cs

namespace automapper_sample  

{  

    public class Student  

    {  

        public string Name { get; set; }  

        public int Age { get; set; }  

        public string City { get; set; }  

    }  

}  

namespace automapper_sample  

{  

    public class StudentDTO  

    {  

        public string Name { get; set; }  

        public int Age { get; set; }  

        public string City { get; set; }  

    }  

}  

4. Creating Profiles

Create a new class called AutoMapperProfile.cs which inherits from Profile class of AutoMapper. Use CreateMap<source, destination>() to create a mapping between classes.

using AutoMapper;  

namespace automapper_sample  

{  

    public class AutoMapperProfile : Profile  

    {  

        public AutoMapperProfile()  

        {  

            CreateMap<StudentDTO, Student>();  

        }  

    }  

}  

5. Using IMapper

IMapper interface is used to map two objects. Create a new controller called StudentController.cs. Resolve the IMapper dependency in the controller constructor.

using AutoMapper;  

using Microsoft.AspNetCore.Mvc;  

namespace automapper_sample.Controllers  

{  

    [Route("api/[controller]")]  

    public class StudentController : Controller  

    {  

        private readonly IMapper _mapper;  

        public StudentController(IMapper mapper)  

        {  

            _mapper = mapper;  

        }  

        // GET: api/<controller>  

        [HttpGet]  

        public Student Get()  

        {  

            StudentDTO studentDTO = new StudentDTO()  

            {  

                Name = "Student 1",  

                Age = 25,  

                City = "New York"  

            };  

            return _mapper.Map<Student>(studentDTO);  

        }  

    }  

}  

View components in ASP.NET Core

ViewComponent was introduced in ASP.NET Core MVC. It can do everything that a partial view can and can do even more. ViewComponents are completely self-contained objects that consistently render html from a razor view. 

It is quite similar to the partial view in terms of reusability and reduce code repetition.

View components do not use model binding. But, it works only with the data provided when we called it. Like Partial View, View components does not depend on controllers. It has its own class to implement the logic to develop the component’s model and razor markup view page. The most important thing is that View Components can utilize dependency injection, which makes them very much powerful and testable.

A View Components has the following features –

- View Components supports SOC (Separation-Of-Concerns)

- It can have its own business logic as well as parameter

- It is always invoked from the Layout Page

- It always renders chunk rather than a whole process.


View Components is actually behaving like a web part which contains both business logic and UI design to create a web part package which can be reused in the multiple parts of the web application.

View Components also involves processing by both a view component class and a View. The View Component class must be derived from the ViewComponent class.

Difference between Web API and Web Services

Features of Web API

Efficiency

Wider reach

Customizable

Personalization

Data ownership

Easy integration with GUI

Time effective

Language-independent


Features of Web Services

Loosely coupled

Synchronous or asynchronous functionality

Ability to support remote procedure calls

Supports document exchange


Advantages of API Services

API supports traditional CRUD (Create Read Update Delete) actions as it works with HTTP verbs GET, PUT, POST, and DELETE.

API helps you to expose service data to the browser

It is based on HTTP, which is easy to define, expose in REST-full way.

Advantages of Web Services

Here are the important pros/benefits of using web services:

Offers faster communications within and across organizations

Each service exists independently of other services.

Interoperability has the highest priority.

Using Web services, your application helps you to publish its message or function to the rest of the world.

Web services help solve interoperability issues by giving different applications a way to link their data.

Web services help you to exchange data between different applications and different platforms.

It allows applications to communicate, exchange data, and shared services among themselves.

Web services are specifically designed to be used as a web page request and help you to receive data.

It serves as building blocks which makes it easy to reuse web service components in other services. Web Services are deployed on internet standards such as standard Apache, and Axis2. It provides WSDL, HTTP, driven services.


Disadvantages of API

Creating API is a very time-consuming process

A fixed scale is necessary

Imprecise boundary delineation

To create API, programming knowledge is necessary

Maintenance cost is very high

It can crash when testing API

Disadvantages of Web Services


Drawbacks/cons of using Web services:

It does not access from browser

Not leverage emerging Web developments (Semantic Web, AJAX XMLHttpRequest, etc.)

Some web services are simple to use, but there are some flaws of using it.

Any time one creates a service to handle a variety of customers, there is a demand for specialized machine requirements.

The HTTP protocol is not reliable, so it does not offer any guarantee of delivery of the response.



Web ServiceAPI
All web services are APIs.All APIs are not web services.
It supports XML.Responses are formatted using Web API’s MediaTypeFormatter into XML, JSON, or any other given format.
You need a SOAP protocol to send or receive and data over the network. Therefore it does not have light-weight architecture.API has a light-weight architecture.
It can be used by any client who understands XML.It can be used by a client who understands JSON or XML.
Web service uses three styles: REST, SOAP, and XML-RPC for communication.API can be used for any style of communication.
It provides supports only for the HTTP protocol.It provides support for the HTTP/s protocol: URL Request/Response Headers, etc.

Dependency Injection in ASP.NET Core MVC

Dependency Injection is the design pattern that help us to create application which loosely coupled. This means that object should only have those dependency that required during complete task. The main advantages of DI (Dependency Injection) is our application loosely coupled and has provide greater maintainability, testability and also re-usability. 


There are three type of DI: Construction Injection, Setter Injection, Interface based Injection.


1. The Construction Injection type of DI accept their dependency at constructor level it means that when create object of the class, their dependency pass through the constructor of the class. It provide the strong dependency contract between objects. 

2. The Setter Injection is also known as property injection. In this type of dependency injection, dependency pass through public property instead of constructor. It allows us to pass the dependencies when they required. It does not provide strong dependency contract between objects. 

3. The interface-based dependency injection can be achieved by creating the common interface and other classes are implements this interface to inject the dependency. In this type of DI, we can use either constructor injection or setter injection.

There is a built-in support of dependency injection in ASP.net Core. This supports is not limited to middleware, but also support in Controllers, views, and model as well. There are two type of service container provided by the ASP.net core: Framework Services and Application Services. The framework services are service that are provided by the ASP.net core such as ILoggerFactory etc. The application services are the custom services created base on our requirement.


- Dependency injection into controllers - 

ASP.NET Core supports Dependency Injection(DI) between classes and their dependencies. MVC Controllers request dependencies explicitly via constructors. Furthermore, ASP.NET Core has built-in support for dependency injection, hence making the application easier to test and maintain.

We add services as a constructor parameter and the runtime resolves the service from the service container. We typically define services using interfaces.

When we implement a repository pattern in the ASP.NET Core MVC application, we make use of Dependency Injection in our controllers.

Let’s create an ASP.NET Core MVC application and implement a simple data repository as described in the article.


First of all, let’s create an interface IDataRepository:

public interface IDataRepository<TEntity>

{

    IEnumerable<TEntity> GetAll();

    void Add(Employee employee);

}

Then let’s create a class EmployeeManager implementing the IDataRepository interface:

public class EmployeeManager : IDataRepository<Employee>

{

    public void Add(Employee employee)

    {

        throw new NotImplementedException();

    }

    IEnumerable<Employee> IDataRepository<Employee>.GetAll()

    {

        return new List<Employee>() 

       {

            new Employee(){ }

        };

    }

}

The next step is to add the service to the service container. We need to do that in the ConfigureServices() method in the Startup.cs class:

services.AddScoped<IDataRepository<Employee>, EmployeeManager>();

By doing so, we have configured the repository using Dependency Injection.

Next, let’s create the EmployeeController with the Index() action method to get the list of all employees:

public class EmployeeController : Controller

{

    private readonly IDataRepository<Employee> _dataRepository;

    public EmployeeController(IDataRepository<Employee> dataRepository)

    {

        _dataRepository = dataRepository;

    }

    public IActionResult Index()

    {

        IEnumerable<Employee> employees = _dataRepository.GetAll();

        return View(employees);

    }

}

Here, we first declare a _dataRepository variable of type IDataRepository<Employee>. Later, we inject it through the constructor.

We can also inject a service directly into an action method without using a constructor injection. We can use the [FromServices] attribute for that:

public IActionResult Index([FromServices]  IDataRepository<Employee> _dataRepository)

{

    IEnumerable<Employee> employees = _dataRepository.GetAll();

    return View(employees);

}

TheFromServices attribute specifies that an action parameter should be bound using the request services.

Now, we have learned how to use Dependency Injection to provide dependencies into a Controller.



- Injecting Dependencies into Views -

We can inject a service into a view using the @inject directive. @inject adds a property to our view and initialize it using DI:

@inject <type> <name>

Let’s create a controller action method to display a book creation form:

public class BooksController : Controller

{

    public IActionResult Create()

    {

        return View();

    }

}

Then let’s create a Book model class:

public class Book

{

    public int Id { get; set; }

    [Display(Name = "Book Title")]

    public string Title { get; set; }

    public string Genre { get; set; }

    [DataType(DataType.Currency)]

    [Range(1, 100)]

    public decimal Price { get; set; }

    [Display(Name = "Publish Date")]

    [DataType(DataType.Date)]

    public DateTime PublishDate { get; set; }

}

For the next step, let’s define a BooksLookupService for supplying the list data for Genres:

public class BooksLookupService

{

    public List<string> GetGenres()

    {

        return new List<string>()

        {

            "Fiction",

            "Thriller",

            "Comedy",

            "Autobiography"

        };

    }

}

Then let’s create a view and inject an instance of BooksLookupService into it:

@model WorkingWithDI.Models.Book

@inject WorkingWithDI.Models.Services.BooksLookupService BooksLookupService

@{

    ViewData["Title"] = "Create";

    var genres = BooksLookupService.GetGenres();

}

<h1>Create</h1>

<h4>Book</h4>

<hr />

<div class="row">

    <div class="col-md-4">

        <form asp-action="Create">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">

                <label asp-for="Title" class="control-label"></label>

                <input asp-for="Title" class="form-control" />

                <span asp-validation-for="Title" class="text-danger"></span>

            </div>

            <div>

                <label asp-for="Genre" class="control-label"></label>

                <select asp-items="@(new SelectList(genres))" class="form-control" ></select>

            </div>

            <div class="form-group">

                <label asp-for="Price" class="control-label"></label>

                <input asp-for="Price" class="form-control" />

                <span asp-validation-for="Price" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="PublishDate" class="control-label"></label>

                <input asp-for="PublishDate" class="form-control" />

                <span asp-validation-for="PublishDate" class="text-danger"></span>

            </div>

            <div class="form-group">

                <input type="submit" value="Create" class="btn btn-primary" />

            </div>

        </form>

    </div>

</div>

<div>

    <a asp-action="Index">Back to List</a>

</div>

This will supply the list values into the view.

As the last step, we need to register the types that we request through dependency injection in Startup.ConfigureServices(). If a type is unregistered, it throws a runtime exception.

services.AddTransient<BooksLookupService>();


That’s it. Now let’s run the application and navigate to Create Books form:

We can see that the list of Genres is populated by getting the values from the BooksLookupService.

Now, we have learned how to inject a dependency directly into the view.

HTTP Status Codes

HTTP defines these standard status codes that can be used to convey the results of a client’s request. The status codes are divided into five categories.

1xx: Informational – Communicates transfer protocol-level information.

2xx: Success – Indicates that the client’s request was accepted successfully.

3xx: Redirection – Indicates that the client must take some additional action in order to complete their request.

4xx: Client Error – This category of error status codes points the finger at clients.

5xx: Server Error – The server takes responsibility for these error status codes.


1xx Status Codes [Informational]

Status Code

Description

100

Continue

An interim response. Indicates to the client that the initial part of the request has been received and has not yet been rejected by the server. The client SHOULD continue by sending the remainder of the request or, if the request has already been completed, ignore this response. The server MUST send a final response after the request has been completed.

101

Switching Protocol

Sent in response to an Upgrade request header from the client, and indicates the protocol the server is switching to.

102

Processing
(WebDAV)

Indicates that the server has received and is processing the request, but no response is available yet.

103

Early Hints

Primarily intended to be used with the Link header. It suggests the user agent start preloading the resources while the server prepares a final response.

2xx Status Codes [Success]

Status Code

Description

200

OK

Indicates that the request has succeeded.

201

Created

Indicates that the request has succeeded and a new resource has been created as a result.

202

Accepted

Indicates that the request has been received but not completed yet. It is typically used in log running requests and batch processing.

203

Non-Authoritative Information

Indicates that the returned metainformation in the entity-header is not the definitive set as available from the origin server, but is gathered from a local or a third-party copy. The set presented MAY be a subset or superset of the original version.

204

No Content

The server has fulfilled the request but does not need to return a response body. The server may return the updated meta information.

205

Reset Content

Indicates the client to reset the document which sent this request.

206

Partial Content

It is used when the Range header is sent from the client to request only part of a resource.

207

Multi-Status (WebDAV)

An indicator to a client that multiple operations happened, and that the status for each operation can be found in the body of the response.

208

Already Reported (WebDAV)

Allows a client to tell the server that the same resource (with the same binding) was mentioned earlier. It never appears as a true HTTP response code in the status line, and only appears in bodies.

226

IM Used

The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.

3xx Status Codes [Redirection]

Status Code

Description

300 Multiple Choices

The request has more than one possible response. The user-agent or user should choose one of them.

301 Moved Permanently

The URL of the requested resource has been changed permanently. The new URL is given by the Location header field in the response. This response is cacheable unless indicated otherwise.

302 Found

The URL of the requested resource has been changed temporarily. The new URL is given by the Location field in the response. This response is only cacheable if indicated by a Cache-Control or Expires header field.

303 See Other

The response can be found under a different URI and SHOULD be retrieved using a GET method on that resource.

304 Not Modified

Indicates the client that the response has not been modified, so the client can continue to use the same cached version of the response.

305 Use Proxy (Deprecated)

Indicates that a requested response must be accessed by a proxy.

306 (Unused)

It is a reserved status code and is not used anymore.

307 Temporary Redirect

Indicates the client to get the requested resource at another URI with same method that was used in the prior request. It is similar to 302 Found with one exception that the same HTTP method will be used that was used in the prior request.

308 Permanent Redirect (experimental)

Indicates that the resource is now permanently located at another URI, specified by the Location header. It is similar to 301 Moved Permanently with one exception that the same HTTP method will be used that was used in the prior request.

4xx Status Codes (Client Error)

Status Code

Description

400 Bad Request

The request could not be understood by the server due to incorrect syntax. The client SHOULD NOT repeat the request without modifications.

401 Unauthorized

Indicates that the request requires user authentication information. The client MAY repeat the request with a suitable Authorization header field

402 Payment Required (Experimental)

Reserved for future use. It is aimed for using in the digital payment systems.

403 Forbidden

Unauthorized request. The client does not have access rights to the content. Unlike 401, the client’s identity is known to the server.

404 Not Found

The server can not find the requested resource.

405 Method Not Allowed

The request HTTP method is known by the server but has been disabled and cannot be used for that resource.

406 Not Acceptable

The server doesn’t find any content that conforms to the criteria given by the user agent in the Accept header sent in the request.

407 Proxy Authentication Required

Indicates that the client must first authenticate itself with the proxy.

408 Request Timeout

Indicates that the server did not receive a complete request from the client within the server’s allotted timeout period.

409 Conflict

The request could not be completed due to a conflict with the current state of the resource.

410 Gone

The requested resource is no longer available at the server.

411 Length Required

The server refuses to accept the request without a defined Content- Length. The client MAY repeat the request if it adds a valid Content-Length header field.

412 Precondition Failed

The client has indicated preconditions in its headers which the server does not meet.

413 Request Entity Too Large

Request entity is larger than limits defined by server.

414 Request-URI Too Long

The URI requested by the client is longer than the server can interpret.

415 Unsupported Media Type

The media-type in Content-type of the request is not supported by the server.

416 Requested Range Not Satisfiable

The range specified by the Range header field in the request can’t be fulfilled.

417 Expectation Failed

The expectation indicated by the Expect request header field can’t be met by the server.

418 I’m a teapot (RFC 2324)

It was defined as April’s lool joke and is not expected to be implemented by actual HTTP servers. (RFC 2324)

420 Enhance Your Calm (Twitter)

Returned by the Twitter Search and Trends API when the client is being rate limited.

422 Unprocessable Entity (WebDAV)

The server understands the content type and syntax of the request entity, but still server is unable to process the request for some reason.

423 Locked (WebDAV)

The resource that is being accessed is locked.

424 Failed Dependency (WebDAV)

The request failed due to failure of a previous request.

425 Too Early (WebDAV)

Indicates that the server is unwilling to risk processing a request that might be replayed.

426 Upgrade Required

The server refuses to perform the request. The server will process the request after the client upgrades to a different protocol.

428 Precondition Required

The origin server requires the request to be conditional.

429 Too Many Requests

The user has sent too many requests in a given amount of time (“rate limiting”).

431 Request Header Fields Too Large

The server is unwilling to process the request because its header fields are too large.

444 No Response (Nginx)

The Nginx server returns no information to the client and closes the connection.

449 Retry With (Microsoft)

The request should be retried after performing the appropriate action.

450 Blocked by Windows Parental Controls (Microsoft)

Windows Parental Controls are turned on and are blocking access to the given webpage.

451 Unavailable For Legal Reasons

The user-agent requested a resource that cannot legally be provided.

499 Client Closed Request (Nginx)

The connection is closed by the client while HTTP server is processing its request, making the server unable to send the HTTP header back.

5xx Status Codes (Server Error)


Status Code

Description

500 Internal Server Error

The server encountered an unexpected condition that prevented it from fulfilling the request.

501 Not Implemented

The HTTP method is not supported by the server and cannot be handled.

502 Bad Gateway

The server got an invalid response while working as a gateway to get the response needed to handle the request.

503 Service Unavailable

The server is not ready to handle the request.

504 Gateway Timeout

The server is acting as a gateway and cannot get a response in time for a request.

505 HTTP Version Not Supported (Experimental)

The HTTP version used in the request is not supported by the server.

506 Variant Also Negotiates (Experimental)

Indicates that the server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper endpoint in the negotiation process.

507 Insufficient Storage (WebDAV)

The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request.

508 Loop Detected (WebDAV)

The server detected an infinite loop while processing the request.

510 Not Extended

Further extensions to the request are required for the server to fulfill it.

511 Network Authentication Required

Indicates that the client needs to authenticate to gain network access.



6. REST Specific HTTP Status Codes


4xx: Client Error – This category of error status codes points the finger at clients.

5xx: Server Error – The server takes responsibility for these error status codes.