{"id":18647500,"url":"https://github.com/mfarkan/sample-of-web-api","last_synced_at":"2025-11-05T06:30:32.775Z","repository":{"id":116078259,"uuid":"135204679","full_name":"mfarkan/Sample-Of-Web-API","owner":"mfarkan","description":"Asp.NET Web API With IoC Container and more options","archived":false,"fork":false,"pushed_at":"2019-04-19T06:47:30.000Z","size":50,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-12-27T12:11:56.674Z","etag":null,"topics":["csharp","webapi-2"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mfarkan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-28T20:10:01.000Z","updated_at":"2023-03-23T08:16:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"068d36b3-9502-449f-b5f4-36c98f0a4eb7","html_url":"https://github.com/mfarkan/Sample-Of-Web-API","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfarkan%2FSample-Of-Web-API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfarkan%2FSample-Of-Web-API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfarkan%2FSample-Of-Web-API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfarkan%2FSample-Of-Web-API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mfarkan","download_url":"https://codeload.github.com/mfarkan/Sample-Of-Web-API/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239449584,"owners_count":19640535,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","webapi-2"],"created_at":"2024-11-07T06:26:40.393Z","updated_at":"2025-11-05T06:30:32.742Z","avatar_url":"https://github.com/mfarkan.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sample Of Web API\nWhat will you find in this sample of web API ? Here is the answers ;\n\n - **IoC Container** ; in this project ApiControllers resolve in container.( Castle Windsor )\n - **Logging Mechanism** ; in this project we're using Log4Net for logging mechanism and all requests have Unique track Id ( for c# its Guid )\n - **Unit Tests** ; in this project we're using Microsoft's Unit test framework.\n - **Global Exception Logging And Handling** ; in this project we have 2 services for exception logging and handling.These services are inherited **IExceptionLogger** and **IExceptionHandler** interfaces.\n - **Swagger Configuration** ; Documentation for Swagger.\n - **Global Request Logging** ; Global logging Attribute.\n \n## Dependency Injection For API\nThis sample project , we will use **Castle Windsor** for IoC Container.You can use another IoC Container framework (for example : Unity , Ninject etc. )\n\nWeb API provides two primary mechanism for controller dependency injection. Implementing a custom **IHttpControllerActivator** and implementing a custom **IDependencyResolver**. ([*ASP. NET Web API 2 Recipes: A Problem-Solution Approach - Filip Wojcieszyn*](https://books.google.com.tr/books?id=7aE8BAAAQBAJ\u0026printsec=frontcover\u0026hl=tr#v=onepage\u0026q\u0026f=false))\n\nIn this sample, using the **IHttpControllerActivator**. It's resolve controller classes.\n\n**For Example to IHttpControllerActivator Implentation;**\n\n```c#\n    public class WindsorCompositionRoot : IHttpControllerActivator\n    {\n        private readonly IWindsorContainer _container;\n        public WindsorCompositionRoot(IWindsorContainer container)\n        {\n            _container = container;\n        }\n        public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\n        {\n            var controller =\n            (IHttpController)this._container.Resolve(controllerType);\n\n           request.RegisterForDispose(\n            new Release(\n                () =\u003e this._container.Release(controller)));\n\n            return controller;\n        }\n    }\npublic class Release : IDisposable\n    {\n        private readonly Action _release;\n        public Release(Action release)\n        {\n            this._release = release;\n        }\n        public void Dispose()\n        {\n            this._release();\n        }\n    }\n```\n**Here is Controller Installer ;**\n```c#\npublic class ControllerInstaller : IWindsorInstaller\n    {\n        public void Install(IWindsorContainer container, IConfigurationStore store)\n        {\n            container.Register(Classes.FromThisAssembly()\n                        .BasedOn\u003cApiController\u003e()\n                        .LifestylePerWebRequest()\n                        );\n        }\n    }\n``` \n**And Global.asax configuration ;**\n```c#\nIWindsorContainer container = new WindsorContainer();\ncontainer.Install(FromAssembly.This());\nGlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorCompositionRoot(container)); \n``` \n\nAfter this implentation , all apicontroller release this Activator class and **container** is carrying all controller.\n\n## Logging Mechanism\n\n**Log4net** is a usefull component for all project because it's easy to configuration and simple to use.\n\nDownload the log4net package with nugget and download *[my other project](https://github.com/mfarkan/Log4NetCustomLogger)* to use with it :)\n\n## Unit Tests For API\n\nI used this guide for Unit testing ; \n\n[Microsoft Documentation](https://docs.microsoft.com/tr-tr/aspnet/web-api/overview/testing-and-debugging/unit-testing-with-aspnet-web-api)\n\nHere is the TestControllerClass;\n```c#\n[TestClass]\n    public class TestProductController\n    {\n        [TestMethod]\n        public void getProduct_ReturnEmptyProduct()\n        {\n            var service = new ProductService();\n            var controller = new ProductController(service);\n            var result = controller.getProduct(9999);\n            Assert.IsNull(result);\n        }\n        [TestMethod]\n        public void getProduct_ReturnFirstProduct()\n        {\n            var service = new ProductService();\n            var controller = new ProductController(service);\n            Product sample = new Product()\n            {\n                ProductId = 1,\n                ProductName = \"MFA\",\n                Status = 0,\n                ResponseCode = null,\n                Message = null\n            };\n            var result = controller.getProduct(1);\n\t\tAssert.AreEqual(sample.ProductName, result.ProductName);\n        }\n```\n## Global Exception Logging And Handling\n\nAll unhandled exceptions can now be logged through one central mechanism, and the behavior for unhandled exceptions can be customized.([*Global Logging*](https://docs.microsoft.com/en-us/aspnet/web-api/overview/releases/whats-new-in-aspnet-web-api-21))\n\n**When to use** ;\n\n-   Exception loggers are the solution to seeing all unhandled exception caught by Web API.\n-  Exception handlers are the solution for customizing all possible responses to unhandled exceptions caught by Web API.\n\n**For example IExceptionLogger** ;\n```c#\npublic class CustomExceptionLogger : ExceptionLogger\n    {\n        private readonly ILogger _logger;\n        public CustomExceptionLogger(ILogger logger)\n        {\n            this._logger = logger;\n        }\n        public override void Log(ExceptionLoggerContext context)\n        {\n            var Guid = context.Request.Headers.GetValues(\"TrackId\").FirstOrDefault();\n            _logger.Log(\"Track Id : \" + Guid + \" - ERROR : {\" + context.Exception.Message + \"}\", LogType.Error);\n            base.Log(context);\n        }\n    }\n```\n**For example IExceptionHandling** ;\n```c#\npublic class HandlerLogger :ExceptionHandler\n    {\n        private readonly ILogger _logger;\n        public HandlerLogger(ILogger logger)\n        {\n            _logger = logger;\n        }\n        public override void Handle(ExceptionHandlerContext context)\n        {\n            ResponseHeader header;\n            var ReturnType = context.Request.GetActionDescriptor().ReturnType;\n            header = Activator.CreateInstance(ReturnType) as ResponseHeader;\n            header.Message = context.Exception.Message;\n            header.ResponseCode = \"0001\";\n            header.Status = 1;\n            var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, header);\n            context.Result = new ResponseMessageResult(response);\n            base.Handle(context);\n        }\n    }\n```\n**And Global.asax configuration ;**\n\n```c#\nGlobalConfiguration.Configuration.Services.Replace(typeof(IExceptionHandler), new HandlerLogger(container.Resolve\u003cILogger\u003e()));\nGlobalConfiguration.Configuration.Services.Replace(typeof(IExceptionLogger), new CustomExceptionLogger(container.Resolve\u003cILogger\u003e()));\n```\nIn these code blocks says handle unexpected error **globally** and **return** custom response and response model.\n\n## Swagger Configuration\n\nWhen consuming a Web API, understanding its various methods can be challenging for a developer.[*Swagger*](https://swagger.io/), also known as Open API, solves the problem of generating useful documentation and help pages for Web APIs.  It provides benefits such as interactive documentation, client SDK generation, and API discoverability.\n\n## Global Request Logging\n\nThe goal is ,who is requesting our API and if its success , What is the response?Im managing it with using **ActionFilterAttribute**.\n\nActionFilterAttribute has two methods ;\n\n - **OnActionExecuting** ; Its for using Request logging and create **GuID** add to Request Header.\n - **OnActionExecuted** ; If request successfully end , log the Response.\n\nHere is the **LoggingAttribute** ;\n```c#\n    public class LoggingAttribute : ActionFilterAttribute\n    {\n        private readonly ILogger logger;\n        private string _Guid;\n        public LoggingAttribute(ILogger logger)\n        {\n            this.logger = logger;\n        }\n        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\n        {\n            string jSonData = actionExecutedContext.Response?.Content.ReadAsStringAsync().Result;\n            this.logger.Log(\"Track Id : \" + _Guid + \" - OutGoing Response {\" + jSonData + \"}\", LogType.Debug);\n            base.OnActionExecuted(actionExecutedContext);\n        }\n        public override void OnActionExecuting(HttpActionContext actionContext)\n        {\n            string jSonData = actionContext.Request.Content?.ReadAsStringAsync().Result;\n            _Guid = Guid.NewGuid().ToString();\n            actionContext.Request.Headers.Add(\"TrackId\", _Guid);\n            this.logger.Log(\"Track Id : \" + _Guid + \" - \" + actionContext.Request.RequestUri.LocalPath + \" - Incoming Request {\" + jSonData + \"}\", LogType.Debug);\n            base.OnActionExecuting(actionContext);\n        }\n    }\n``` \nGlobal.asax configuration ; \n```c#\nGlobalConfiguration.Configuration.Filters.Add(new LoggingAttribute(container.Resolve\u003cILogger\u003e()));\n```\n\nThank you !\n\n***Resources ;***\n\n - [*Global Exception Logging*](https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/web-api-global-error-handling)\n - [*New Futures Of Web API 2.1*](https://docs.microsoft.com/en-us/aspnet/web-api/overview/releases/whats-new-in-aspnet-web-api-21)\n - [*Ioc Container Frameworks*](https://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx)\n - [*Swagger Documentation*](https://swagger.io)\n - [*Castle Windsor*](http://www.castleproject.org)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfarkan%2Fsample-of-web-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmfarkan%2Fsample-of-web-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfarkan%2Fsample-of-web-api/lists"}