The document discusses implementing request and exception logging in ASP.NET Web APIs using NLog, Action Filters, and Exception Filters. It describes setting up NLog configuration, creating an NLogger class to handle logging, and adding an Action Filter (LoggingFilterAttribute) to log requests. It also covers adding an Exception Filter (GlobalExceptionAttribute) to log exceptions, modifying classes to support exception logging, and throwing an exception to test the exception logging.
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsAkhil Mittal
We have already learnt a lot on WebAPI. I have already explained how to create WebAPI, connect it with database using Entity Framework, resolving dependencies using Unity Container as well as using MEF. In all our sample applications we were using default route that MVC provides us for CRUD operations. In this article I’ll explain how to write your own custom routes using Attribute Routing. We’ll deal with Action level routing as well as Controller level routing. I’ll explain this in detail with the help of a sample application. My new readers can use any Web API sample they have, else you can also use the sample applications we developed in my previous articles.
Inversion of control using dependency injection in Web APIs using Unity Conta...Akhil Mittal
My article will explain how we can make our Web API service architecture loosely coupled and more flexible. We already learnt that how we can create a RESTful service using Asp.net Web API and Entity framework in my last article. If you remember we ended up in a solution with a design flaw, we’ll try to overcome that flaw by resolving the dependencies of dependent components. For those who have not followed my previous article, they can learn by having the sample project attached as a test application from my first article.
The document discusses setting up a development environment for Java web applications using frameworks like Struts, including installing Java, Tomcat, and Struts. It also provides an overview of developing a basic "Hello World" Struts application, including creating an action class and configuring it in the struts.xml file to return the view page. The document includes code samples for configuring filters in web.xml and implementing a basic action class and JSP view page.
The document provides an overview of new features in JavaServer Faces (JSF) 2.0, including foundational changes, improved system events, resource handling, state saving, GET request support, and a more powerful component model with composite components and behaviors. Key additions are support for Ajax, easier component development through templating with Facelets, and performance improvements through partial state saving.
Resolve dependency of dependencies using Inversion of Control and dependency ...Akhil Mittal
In my last two articles I explained how to create a RESTful service using ASP.NET Web API working with Entity Framework and resolving dependencies using Unity Container. In this article I’ll explain how to create a loosely coupled system with Unity Container and MEF(Managed Extensibility Framework) using Inversion of Control. I’ll not be explaining much theory but rather focus more on practical implementations. For the readers who are following this series, they can use their existing solution that they have created till time. For my new readers of this article, I have provided the download link for the previous source code and current source code as well.
For theory and understanding of DI and IOC you can follow the following links: Unity and Inversion of Control(IOC).
1) Single page applications (SPAs) use JavaScript to dynamically update the content of a single web page rather than loading entire new pages. This reduces page refreshes.
2) React is a popular JavaScript library for building user interfaces, especially for SPAs. It uses a virtual DOM for faster rendering.
3) Create-React-App is a command line interface that sets up a React project with common dependencies like Babel and Webpack preconfigured.
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsAkhil Mittal
We have already learnt a lot on WebAPI. I have already explained how to create WebAPI, connect it with database using Entity Framework, resolving dependencies using Unity Container as well as using MEF. In all our sample applications we were using default route that MVC provides us for CRUD operations. In this article I’ll explain how to write your own custom routes using Attribute Routing. We’ll deal with Action level routing as well as Controller level routing. I’ll explain this in detail with the help of a sample application. My new readers can use any Web API sample they have, else you can also use the sample applications we developed in my previous articles.
Inversion of control using dependency injection in Web APIs using Unity Conta...Akhil Mittal
My article will explain how we can make our Web API service architecture loosely coupled and more flexible. We already learnt that how we can create a RESTful service using Asp.net Web API and Entity framework in my last article. If you remember we ended up in a solution with a design flaw, we’ll try to overcome that flaw by resolving the dependencies of dependent components. For those who have not followed my previous article, they can learn by having the sample project attached as a test application from my first article.
The document discusses setting up a development environment for Java web applications using frameworks like Struts, including installing Java, Tomcat, and Struts. It also provides an overview of developing a basic "Hello World" Struts application, including creating an action class and configuring it in the struts.xml file to return the view page. The document includes code samples for configuring filters in web.xml and implementing a basic action class and JSP view page.
The document provides an overview of new features in JavaServer Faces (JSF) 2.0, including foundational changes, improved system events, resource handling, state saving, GET request support, and a more powerful component model with composite components and behaviors. Key additions are support for Ajax, easier component development through templating with Facelets, and performance improvements through partial state saving.
Resolve dependency of dependencies using Inversion of Control and dependency ...Akhil Mittal
In my last two articles I explained how to create a RESTful service using ASP.NET Web API working with Entity Framework and resolving dependencies using Unity Container. In this article I’ll explain how to create a loosely coupled system with Unity Container and MEF(Managed Extensibility Framework) using Inversion of Control. I’ll not be explaining much theory but rather focus more on practical implementations. For the readers who are following this series, they can use their existing solution that they have created till time. For my new readers of this article, I have provided the download link for the previous source code and current source code as well.
For theory and understanding of DI and IOC you can follow the following links: Unity and Inversion of Control(IOC).
1) Single page applications (SPAs) use JavaScript to dynamically update the content of a single web page rather than loading entire new pages. This reduces page refreshes.
2) React is a popular JavaScript library for building user interfaces, especially for SPAs. It uses a virtual DOM for faster rendering.
3) Create-React-App is a command line interface that sets up a React project with common dependencies like Babel and Webpack preconfigured.
The document discusses Spring Boot, a framework for creating stand-alone, production-grade Spring based applications. It describes how Spring Boot allows creating projects quickly with features like embedded servers and auto-configuration. It then covers how to develop a basic Spring Boot web application including creating the project structure with Maven, adding controllers and properties files, and connecting to databases using Spring Data. Overall, the document provides an overview of Spring Boot and guidance on starting a Spring Boot web application project.
The project titled "WiFi Connect" is an Android application that allows sending text messages and files between two Android devices using their WiFi networks. The project was developed in Android using Java and focuses on sending text messages and files via WiFi. It includes five modules: 1) Client/Server socket programming, 2) WiFi on/off button, 3) Server and client socket Android applications, 4) WiFi demo, and 5) WiFi Direct demo.
The document discusses various ways to optimize Flex applications for performance, including:
1. Using runtime shared libraries (RSLs) to externalize shared assets and reduce SWF file size.
2. Optimizing object creation by delaying it until necessary or staggering creation.
3. Improving measurement and layout performance by reducing nested containers and using Box containers when possible.
This document provides an overview and agenda for a presentation on web parts in ASP.NET. It defines what a web part is, discusses how they were built before ASP.NET 2.0, and how to build standard and custom web parts. It also covers the web parts infrastructure in ASP.NET 2.0 including the life cycle, zones, and controls. Examples are provided for hello world web parts, using user controls in web parts, and calling web services from web parts.
A developer has been working on an ASP.NET Core project for a few months. During that time he had various problems I had to fix. Then he converted his application to the RC2 version that was released a few weeks ago. Here we write down a post listing problems that could be fixed. Hope a few would find it useful.
Android MVVM architecture using Kotlin, Dagger2, LiveData, MediatorLiveDataWaheed Nazir
Kotlin MVVM Architecture:
A sample app that display list of Google news. The purpose of this project to illustrate the usage of MVVM architecture design pattern that follow the best practices of Object Oriented Design Patterns using the following technology stack.
Architecture Design Pattern
MVVM
Dagger2 (Dependency Injection)
Live Data, MediatorLiveData
Room Database
Retrofit
Unit Testing (Espresso), Mockito (Coming soon)
Repository Pattern
AndroidX
Glide
NetworkBoundResource, NetworkAndDBBoundResource
Google News API
JetPack Libraries
This seminar provides an introduction to Portlet development using the Spring MVC framework. Topics include: quick introductions to Spring and JSR 168 Portlets, setting up a Portlet development environment, an overview of the Spring MVC API, and then a series of sample applications that cover specific topics like Handler Mappings, Controllers, Interceptors, Form Controllers, File Uploads and the new Annotation-based Mappings introduced in Spring 2.5.
Sample code is available at:
http://www.ja-sig.org/wiki/x/CACDAQ
This document provides an overview and introduction to web parts in ASP.NET. It discusses what web parts are, the benefits they provide, and how they work. Key points covered include how web parts allow for personalization, reuse of content across pages, and communication between parts. The document also outlines the basic infrastructure that supports web parts, including the WebPartManager, zones, and how to create simple web parts and use controls within them.
The document discusses various techniques for building mashup applications using Adobe AIR, including integrating HTML and JavaScript, monitoring network connectivity, working with files and SQLite databases, and creating different types of menus. Key topics include using the HTMLLoader class to display HTML, the URLMonitor class to check network status, File and FileStream classes to access files, and SQLConnection to interface with SQLite databases locally. The document also covers creating window, application, context and system tray menus in AIR applications.
JSF 2 and beyond: Keeping progress comingAndy Schwartz
Covers new features in JSF 2, community involvement in JSF and a look towards the future of this framework.
Presented by Dan Allen, Pete Muir and Andy Schwartz at Devoxx 2009.
http://www.devoxx.com/display/DV09/JSF+2+and+beyond
This document discusses unit testing Web APIs using the NUnit and Moq frameworks. It provides an overview of unit testing and the NUnit and Moq frameworks. It then details setting up a test project and installing necessary packages. The document focuses on writing unit tests for the business logic layer and controllers, demonstrating how to test a ProductService class by mocking dependencies, writing test methods, and more.
The document describes setting up unit testing for a Web API project using NUnit and Moq frameworks. It includes:
1. Adding a test project and installing necessary packages like NUnit, Moq, EntityFramework, and Newtonsoft.Json.
2. Defining variables and setting up mocks for the repositories, services, and UnitOfWork classes needed for the tests.
3. Writing tests for the ProductController including getting all products, getting a product by ID, and testing exceptions.
4. Explaining how to mock the repositories to simulate database operations during the tests.
So in summary, it covers the steps to set up a Web API project for unit testing and then provides examples
Company Visitor Management System Report.docxfantabulous2024
The document provides an overview of a Company Visitor Management System project. It includes sections on the project introduction, modules, requirements, analysis and design, database tables, implementation, evaluation, and conclusion. The system is a web-based application built with Python, Django, and MySQL to more effectively manage and track company visitors through features like adding visitors, generating reports, and password recovery/management. UML diagrams including use cases, classes, entities, and data flow are included to visualize the system design.
The document discusses using Google App Engine and Google Web Toolkit to develop a simple stock market analysis program. It provides an overview of cloud computing and the key aspects of Google App Engine, including its architecture, data storage via Bigtable, and development process. It then describes how the stock analysis program was built with GWT to allow users to search for stock quotes, view their portfolio, and remove stocks, all while taking advantage of Google's cloud infrastructure. Code snippets demonstrate integrating GWT with App Engine for user login/logout and accessing data from the cloud.
The document discusses the Polymer JavaScript library. It begins with an abstract that outlines what Polymer is - a library for creating reusable web components for modern web applications using HTML web components. It then covers key topics like the features of Polymer, how to create custom elements, data binding, events, comparisons to Angular, and more. The document provides technical details about Polymer's architecture, components, and how it can be used to build web applications.
This document provides an overview of using Google App Engine to develop a file repository application. It first discusses cloud computing and Google App Engine, including its architecture, key concepts like Bigtable distributed storage and the datastore. It then describes building a file repository app with functions like upload, download and file listing. The app is implemented using Java servlets, JSP, Apache Commons FileUpload and Google APIs.
Explore seamless Jaeger integration with Spring Cloud for streamlined application monitoring and enhanced performance. Learn how to leverage distributed tracing capabilities for efficient microservices management.
Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
The document discusses implementing a repository pattern in an MVC application using Entity Framework. It begins with an introduction and roadmap of previous articles. It then discusses the benefits of a repository pattern in abstracting the data access layer from business logic. Steps are provided to create a sample repository interface and class to implement basic CRUD operations on a User entity, abstracting the data access code from the controller. The repository class uses the Entity Framework context to perform operations while resolving tight coupling issues between layers. It concludes that while this implementation works for a single entity, a generic repository will be needed to cleanly support multiple entities without duplication.
This document outlines 5 projects for building a library management system. Project 1 involves building .NET class libraries. Project 2 creates a Windows forms frontend. Project 3 develops the business and data access tiers using LINQ and stored procedures. Project 4 adds a web frontend. Project 5 implements a WCF service for interoperability and uses security features.
This document discusses AngularJS, an open-source JavaScript framework. It provides an overview of AngularJS, including its key features like data binding, modularity, reusability, and testing capabilities. The document then describes some core AngularJS concepts like scopes, modules, controllers, directives, filters, and dependency injection. It also discusses how AngularJS works and initializes. Finally, the document demonstrates an implementation of an employee management system using AngularJS, GitHub, Grunt, and other tools to showcase features like adding and sorting employees.
The document discusses Spring Boot, a framework for creating stand-alone, production-grade Spring based applications. It describes how Spring Boot allows creating projects quickly with features like embedded servers and auto-configuration. It then covers how to develop a basic Spring Boot web application including creating the project structure with Maven, adding controllers and properties files, and connecting to databases using Spring Data. Overall, the document provides an overview of Spring Boot and guidance on starting a Spring Boot web application project.
The project titled "WiFi Connect" is an Android application that allows sending text messages and files between two Android devices using their WiFi networks. The project was developed in Android using Java and focuses on sending text messages and files via WiFi. It includes five modules: 1) Client/Server socket programming, 2) WiFi on/off button, 3) Server and client socket Android applications, 4) WiFi demo, and 5) WiFi Direct demo.
The document discusses various ways to optimize Flex applications for performance, including:
1. Using runtime shared libraries (RSLs) to externalize shared assets and reduce SWF file size.
2. Optimizing object creation by delaying it until necessary or staggering creation.
3. Improving measurement and layout performance by reducing nested containers and using Box containers when possible.
This document provides an overview and agenda for a presentation on web parts in ASP.NET. It defines what a web part is, discusses how they were built before ASP.NET 2.0, and how to build standard and custom web parts. It also covers the web parts infrastructure in ASP.NET 2.0 including the life cycle, zones, and controls. Examples are provided for hello world web parts, using user controls in web parts, and calling web services from web parts.
A developer has been working on an ASP.NET Core project for a few months. During that time he had various problems I had to fix. Then he converted his application to the RC2 version that was released a few weeks ago. Here we write down a post listing problems that could be fixed. Hope a few would find it useful.
Android MVVM architecture using Kotlin, Dagger2, LiveData, MediatorLiveDataWaheed Nazir
Kotlin MVVM Architecture:
A sample app that display list of Google news. The purpose of this project to illustrate the usage of MVVM architecture design pattern that follow the best practices of Object Oriented Design Patterns using the following technology stack.
Architecture Design Pattern
MVVM
Dagger2 (Dependency Injection)
Live Data, MediatorLiveData
Room Database
Retrofit
Unit Testing (Espresso), Mockito (Coming soon)
Repository Pattern
AndroidX
Glide
NetworkBoundResource, NetworkAndDBBoundResource
Google News API
JetPack Libraries
This seminar provides an introduction to Portlet development using the Spring MVC framework. Topics include: quick introductions to Spring and JSR 168 Portlets, setting up a Portlet development environment, an overview of the Spring MVC API, and then a series of sample applications that cover specific topics like Handler Mappings, Controllers, Interceptors, Form Controllers, File Uploads and the new Annotation-based Mappings introduced in Spring 2.5.
Sample code is available at:
http://www.ja-sig.org/wiki/x/CACDAQ
This document provides an overview and introduction to web parts in ASP.NET. It discusses what web parts are, the benefits they provide, and how they work. Key points covered include how web parts allow for personalization, reuse of content across pages, and communication between parts. The document also outlines the basic infrastructure that supports web parts, including the WebPartManager, zones, and how to create simple web parts and use controls within them.
The document discusses various techniques for building mashup applications using Adobe AIR, including integrating HTML and JavaScript, monitoring network connectivity, working with files and SQLite databases, and creating different types of menus. Key topics include using the HTMLLoader class to display HTML, the URLMonitor class to check network status, File and FileStream classes to access files, and SQLConnection to interface with SQLite databases locally. The document also covers creating window, application, context and system tray menus in AIR applications.
JSF 2 and beyond: Keeping progress comingAndy Schwartz
Covers new features in JSF 2, community involvement in JSF and a look towards the future of this framework.
Presented by Dan Allen, Pete Muir and Andy Schwartz at Devoxx 2009.
http://www.devoxx.com/display/DV09/JSF+2+and+beyond
This document discusses unit testing Web APIs using the NUnit and Moq frameworks. It provides an overview of unit testing and the NUnit and Moq frameworks. It then details setting up a test project and installing necessary packages. The document focuses on writing unit tests for the business logic layer and controllers, demonstrating how to test a ProductService class by mocking dependencies, writing test methods, and more.
The document describes setting up unit testing for a Web API project using NUnit and Moq frameworks. It includes:
1. Adding a test project and installing necessary packages like NUnit, Moq, EntityFramework, and Newtonsoft.Json.
2. Defining variables and setting up mocks for the repositories, services, and UnitOfWork classes needed for the tests.
3. Writing tests for the ProductController including getting all products, getting a product by ID, and testing exceptions.
4. Explaining how to mock the repositories to simulate database operations during the tests.
So in summary, it covers the steps to set up a Web API project for unit testing and then provides examples
Company Visitor Management System Report.docxfantabulous2024
The document provides an overview of a Company Visitor Management System project. It includes sections on the project introduction, modules, requirements, analysis and design, database tables, implementation, evaluation, and conclusion. The system is a web-based application built with Python, Django, and MySQL to more effectively manage and track company visitors through features like adding visitors, generating reports, and password recovery/management. UML diagrams including use cases, classes, entities, and data flow are included to visualize the system design.
The document discusses using Google App Engine and Google Web Toolkit to develop a simple stock market analysis program. It provides an overview of cloud computing and the key aspects of Google App Engine, including its architecture, data storage via Bigtable, and development process. It then describes how the stock analysis program was built with GWT to allow users to search for stock quotes, view their portfolio, and remove stocks, all while taking advantage of Google's cloud infrastructure. Code snippets demonstrate integrating GWT with App Engine for user login/logout and accessing data from the cloud.
The document discusses the Polymer JavaScript library. It begins with an abstract that outlines what Polymer is - a library for creating reusable web components for modern web applications using HTML web components. It then covers key topics like the features of Polymer, how to create custom elements, data binding, events, comparisons to Angular, and more. The document provides technical details about Polymer's architecture, components, and how it can be used to build web applications.
This document provides an overview of using Google App Engine to develop a file repository application. It first discusses cloud computing and Google App Engine, including its architecture, key concepts like Bigtable distributed storage and the datastore. It then describes building a file repository app with functions like upload, download and file listing. The app is implemented using Java servlets, JSP, Apache Commons FileUpload and Google APIs.
Explore seamless Jaeger integration with Spring Cloud for streamlined application monitoring and enhanced performance. Learn how to leverage distributed tracing capabilities for efficient microservices management.
Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
The document discusses implementing a repository pattern in an MVC application using Entity Framework. It begins with an introduction and roadmap of previous articles. It then discusses the benefits of a repository pattern in abstracting the data access layer from business logic. Steps are provided to create a sample repository interface and class to implement basic CRUD operations on a User entity, abstracting the data access code from the controller. The repository class uses the Entity Framework context to perform operations while resolving tight coupling issues between layers. It concludes that while this implementation works for a single entity, a generic repository will be needed to cleanly support multiple entities without duplication.
This document outlines 5 projects for building a library management system. Project 1 involves building .NET class libraries. Project 2 creates a Windows forms frontend. Project 3 develops the business and data access tiers using LINQ and stored procedures. Project 4 adds a web frontend. Project 5 implements a WCF service for interoperability and uses security features.
This document discusses AngularJS, an open-source JavaScript framework. It provides an overview of AngularJS, including its key features like data binding, modularity, reusability, and testing capabilities. The document then describes some core AngularJS concepts like scopes, modules, controllers, directives, filters, and dependency injection. It also discusses how AngularJS works and initializes. Finally, the document demonstrates an implementation of an employee management system using AngularJS, GitHub, Grunt, and other tools to showcase features like adding and sorting employees.
This document provides an overview of Angular 2 including:
- Main blocks like components, directives, services, routing etc.
- How to set up a development environment with Node.js and TypeScript
- Examples of core features like data binding, communication between components, dependency injection, and HTTP requests
- Tips for organizing projects, lazy loading modules, ahead of time compilation, and using the Angular CLI
The document is a project report submitted to Bharati Vidyapeeth University by Akash Raj guru. It contains information on three web development frameworks - Django, QT, and Web2py. For the Django framework section, it provides an introduction to Django including what it is, its prerequisites, downloading and installing Django, creating projects and applications in Django, and building Django applications. It also includes project snapshots and source code for a Django project.
The document discusses adding user management functionality to a Node.js application called QAVideos. It involves the following steps:
1. Creating the application using StrongLoop's Loopback framework.
2. Adding Angular support to handle data binding between the client and server.
3. Adding signup and login functionality including signup and success pages, a signup controller, and an authentication service to register new users.
Get things done with Yii - quickly build webapplicationsGiuliano Iacobelli
Lesson teached at Università di Roma Tre - Software Engineering course.
Web is plenty of amazing tools used daily by millions of people. A good idea can turn to be a highly profitable business if well executed. Yii framework is an ideal tool to build in short time an MVP of your product to start as soon as possible to find your market fit. Here follows some infos about the framework and steps on how to build a simple blog over Yii.
https://youtu.be/_yLt_abcK2w
Angular is a TypeScript-based open-source front-end platform that makes it easy to build applications with in web/mobile/desktop. The major features of this framework such as declarative templates, dependency injection, end to end tooling, and many more other features are used to ease the development.
Angular 7 is a Javascript framework built around the concept of components, and more precisely, with the Web Components standard in mind. It was rewritten from scratch by the Angular team using Typescript (although we can use it with ES5, ES6, or Dart as well).
Angular 7 is a big change for us compared to 1.x. Because it is a completely different framework than 1.x, and is not backward-compatible. Angular 7 is written entirely in Typescript and meets the ECMAScript 6 specification
angular interview questions and answers, angular 7 interview questions and answers, angular interview question, angular interview questions and answers for experienced, angular 7 interview questions, angular 6 interview questions,
angular interview questions, angular 6 interview questions and answers, angular 2 interview questions, angular7, angular 5 interview questions, angular interview, angular 2 interview questions and answers, angular questions and answers
Spring boot is a suite, pre-configured, pre-sugared set of frameworks/technologies to reduce boilerplate configuration providing you the shortest way to have a Spring web application up and running with smallest line of code/configuration out-of-the-box.
The document summarizes several .NET projects completed by Alexander F Vogel including creating class libraries, a Windows forms application for a library management system, updating the system to use LINQ and web services, and developing a testing application. The projects involved designing interfaces, classes, databases and stored procedures to implement business requirements while following best practices for maintainability, validation, error handling and usability.
Do you want your customers and/or employees to have a speedy, no-hassle end-user experience when they use your website or server, respectively? Of course you do – because an unsatisfied end-user means lost business – as in the case of a customer – or a really annoyed employee.
That’s why Monitis — the 100% Cloud-based, complete, and flexible IT monitoring solution that consolidates back-end monitoring, application monitoring, website monitoring, and cloud monitoring in an all-lin-one, central monitoring service (that was a mouthful) — has put together this collection of tips for optimizing HTML/CSS (Cascading Style Sheets) and images.
This document discusses content negotiation in ASP.NET Web API 2. It explains what content negotiation is, why it is important, and how to implement it in Web API. Content negotiation allows a client to specify the desired response format using request headers like Accept and Content-Type. Web API uses formatters to serialize the response into the requested format. The document provides examples of configuring formatters to support different media types and customize the JSON output. It also describes how the content negotiation pipeline in Web API works to select the appropriate formatter based on the request headers.
The document discusses new and improved debugging features in Visual Studio 2015, including easier breakpoint configuration with an inline toolbar, simplified context menus, and settings windows that appear as peek windows. It also covers breakpoint conditions that allow hitting a breakpoint based on the number of hits or a conditional expression. Breakpoint actions allow logging messages to the output window. Additionally, the improved Error List in VS 2015 displays all errors at once, allows filtering by severity and error code, and links error codes to documentation.
This document discusses code refactoring techniques in Visual Studio 2015, including inline temporary variables and introducing local variables. It provides an example C# class with a method to fetch products above a certain price, and shows how Visual Studio's code refactoring suggestions can optimize the method in multiple steps. These include removing temporary variables, converting the method to an expression-bodied member, and reducing the code to a single line. The document emphasizes that code refactoring requires an understanding of how the changes will affect the code.
The document discusses renaming features in Visual Studio 2015. It describes how VS2015 provides renaming assistance through suggestions from the light bulb icon and previews changes before renaming. The renaming window allows renaming variables, methods, properties, classes, parameters and strings. It can also rename code comments and detect conflicts if the new name already exists. Renaming occurs inline and on the fly. The examples demonstrate renaming a variable, method, and parameter across multiple files. VS2015 helps optimize code through intelligent and automated renaming.
The document discusses Visual Studio's live static code analysis feature. It explains that this feature analyzes code in real-time as it is written, without requiring compilation, to detect errors and potential issues based on installed code analyzers. The document demonstrates how to install and use code analyzers through examples, showing how analyzers detect issues and provide suggestions to fix problems directly in the code editor through light bulb notifications. It provides a case study walking through fixing various issues detected in sample code using suggestions from an analyzer to iteratively improve the code quality.
The document discusses the code assistance features of Visual Studio 2015. It provides examples of how the light bulb icon displays potential fixes for syntax errors and missing code. It also shows how refactoring suggestions are provided to optimize code, such as removing unused namespaces or changing a method to directly return a value rather than using a temporary variable. The light bulb icon assists with code completion, error fixing, and refactoring to improve code quality and developer productivity.
Release planning is a challenging but important part of the agile development process. There are two main approaches to release planning: fixed timeline and fixed scope of work. With a fixed timeline, the deadline cannot be extended and functionality may need to be cut, while a fixed scope defines what must be included regardless of timeline. The objective of release planning is to baseline the product roadmap and team commitments, while allowing flexibility based on which approach is chosen.
This document discusses extending OData support in ASP.NET Web APIs. It provides an introduction to OData and the roadmap for a RESTful Web API series. It describes setting up a solution to add OData support and modifying existing API endpoints to be OData enabled. This allows queries to support options like $top, $filter, $orderby and more to filter, sort, page and select data from the server.
Generic Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
This document discusses implementing a generic repository pattern and unit of work pattern in an MVC application using Entity Framework. It begins by introducing the concepts of a generic repository and unit of work. It then shows how to create a generic repository class that can be used for any entity. A unit of work class is created to manage transactions and repositories. Properties on the unit of work class provide access to repositories without having to create separate classes. CRUD operations on entities are demonstrated using the generic repository through the unit of work. This completes the tutorial on implementing these patterns to reduce redundant code and complexity in an MVC application.
MVC Application using EntityFramework Code-First approach Part4Akhil Mittal
This document discusses connecting an MVC application to a database using Entity Framework's Code First approach. It explains that with Code First, domain models are designed first before the database is automatically generated. The steps shown create a DbContext class that inherits from DbContext and defines a DbSet for the User model. A connection string is added and the DbContext is used instead of the prior Entity Data Model classes. When run, the database is dynamically generated based on the model, allowing CRUD operations on the User table through the application and Entity Framework.
Learning MVC Part 3 Creating MVC Application with EntityFrameworkAkhil Mittal
This document discusses connecting an existing MVC application to a database using Entity Framework instead of LINQ to SQL. It provides steps to generate an Entity Data Model from an existing database, generate strongly typed entity classes, and modify the application's controllers to use the Entity Framework context instead of the LINQ to SQL context. The key steps are: 1) Adding an Entity Data Model file and generating entity classes; 2) Modifying controllers to use the Entity Framework context instead of LINQ to SQL; 3) Binding views to the generated entity classes. The document emphasizes that Entity Framework automates CRUD operations and allows focusing on business logic rather than data access code.
This document discusses creating an MVC application from scratch using LINQ to SQL to perform CRUD operations on a database. It covers:
1. Creating an empty MVC project and adding controllers, views and models
2. Creating a sample database and using LINQ to SQL for communication between the MVC app and database
3. Performing CRUD operations in the MVC app by querying the database and passing data between controllers and views
This document introduces the MVC architecture and separation of concerns. It outlines a 6 part roadmap to cover MVC fundamentals and implementing it with Entity Framework. Part 1 introduces MVC, defining the roles of models, views, and controllers. It explains how MVC separates the application into independent and reusable components for the model, views for presentation, and controllers for handling requests. This separation aims to improve maintainability and extensibility of applications.
This document discusses implementing security in a Web API using basic authentication and token-based authorization. It introduces basic authentication as a means of validating a user's credentials through a username and password sent in the request header. Token-based authorization is described as sending a token to authenticated users that allows them to access other resources. The document then outlines steps to create a user service, implement basic authentication using an authentication filter, and implement token-based authorization by setting up databases, services, and controllers and marking them with an authorization filter. Maintaining sessions with tokens is also briefly mentioned.
C sharp and asp.net interview questionsAkhil Mittal
The document provides summaries of common questions and answers related to ASP.NET, C#, and the .NET framework. It defines view state as storing the current property settings of an ASP.NET page and controls to detect form submissions. It explains that user controls allow reusing ASP.NET pages as controls, and validation controls perform input checking on server controls. The document also distinguishes between Response.Write and Response.Output.Write, and lists page life cycle methods like Init, Load, and Unload.
This document provides answers to common ASP.NET interview questions. It begins with questions about the differences between custom controls and user controls, ASP session state and ASP.NET session state, and datasets versus recordsets in ADO.NET. Subsequent questions cover topics like view state, authentication, caching, validation controls, and working with data controls.
Diving in OOP (Day 1) : Polymorphism and Inheritance (Early Binding/Compile T...Akhil Mittal
I have been writing a lot about advanced topics like MVC, Entity Framework, Repository Patterns etc., my priority always remains to cover the topic as a whole, so that a reader do not have to search for missing links anywhere else. My this article will cover almost every OOPS concept that a novice/beginner developer hunt for, and not only beginners, the article’s purpose is to be helpful to experience professionals also who need to sometimes brush-up their concepts or who prepare for interviews .
Diving in OOP (Day 6): Understanding Enums in C# (A Practical Approach)Akhil Mittal
My article of the series “Diving in OOP” will explain enum datatype in C#. We’ll learn by doing hands on lab and not only by theory. We’ll explore the power of enum and will cover almost every scenario in which we can use enum. We’ll follow a practical approach of learning to understand this concept. We may come across complex examples to understand the concept more deeply.
Diving into OOP (Day 5): All About C# Access Modifiers (Public/Private/Protec...Akhil Mittal
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.
Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time...Akhil Mittal
The document discusses runtime polymorphism in C# using method overriding. It shows how to override methods in a derived class by marking the base class methods as virtual and using the override keyword in the derived class. An experiment is conducted where calling a method on an object initialized as the base class but actually referring to a derived class instance results in the overridden method from the derived class being called due to runtime binding.
Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time...
RESTful Day 6
1. RESTful Day #6: Request logging and
Exception handing/logging in Web APIs
using Action Filters, Exception Filters
and NLog. – Akhil Mittal, Sachin Verma
Table of Contents
Table of Contents _____________________________________________________________ 1
Introduction _________________________________________________________________ 2
Roadmap ___________________________________________________________________ 2
Request Logging______________________________________________________________ 3
Setup NLog in WebAPI ______________________________________________________________ 4
Step 1: Download NLog Package ______________________________________________________________ 5
Step 2: Configuring NLog ____________________________________________________________________ 6
NLogger Class _____________________________________________________________________ 8
Adding Action Filter _______________________________________________________________ 11
Step 1: Adding LoggingFilterAttribute class ____________________________________________________ 11
Step 2: Registering Action Filter (LoggingFilterAttribute)__________________________________________ 12
Running the application_______________________________________________________ 13
Exception Logging ___________________________________________________________ 22
Implementing Exception logging _____________________________________________________ 22
Step 1: Exception Filter Attribute ____________________________________________________________ 22
Step 2: Modify NLogger Class _______________________________________________________________ 24
Step 3: Modify Controller for Exceptions ______________________________________________________ 25
Step 4: Run the application _________________________________________________________________ 26
Custom Exception logging _____________________________________________________ 30
JSon Serializers ___________________________________________________________________ 35
Modify NLogger Class______________________________________________________________ 36
Modify GlobalExceptionAttribute ____________________________________________________ 38
Modify Product Controller__________________________________________________________ 39
Run the application _______________________________________________________________ 40
Update the controller for new Exception Handling ______________________________________ 44
Product Controller ________________________________________________________________________ 45
2. Conclusion__________________________________________________________________ 47
Other Series ___________________________________________ Error! Bookmark not defined.
Introduction
We have been learning a lot about WebAPI, its uses, implementations, and security aspects
since last five articles of the series. The article is also written and compiled by my co-author
Sachin Verma. This article of the series will explain how we can handle requests and log them
for tracking and for the sake of debugging, how we can handle exceptions and log them. We’ll
follow centralized way of handling exceptions in WebAPI and write our custom classes to be
mapped to the type of exception that we encounter and log the accordingly. I’ll use NLog to log
requests and exceptions as well. We’ll leverage the capabilities of Exception Filters and Action
Filters to centralize request logging and exception handling in WebAPI.
Roadmap
Following is the roadmap I have setup to learn WebAPI step by step,
3. RESTful Day #1: Enterprise-level application architecture with Web APIs using Entity
Framework, Generic Repository pattern and Unit of Work.
RESTful Day #2: Inversion of control using dependency injection in Web APIs using Unity
Container and Bootstrapper.
RESTful Day #3: Resolve dependency of dependencies using Inversion of Control and
dependency injection in ASP.Net Web APIs with Unity Container and Managed Extensibility
Framework (MEF).
RESTful Day #4: Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web
APIs.
RESTful Day #5: Basic Authentication and Token-based custom Authorization in Web
APIs using Action Filters.
RESTful Day #6: Request logging and Exception handing/logging in Web APIs using Action
Filters, Exception Filters and nLog.
RESTful Day #7: Unit testing ASP.Net Web API controllers using nUnit.
RESTful Day #8: Extending OData support in ASP.Net Web APIs.
I’ll purposely use Visual Studio 2010 and .net Framework 4.0 because there are few
implementations that are very hard to find in .Net Framework 4.0, but I’ll make it easy by
showing how we can do it.
Request Logging
Since we are writing web services, we are exposing our end points. We must know where the
requests are coming from and what requests are coming to our server. Logging could be very
beneficial and helps us in a lot of ways like, debugging, tracing, monitoring and analytics.
4. We already have an existing design. If you open the solution, you’ll get to see the structure as
mentioned below or one can also implement this approach in their existing solution as well,
Setup NLog in WebAPI
NLog serves various purposes but primarily logging. We’ll use NLog for logging into files and
windows event as well. You can read more about NLog at http://NLog-project.org/
One can use the sample application that we used in Day#5 or can have any other application as
well. I am using the existing sample application that we were following throughout all the parts
of this series. Our application structure looks something like,
5. Step 1: Download NLog Package
Right click WebAPI project and select manage Nuget Packages from the list. When the Nuget Package
Manager appears, search for NLog. You’ll get Nlog like shown in image below, just install it to our
project,
After adding this you will find following NLog dll referenced in your application –
6. Step 2: Configuring NLog
To configure NLog with application add following settings in our existing WebAPI web.config
file,
ConfigSection –
Configuration Section – I have added the <NLog> section to configuration and defined the path
and format dynamic target log file name, also added the eventlog source to Api Services.
7. As mentioned in above target path, I have also created to “APILog” folder in the base directory
of application –
8. Now we have configured the NLog in our application, and it is ready to start work for request
logging. Note that in the rules section we have defined rules for logging in files as well as in
windows events log as well, you can choose both of them or can opt for one too. Let’s start
with logging request in application, with action filters –
NLogger Class
Add a folder “Helpers” in the API, which will segregate the application code for readability,
better understanding and maintainability.
To start add our main class “NLogger”, which will responsible for all types of errors and info
logging, to same Helper folder. Here NLogger class implements ITraceWriter interface, which
provides “Trace” method for the service request –
#region Using namespaces.
using System;
9. using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Tracing;
using NLog;
using System.Net.Http;
using System.Text;
using WebApi.ErrorHelper;
#endregion
namespace WebApi.Helpers
{
/// <summary>
/// Public class to log Error/info messages to the access log file
/// </summary>
public sealed class NLogger : ITraceWriter
{
#region Private member variables.
private static readonly Logger ClassLogger = LogManager.GetCurrentClassLogger();
private static readonly Lazy<Dictionary<TraceLevel, Action<string>>> LoggingMap = new
Lazy<Dictionary<TraceLevel, Action<string>>>(() => new Dictionary<TraceLevel, Action<string>>
{ { TraceLevel.Info, ClassLogger.Info }, { TraceLevel.Debug, ClassLogger.Debug }, {
TraceLevel.Error, ClassLogger.Error }, { TraceLevel.Fatal, ClassLogger.Fatal }, { TraceLevel.Warn,
ClassLogger.Warn } });
#endregion
#region Private properties.
/// <summary>
/// Get property for Logger
/// </summary>
private Dictionary<TraceLevel, Action<string>> Logger
{
get { return LoggingMap.Value; }
}
#endregion
#region Public member methods.
/// <summary>
/// Implementation of TraceWriter to trace the logs.
/// </summary>
/// <param name="request"></param>
/// <param name="category"></param>
/// <param name="level"></param>
10. /// <param name="traceAction"></param>
public void Trace(HttpRequestMessage request, string category, TraceLevel level,
Action<TraceRecord> traceAction)
{
if (level != TraceLevel.Off)
{
if (traceAction != null && traceAction.Target != null)
{
category = category + Environment.NewLine + "Action Parameters : " +
traceAction.Target.ToJSON();
}
var record = new TraceRecord(request, category, level);
if (traceAction != null) traceAction(record);
Log(record);
}
}
#endregion
#region Private member methods.
/// <summary>
/// Logs info/Error to Log file
/// </summary>
/// <param name="record"></param>
private void Log(TraceRecord record)
{
var message = new StringBuilder();
if (!string.IsNullOrWhiteSpace(record.Message))
message.Append("").Append(record.Message + Environment.NewLine);
if (record.Request != null)
{
if (record.Request.Method != null)
message.Append("Method: " + record.Request.Method + Environment.NewLine);
if (record.Request.RequestUri != null)
message.Append("").Append("URL: " + record.Request.RequestUri +
Environment.NewLine);
if (record.Request.Headers != null && record.Request.Headers.Contains("Token") &&
record.Request.Headers.GetValues("Token") != null &&
record.Request.Headers.GetValues("Token").FirstOrDefault() != null)
message.Append("").Append("Token: " +
record.Request.Headers.GetValues("Token").FirstOrDefault() + Environment.NewLine);
11. }
if (!string.IsNullOrWhiteSpace(record.Category))
message.Append("").Append(record.Category);
if (!string.IsNullOrWhiteSpace(record.Operator))
message.Append(" ").Append(record.Operator).Append("
").Append(record.Operation);
Logger[record.Level](Convert.ToString(message) + Environment.NewLine);
}
#endregion
}
}
Adding Action Filter
Action filter will be responsible for handling all the incoming requests to our APIs and logging
them using NLogger class. We have “OnActionExecuting” method that is implicitly called if we
mark our controllers or global application to use that particular filter. So each time any action of
any controller will be hit, our “OnActionExecuting” method will execute to log the request.
Step 1: Adding LoggingFilterAttribute class
Create a class LoggingFilterAttribute to “ActionFilters” folder and add following code -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Filters;
using System.Web.Http.Controllers;
using System.Web.Http.Tracing;
using System.Web.Http;
using WebApi.Helpers;
namespace WebApi.ActionFilters
{
public class LoggingFilterAttribute : ActionFilterAttribute
{
12. public override void OnActionExecuting(HttpActionContext
filterContext)
{
GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new
NLogger());
var trace =
GlobalConfiguration.Configuration.Services.GetTraceWriter();
trace.Info(filterContext.Request, "Controller : " +
filterContext.ControllerContext.ControllerDescriptor.ControllerType.FullName
+ Environment.NewLine + "Action : " +
filterContext.ActionDescriptor.ActionName, "JSON",
filterContext.ActionArguments);
}
}
}
The LoggingFilterAttribute class derived from ActionFilterAttribute, which is
under System.Web.Http.Filters and overriding the OnActionExecuting method.
Here I have replaced the default “ITraceWriter” service with our NLogger class instance in the
controller’s service container. Now GetTraceWriter() method will return our instance
(instance NLogger class) and Info() will call trace() method of our NLogger class.
Note that the code below,
GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new
NLogger());
is used to resolve dependency between ITaceWriter and NLogger class. Thereafter we use a
variable named trace to get the instance and trace.Info() is used to log the request and
whatever text we want to add along with that request.
Step 2: Registering Action Filter (LoggingFilterAttribute)
In order to register the created action filter to application’s filters, just add a new instance of
your action filter to config.Filters in WebApiConfig class.
using System.Web.Http;
using WebApi.ActionFilters;
namespace WebApi.App_Start
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new LoggingFilterAttribute());
13. }
}
}
Now this action filter is applicable to all the controllers and actions in our project. You may not
believe but request logging is done. It’s time to run the application and validate our homework.
Image credit: https://pixabay.com/en/social-media-network-media-54536/
Running the application
Let’s run the application and try to make a call, using token based authorization, we have
already covered authorization in day#5. You first need to authenticate your request using login
service , and then that service will return a token for making calls to other services. Use that
token to make calls to other services, for more details you can read day5 of this series.
Just run the application, we get,
14. We already have our test client added, but for new readers, just go to Manage Nuget Packages,
by right clicking WebAPI project and type WebAPITestClient in searchbox in online packages,
You’ll get “A simple Test Client for ASP.NET Web API”, just add it. You’ll get a help controller in
Areas-> HelpPage like shown below,
15. I have already provided the database scripts and data in my previous article, you can use the same.
Append “/help” in the application url, and you’ll get the test client,
GET:
17. DELETE:
You can test each service by clicking on it. Once you click on the service link, you'll be redirected
to test the service page of that particular service.On that page there is a button Test API in the
right bottom corner, just press that button to test your service,
Service for Get All products,
18. In below case, I have already generated the token and now using it to make call to fetch all the
products from products table in database.
19. Here I have called allproducts API, Add the value for parameter Id and “Token” header with its
current value and click to get the result -
20. Now let’s see what happens to our APILog folder in application. Here you find the API log has
been created, with the same name we have configured in NLog configuration in web.config file.
The log file contains all the supplied details like Timestamp, Method type, URL , Header
information (Token), Controller name, action and action parameters. You can also add more
details to this log which you deem important for your application.
22. Exception Logging
Our logging setup is completed, now we’ll focus on centralizing exception logging as well, so that none
of the exception escapes without logging itself. Logging exception is of very high importance, it keeps
track of all the exceptions. No matter business or application or system exceptions , but all of them have
to be logged.
Implementing Exception logging
Step 1: Exception Filter Attribute
Adding an action filter in our application for logging the exceptions, for this create a class
GlobalExceptionAttribute to “ActionFilter” folder and add the code below, the class is derived
from ExceptionFilterAttribute, which is under System.Web.Http.Filters.
23. I have override OnException() method, and replaced the default “ITraceWriter” service with
our NLogger class instance in the controller’s service container, same as we have done in Action
logging in above section. Now GetTraceWriter() method will return our instance (instance
NLogger class) and Info() will call trace() method of NLogger class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Filters;
using System.Web.Http;
using System.Web.Http.Tracing;
using WebApi.Helpers;
using System.ComponentModel.DataAnnotations;
using System.Net.Http;
using System.Net;
namespace WebApi.ActionFilters
{
/// <summary>
/// Action filter to handle for Global application errors.
/// </summary>
public class GlobalExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext
context)
{
GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter
), new NLogger());
var trace =
GlobalConfiguration.Configuration.Services.GetTraceWriter();
trace.Error(context.Request, "Controller : " +
context.ActionContext.ControllerContext.ControllerDescriptor.Controlle
rType.FullName + Environment.NewLine + "Action : " +
context.ActionContext.ActionDescriptor.ActionName, context.Exception);
var exceptionType = context.Exception.GetType();
if (exceptionType == typeof(ValidationException))
{
var resp = new
HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new
StringContent(context.Exception.Message), ReasonPhrase =
"ValidationException", };
24. throw new HttpResponseException(resp);
}
else if (exceptionType ==
typeof(UnauthorizedAccessException))
{
throw new
HttpResponseException(context.Request.CreateResponse(HttpStatusCode.Un
authorized));
}
else
{
throw new
HttpResponseException(context.Request.CreateResponse(HttpStatusCode.In
ternalServerError));
}
}
}
}
Step 2: Modify NLogger Class
Our NLogger class is capable to log all info and events, I have done some changes in private
method Log() to handle the exceptions –
#region Private member methods.
/// <summary>
/// Logs info/Error to Log file
/// </summary>
/// <param name="record"></param>
private void Log(TraceRecord record)
{
var message = new StringBuilder();
if (!string.IsNullOrWhiteSpace(record.Message))
message.Append("").Append(record.Message +
Environment.NewLine);
if (record.Request != null)
{
if (record.Request.Method != null)
message.Append("Method: " + record.Request.Method +
Environment.NewLine);
25. if (record.Request.RequestUri != null)
message.Append("").Append("URL: " +
record.Request.RequestUri + Environment.NewLine);
if (record.Request.Headers != null &&
record.Request.Headers.Contains("Token") &&
record.Request.Headers.GetValues("Token") != null &&
record.Request.Headers.GetValues("Token").FirstOrDefault() != null)
message.Append("").Append("Token: " +
record.Request.Headers.GetValues("Token").FirstOrDefault() +
Environment.NewLine);
}
if (!string.IsNullOrWhiteSpace(record.Category))
message.Append("").Append(record.Category);
if (!string.IsNullOrWhiteSpace(record.Operator))
message.Append(" ").Append(record.Operator).Append("
").Append(record.Operation);
if (record.Exception != null &&
!string.IsNullOrWhiteSpace(record.Exception.GetBaseException().Message
))
{
var exceptionType = record.Exception.GetType();
message.Append(Environment.NewLine);
message.Append("").Append("Error: " +
record.Exception.GetBaseException().Message + Environment.NewLine);
}
Logger[record.Level](Convert.ToString(message) +
Environment.NewLine);
}
Step 3: Modify Controller for Exceptions
Our application is now ready to run, but there is no exception in our code, so I added a throw
exception code in ProductController, just the Get(int id) method so that it can throw exception
for testing our exception logging mechanism, It will throw an exception if the product is not
there in database with the provided id.
// GET api/product/5
26. [GET("productid/{id?}")]
[GET("particularproduct/{id?}")]
[GET("myproduct/{id:range(1, 3)}")]
public HttpResponseMessage Get(int id)
{
var product = _productServices.GetProductById(id);
if (product != null)
return Request.CreateResponse(HttpStatusCode.OK, product);
throw new Exception("No product found for this id");
//return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No
product found for this id");
}
Step 4: Run the application
Run the application and click on Product/all API
27. Add the parameter id value to 1 and header Token with it’s current value, click on send button
to get the result –
Now we can see that the Status is 200/OK, and we also get a product with the provided id in the
response body. Let’s see the API log now –
28. The log has captured the call of Product API, now provide a new product id as parameter, which
is not there in database, I am using 12345 as product id and result is –
29. We can see there is an 500/Internal Server Error now in response status, lets check the API Log-
Well, now the log has captured both the event and error of same call on the server, you can see
call log details and the error with provided error message in the log.
30. Custom Exception logging
In the above section we have implemented exception logging, but there is default system
response and status ( i. e. 500/Internal Server Error) , It will be always good to have your own
custom response and exceptions for your API. That will be easier for client to consume and
understand the API responses.
Step 1: Add Custom Exception Classes
Add “Error Helper” folder to application to maintain our custom exception classes separately
and add “IApiExceptions” interface to newly created “ErrorHelper” folder -
Add following code the IApiExceptions interface, this will serve as a template for all
exception classes, I have added four common properties for our custom classes to maintain
31. Error Code, ErrorDescription, HttpStatus (Contains the values of status codes defined for
HTTP) and ReasonPhrase.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace WebApi.ErrorHelper
{
/// <summary>
/// IApiExceptions Interface
/// </summary>
public interface IApiExceptions
{
/// <summary>
/// ErrorCode
/// </summary>
int ErrorCode { get; set; }
/// <summary>
/// ErrorDescription
/// </summary>
string ErrorDescription { get; set; }
/// <summary>
/// HttpStatus
/// </summary>
HttpStatusCode HttpStatus { get; set; }
/// <summary>
/// ReasonPhrase
/// </summary>
string ReasonPhrase { get; set; }
}
}
Here, I divided our exceptions in three categories
1. API Exceptions – for API level exceptions.
2. Business Exceptions – for exceptions at business logic level.
3. Data Exceptions – Data related exceptions.
To implement this create a three new classes ApiException.cs, ApiDataException.cs and
ApiBusinessException classes to same folder which implements IApiExceptions interface with
following code to the classes –
32. #region Using namespaces.
using System;
using System.Net;
using System.Runtime.Serialization;
#endregion
namespace WebApi.ErrorHelper
{
/// <summary>
/// Api Exception
/// </summary>
[Serializable]
[DataContract]
public class ApiException : Exception, IApiExceptions
{
#region Public Serializable properties.
[DataMember]
public int ErrorCode { get; set; }
[DataMember]
public string ErrorDescription { get; set; }
[DataMember]
public HttpStatusCode HttpStatus { get; set; }
string reasonPhrase = "ApiException";
[DataMember]
public string ReasonPhrase
{
get { return this.reasonPhrase; }
set { this.reasonPhrase = value; }
}
#endregion
}
}
I have initialized ReasonPhrase property with different default values in these classes to
differentiate the implementation, you can use implement your custom classes as per your
application needs.
The directives applied on class as Serializable and DataContract to make sure that the class
defines or implements a data contract is serializable and can be serialize by a serializer.
Note – Add reference of “System.Runtime.Serialization.dll” dll if you facing any assembly issue.
In the same way add “ApiBusinessException” and “ApiDataException” classes into the same
folder, with the following code –
33. #region Using namespaces.
using System;
using System.Net;
using System.Runtime.Serialization;
#endregion
namespace WebApi.ErrorHelper
{
/// <summary>
/// Api Business Exception
/// </summary>
[Serializable]
[DataContract]
public class ApiBusinessException : Exception, IApiExceptions
{
#region Public Serializable properties.
[DataMember]
public int ErrorCode { get; set; }
[DataMember]
public string ErrorDescription { get; set; }
[DataMember]
public HttpStatusCode HttpStatus { get; set; }
string reasonPhrase = "ApiBusinessException";
[DataMember]
public string ReasonPhrase
{
get { return this.reasonPhrase; }
set { this.reasonPhrase = value; }
}
#endregion
#region Public Constructor.
/// <summary>
/// Public constructor for Api Business Exception
/// </summary>
/// <param name="errorCode"></param>
/// <param name="errorDescription"></param>
/// <param name="httpStatus"></param>
public ApiBusinessException(int errorCode, string errorDescription,
HttpStatusCode httpStatus)
{
ErrorCode = errorCode;
ErrorDescription = errorDescription;
HttpStatus = httpStatus;
}
34. #endregion
}
}
#region Using namespaces.
using System;
using System.Net;
using System.Runtime.Serialization;
#endregion
namespace WebApi.ErrorHelper
{
/// <summary>
/// Api Data Exception
/// </summary>
[Serializable]
[DataContract]
public class ApiDataException : Exception, IApiExceptions
{
#region Public Serializable properties.
[DataMember]
public int ErrorCode { get; set; }
[DataMember]
public string ErrorDescription { get; set; }
[DataMember]
public HttpStatusCode HttpStatus { get; set; }
string reasonPhrase = "ApiDataException";
[DataMember]
public string ReasonPhrase
{
get { return this.reasonPhrase; }
set { this.reasonPhrase = value; }
}
#endregion
#region Public Constructor.
/// <summary>
/// Public constructor for Api Data Exception
/// </summary>
/// <param name="errorCode"></param>
/// <param name="errorDescription"></param>
/// <param name="httpStatus"></param>
public ApiDataException(int errorCode, string errorDescription,
HttpStatusCode httpStatus)
{
35. ErrorCode = errorCode;
ErrorDescription = errorDescription;
HttpStatus = httpStatus;
}
#endregion
}
}
JSon Serializers
There are some objects need to be serialized in json, to log and to transfer through the
modules, for this I have add some extension methods to Object class –
For that add “System.Web.Extensions.dll” reference to project and add “JSONHelper” class to
Helpers folder, with following code –
#region Using namespaces.
using System.Web.Script.Serialization;
using System.Data;
using System.Collections.Generic;
using System;
#endregion
namespace WebApi.Helpers
{
public static class JSONHelper
{
#region Public extension methods.
/// <summary>
/// Extened method of object class, Converts an object to a json string.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJSON(this object obj)
{
var serializer = new JavaScriptSerializer();
try
{
return serializer.Serialize(obj);
}
catch(Exception ex)
{
36. return "";
}
}
#endregion
}
}
In the above code “ToJSON()” method is an extension of base Object class, which serializes
supplied the object to a JSon string. The method using “JavaScriptSerializer” class which exist in
“System.Web.Script.Serialization”.
Modify NLogger Class
For exception handling I have modified the Log() method of NLogger, which will now handle the
different API exceptions.
/// <summary>
/// Logs info/Error to Log file
/// </summary>
/// <param name="record"></param>
private void Log(TraceRecord record)
{
var message = new StringBuilder();
if (!string.IsNullOrWhiteSpace(record.Message))
message.Append("").Append(record.Message +
Environment.NewLine);
if (record.Request != null)
{
if (record.Request.Method != null)
message.Append("Method: " + record.Request.Method +
Environment.NewLine);
if (record.Request.RequestUri != null)
message.Append("").Append("URL: " +
record.Request.RequestUri + Environment.NewLine);
if (record.Request.Headers != null &&
record.Request.Headers.Contains("Token") &&
record.Request.Headers.GetValues("Token") != null &&
record.Request.Headers.GetValues("Token").FirstOrDefault() != null)
message.Append("").Append("Token: " +
record.Request.Headers.GetValues("Token").FirstOrDefault() +
Environment.NewLine);
}
37. if (!string.IsNullOrWhiteSpace(record.Category))
message.Append("").Append(record.Category);
if (!string.IsNullOrWhiteSpace(record.Operator))
message.Append(" ").Append(record.Operator).Append("
").Append(record.Operation);
if (record.Exception != null &&
!string.IsNullOrWhiteSpace(record.Exception.GetBaseException().Message))
{
var exceptionType = record.Exception.GetType();
message.Append(Environment.NewLine);
if (exceptionType == typeof(ApiException))
{
var exception = record.Exception as ApiException;
if (exception != null)
{
message.Append("").Append("Error: " +
exception.ErrorDescription + Environment.NewLine);
message.Append("").Append("Error Code: " +
exception.ErrorCode + Environment.NewLine);
}
}
else if (exceptionType == typeof(ApiBusinessException))
{
var exception = record.Exception as ApiBusinessException;
if (exception != null)
{
message.Append("").Append("Error: " +
exception.ErrorDescription + Environment.NewLine);
message.Append("").Append("Error Code: " +
exception.ErrorCode + Environment.NewLine);
}
}
else if (exceptionType == typeof(ApiDataException))
{
var exception = record.Exception as ApiDataException;
if (exception != null)
{
message.Append("").Append("Error: " +
exception.ErrorDescription + Environment.NewLine);
message.Append("").Append("Error Code: " +
exception.ErrorCode + Environment.NewLine);
}
}
else
message.Append("").Append("Error: " +
record.Exception.GetBaseException().Message + Environment.NewLine);
}
38. Logger[record.Level](Convert.ToString(message) +
Environment.NewLine);
}
The code above checks the exception object of TraceRecord and updates the logger as per the
exception type.
Modify GlobalExceptionAttribute
As we have created GlobalExceptionAttribute to handle all exceptions and create response in
case of any exception. Now I have added some new code to this in order to enable the
GlobalExceptionAttribute class to handle custom exceptions. I am adding only modified method
here for your reference .
public override void OnException(HttpActionExecutedContext context)
{
GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new
NLogger());
var trace =
GlobalConfiguration.Configuration.Services.GetTraceWriter();
trace.Error(context.Request, "Controller : " +
context.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.F
ullName + Environment.NewLine + "Action : " +
context.ActionContext.ActionDescriptor.ActionName, context.Exception);
var exceptionType = context.Exception.GetType();
if (exceptionType == typeof(ValidationException))
{
var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
{ Content = new StringContent(context.Exception.Message), ReasonPhrase =
"ValidationException", };
throw new HttpResponseException(resp);
}
else if (exceptionType == typeof(UnauthorizedAccessException))
{
throw new
HttpResponseException(context.Request.CreateResponse(HttpStatusCode.Unauthori
zed, new ServiceStatus() { StatusCode = (int)HttpStatusCode.Unauthorized,
StatusMessage = "UnAuthorized", ReasonPhrase = "UnAuthorized Access" }));
}
else if (exceptionType == typeof(ApiException))
{
39. var webapiException = context.Exception as ApiException;
if (webapiException != null)
throw new
HttpResponseException(context.Request.CreateResponse(webapiException.HttpStat
us, new ServiceStatus() { StatusCode = webapiException.ErrorCode,
StatusMessage = webapiException.ErrorDescription, ReasonPhrase =
webapiException.ReasonPhrase }));
}
else if (exceptionType == typeof(ApiBusinessException))
{
var businessException = context.Exception as
ApiBusinessException;
if (businessException != null)
throw new
HttpResponseException(context.Request.CreateResponse(businessException.HttpSt
atus, new ServiceStatus() { StatusCode = businessException.ErrorCode,
StatusMessage = businessException.ErrorDescription, ReasonPhrase =
businessException.ReasonPhrase }));
}
else if (exceptionType == typeof(ApiDataException))
{
var dataException = context.Exception as ApiDataException;
if (dataException != null)
throw new
HttpResponseException(context.Request.CreateResponse(dataException.HttpStatus
, new ServiceStatus() { StatusCode = dataException.ErrorCode, StatusMessage =
dataException.ErrorDescription, ReasonPhrase = dataException.ReasonPhrase
}));
}
else
{
throw new
HttpResponseException(context.Request.CreateResponse(HttpStatusCode.InternalS
erverError));
}
}
In the above code I have modified the overrided method OnExeption() and created new Http
response exception based on the different exception types.
Modify Product Controller
Now modify the Product controller to throw our custom exception form, please look into the Get
method I have modified to throw the APIDataException in case if data is not found and APIException in
any other kind of error.
40. // GET api/product/5
[GET("productid/{id?}")]
[GET("particularproduct/{id?}")]
[GET("myproduct/{id:range(1, 3)}")]
public HttpResponseMessage Get(int id)
{
if (id != null)
{
var product = _productServices.GetProductById(id);
if (product != null)
return Request.CreateResponse(HttpStatusCode.OK, product);
throw new ApiDataException(1001, "No product found for this id.",
HttpStatusCode.NotFound);
}
throw new ApiException() { ErrorCode = (int)HttpStatusCode.BadRequest,
ErrorDescription = "Bad Request..." };
}
Run the application
Run the application and click on Product/all API -
41. Add the parameter id value to 1 and header Token with its current value, click on send button
to get the result –
42. Now we can see that the Status is 200/OK, and we also get a product with the provided id in the
response body. Lets see the API log now –
43. The log has captured the call of Product API, now provide a new product id as parameter, which
is not there in database, I am using 12345 as product id and result is –
We can see, now there is a custom error status code “1001” and messages “No product found
for this id.” And the generic status code “500/Internal Server Error” is now replaced with our
supplied code “404/ Not Found”, which is more meaningful for the client or consumer.
Lets see the APILog now -
44. Well, now the log has captured both the event and error of same call on the server, you can see
call log details and the error with provided error message in the log with our custom error code,
I have only captured error description and error code, but you can add more details in the log
as per your application needs.
Update the controller for new Exception Handling
Following is the code for controllers with implementation of custom exception handling and
logging –
45. Product Controller
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using AttributeRouting;
using AttributeRouting.Web.Http;
using BusinessEntities;
using BusinessServices;
using WebApi.ActionFilters;
using WebApi.Filters;
using System;
using WebApi.ErrorHelper;
namespace WebApi.Controllers
{
[AuthorizationRequired]
[RoutePrefix("v1/Products/Product")]
public class ProductController : ApiController
{
#region Private variable.
private readonly IProductServices _productServices;
#endregion
#region Public Constructor
/// <summary>
/// Public constructor to initialize product service instance
/// </summary>
public ProductController(IProductServices productServices)
{
_productServices = productServices;
}
#endregion
// GET api/product
[GET("allproducts")]
[GET("all")]
public HttpResponseMessage Get()
{
46. var products = _productServices.GetAllProducts();
var productEntities = products as List<ProductEntity> ??
products.ToList();
if (productEntities.Any())
return Request.CreateResponse(HttpStatusCode.OK,
productEntities);
throw new ApiDataException(1000, "Products not found",
HttpStatusCode.NotFound);
}
// GET api/product/5
[GET("productid/{id?}")]
[GET("particularproduct/{id?}")]
[GET("myproduct/{id:range(1, 3)}")]
public HttpResponseMessage Get(int id)
{
if (id != null)
{
var product = _productServices.GetProductById(id);
if (product != null)
return Request.CreateResponse(HttpStatusCode.OK,
product);
throw new ApiDataException(1001, "No product found for this
id.", HttpStatusCode.NotFound);
}
throw new ApiException() { ErrorCode =
(int)HttpStatusCode.BadRequest, ErrorDescription = "Bad Request..." };
}
// POST api/product
[POST("Create")]
[POST("Register")]
public int Post([FromBody] ProductEntity productEntity)
{
return _productServices.CreateProduct(productEntity);
}
// PUT api/product/5
[PUT("Update/productid/{id}")]
[PUT("Modify/productid/{id}")]
public bool Put(int id, [FromBody] ProductEntity productEntity)
{
if (id > 0)
{
return _productServices.UpdateProduct(id, productEntity);
}
return false;
}
47. // DELETE api/product/5
[DELETE("remove/productid/{id}")]
[DELETE("clear/productid/{id}")]
[PUT("delete/productid/{id}")]
public bool Delete(int id)
{
if (id != null && id > 0)
{
var isSuccess = _productServices.DeleteProduct(id);
if (isSuccess)
{
return isSuccess;
}
throw new ApiDataException(1002, "Product is already deleted
or not exist in system.", HttpStatusCode.NoContent );
}
throw new ApiException() {ErrorCode = (int)
HttpStatusCode.BadRequest, ErrorDescription = "Bad Request..."};
}
}
}
Now you can see, our application is so rich and scalable that none of the exception or
transaction can escape logging.Once setup is inplaced, now you don’t have to worry about
writing code each time for logging or requests and exceptions, but you can relax and focus on
business logic only.
Image credit: https://pixabay.com/en/kermit-frog-meadow-daisy-concerns-383370/
Conclusion
48. In this article we learnt about how to perform request logging and exception logging in WebPI. There
could be numerous ways in which you can perform these operations but I tried to present this in as
simple way as possible. My approach was to take our enterprise level to next level of development,
where developers should not always be worried about exception handling and logging. Our solution
provides a generic approach of centralizing the operations in one place; all the requests and exceptions
are automatically taken care of. In my new articles, I’ll try to enhance the application by explaining unit
testing in WebAPI and OData in WebAPI. You can download the complete source code of this article
with packages from GitHub. Happy coding
Other Series
My other series of articles:
Introduction to MVC Architecture and Separation of Concerns: Part 1
Diving Into OOP (Day 1): Polymorphism and Inheritance (Early Binding/Compile Time
Polymorphism)
For more informative articles visit my Blog.