ASP.NET 8 Best Practices - Jonathan R. Danylko - E-Book

ASP.NET 8 Best Practices E-Book

Jonathan R. Danylko

0,0
28,99 €

oder
-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

As .NET 8 emerges as a long-term support (LTS) release designed to assist developers in migrating legacy applications to ASP.NET, this best practices book becomes your go-to guide for exploring the intricacies of ASP.NET and advancing your skills as a software engineer, full-stack developer, or web architect.
This book will lead you through project structure and layout, setting up robust source control, and employing pipelines for automated project building. You’ll focus on ASP.NET components and gain insights into their commonalities. As you advance, you’ll cover middleware best practices, learning how to handle frontend tasks involving JavaScript, CSS, and image files. You’ll examine the best approach for working with Blazor applications and familiarize yourself with controllers and Razor Pages. Additionally, you’ll discover how to leverage Entity Framework Core and exception handling in your application. In the later chapters, you’ll master components that enhance project organization, extensibility, security, and performance.
By the end of this book, you’ll have acquired a comprehensive understanding of industry-proven concepts and best practices to build real-world ASP.NET 8.0 websites confidently.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Veröffentlichungsjahr: 2023

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



ASP.NET 8 Best Practices

Explore techniques, patterns, and practices to develop effective large-scale .NET web apps

Jonathan R. Danylko

BIRMINGHAM—MUMBAI

ASP.NET 8 Best Practices

Copyright © 2023 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Group Product Manager: Rohit Rajkumar

Publishing Product Manager: Jane D’Souza

Senior Editor: Aamir Ahmed

Book Project Manager: Sonam Pandey

Technical Editor: Simran Ali

Copy Editor: Safis Editing

Proofreader: Safis Editing

Indexer: Manju Arasan

Production Designer: Prashant Ghare

DevRel Marketing Coordinator: Nivedita Pandey

First published: December 2023

Production reference: 1011223

Published by Packt Publishing Ltd.

Grosvenor House

11 St Paul’s Square

Birmingham

B3 1RB, UK

ISBN 978-1-83763-212-1

www.packtpub.com

To my family, for their continued support throughout my career (even though I tend to live in the office).

To my colleagues and mentors: this book is a culmination of our discussions, experiences, and solutions (and some fires) we’ve encountered over the years.

To my readers and supporters on DanylkoWeb.com, who allow me to turn their questions into blog posts to further everyone’s knowledge in the end.

Finally, to my parents, who bought me that Commodore VIC-20 when I was 11, which started me on my journey of building software.

–Jonathan

Contributors

About the author

Jonathan R. Danylko is an award-winning web architect who works at Insight, an international company providing enterprise-level solutions. He started development at age 11 with a Commodore VIC-20. He has competed in international programming competitions and has contributed to various publications as an author and technical editor. His career spans 25 years of building internet and intranet websites for small, medium, and Fortune 500 companies, since 1996. He also created, developed, and maintains a blog called DanylkoWeb.com and has been writing blog posts since 2006. Jonathan continues to write code on a daily basis in his personal and professional career.

About the reviewers

Matthew D. Groves is a guy who loves to code. It doesn’t matter whether it’s C#, jQuery, or PHP: he’ll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent’s pizza shop back in the 90s. He currently works for Couchbase, helping developers in any way he can. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, co-author of Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.

Abdulkabir Abdulwasiu is a dedicated individual from Nigeria, holding a bachelor’s degree in mathematics and education. My journey led me to the Federal University of Technology Minna, honing my skills in this specialization. Further education at Nigeria Defense Academy earned me a post-graduate diploma in computer science, igniting my passion for its dynamic potential.

As a classroom teacher for over four years, I’ve inspired young minds through math education. In 2021, I began a software developer role at Vatebra Limited, driving tech innovation in Nigeria. Proficient in C# and .NET, I leverage technology for positive change.

My commitment to learning extends beyond teaching and coding. As a research assistant with Ph.D. students, I explore uncharted territories, refining my research skills. This journey encapsulates my dedication to growth and contributing to cutting-edge academia.

I would like to express my gratitude to my mentors, colleagues, and family for their unwavering support. Their guidance has been invaluable in shaping my journey as an educator, researcher, and software developer. Their belief in my potential has inspired me to reach new heights, and for that, I am truly thankful.

Table of Contents

Preface

1

Taking Control with Source Control

Technical requirements

Branching Strategies

GitFlow

Hotfix branches

GitHub Flow

GitLab Flow

Creating short-lived branches

Understanding Common Practices

Rebase when Private, Merge when Public

Always “Get Latest” Before Committing

Always Build and Test Before Committing

Avoid Committing Binaries

Use tags for versioning

Summary

2

CI/CD – Building Quality Software Automatically

Technical requirements

What is CI/CD?

Preparing your Code

Building Flawlessly

Avoiding Relative Path Names with File-based Operations

Confirming that your Unit Tests are Unit Tests

Creating Environment Settings

Understanding the Pipeline

Pulling Code

Building the application

Running Unit Tests/Code Analysis

Creating Artifacts

Creating a Container

Deploying the software

The Two “Falling” Approaches

Falling Backward (or fallback)

Falling Forward

Deploying Databases

Backing up Before Deploying

Creating a Strategy for Table Structures

Creating a Database Project

Using Entity Framework Core’s Migrations

The three Types of Build Providers

CI/CD Providers

Microsoft Azure Pipelines

GitHub Actions

Amazon CodePipeline

Google CI

Walkthrough of Azure Pipelines

Preparing the Application

Introducing Azure Pipelines

Identifying the Repository

Creating the Build

Creating the Artifacts

Creating a Release

Deploying the Build

Summary

3

Best Approaches for Middleware

Technical requirements

Using Middleware

Understanding the Middleware Pipeline

Using Request Delegates – Run, Use, and Map

Common Practices for Middleware

Defer to Asynchronous

Prioritizing the Order

Consolidating existing Middleware

Encapsulating your Middleware

Creating an Emoji Middleware Component

Encapsulating the Middleware

Examining the Component’s Pipeline

Summary

4

Applying Security from the Start

Technical requirements

Developing Security

Do I have any sensitive data to protect?

Am I exposing anything through the application?

Am I sanitizing user input?

Securing Access

Common Security Practices

Logging

Keep your Framework and Libraries Current

Always Force SSL

Never Trust the Client

Always Encode User Input

Securing Your Headers

Securing Entity Framework Core

Use Microsoft Entra for Securing Applications

Protecting Your Pages with Anti-Forgery

Safeguarding Against the Top 3 Security Threats

Broken Access Control

Cryptographic Failures

Injection

Summary

5

Optimizing Data Access with Entity Framework Core

Technical requirements

Entity Framework Core Implementations

Repository/Unit of Work

The Specification Pattern

Extension Methods

Common Entity Framework Core Practices

Confirming Your Model

Using Async/Await

Logging Your Queries

Using Resources for Large Seed Data

Understanding Deferred Execution

Using a Read-Only State with .AsNoTracking()

Leveraging the Database

Avoiding the Manual Property Mapping

Implementing the Theme Park Example

Overview

Creating the Database

Adding an Asynchronous Read-Only Mode

Including Child Entities

Extending your Model

Summary

6

Best Practices with Web User Interfaces

Technical requirements

Using a task runner

What is a task runner?

Setting up the Task Runner

Structure of a gulpfile

Running automatically

Creating a workflow structure

Defining our workflow paths

Transpiling TypeScript

Bundling and minifying

Implementing additional tasks

Applying standards to UIs

Centralizing your site links

Keeping controllers/pages small

Using ViewComponents

Using Tag Helpers instead of HTML Helpers

Creating SEO-friendly URLs

Introducing Buck’s coffee shop project

Setting up Buck’s website

Updating the links

Creating an OffCanvas Tag Helper

Summary

7

Testing Your Code

Technical requirements

Understand testing concepts

Unit tests

Integration tests

Regression tests

Load testing

System testing (end-to-end or E2E)

UI testing

Best approaches for testing

Why do we write tests?

The “100% test coverage” myth

Using AAA

Avoid writing unit test code for your code

Avoid large unit tests

Avoid unnecessary mocks, fakes, or stubs

Using tests as documentation

Identifying slow integration tests

Find a bug, write a test

Avoid testing .NET

Testing data access

Adding the SQLite provider

Creating the AttractionService test

Creating the LocationService test

Summary

8

Catching Exceptions with Exception Handling

Technical requirements

Using exception handling

What is exception handling?

When to use exception handling

Handling global exceptions

Performance considerations

Common exception handling techniques

Prevention before exception

Use logging

Apply a unit testing methodology

Avoid empty catch statements

Use exception filtering and pattern matching

Use finally blocks for cleanup

Knowing when to throw

Summary

9

Creating Better Web APIs

Technical requirements

Creating APIs quickly

Using Visual Studio

Why minimal APIs?

Designing APIs

Disconnecting from existing schemas

Identifying the resources

Relating HTTP verbs to resources

Returning HTTP status codes

Testing Web APIs

Visual Studio Endpoints Explorer

Integration testing APIs

Standardized Web API techniques

Using the right HTTP verbs and status codes

Beware dependent resources

Pagination in API results

Versioning APIs

Use DTOs, not entities!

Avoid new instances of HttpClient

Summary

10

Push Your Application with Performance

Technical requirements

Why Performance Matters

Establishing Baselines

Using Client-Side Tools

Using Server-Side Tools

Databases

Applying Performance Best Practices

Optimizing client-side performance

Common Server-side Practices

Understanding caching

Summary

11

Appendix

Technical requirements

Programming guidelines

DRY

YAGNI

KISS

Separation of concerns

Refactoring as a process

SOLID principles

Project structure

Understanding the project landscape

Creating project layers

Summary

Thank you!

Index

Other Books You May Enjoy

1

Taking Control with Source Control

Source control is a developer’s best friend and provides them with a way to experiment with code without losing important changes. Source control is the ability to track and maintain changes made to code throughout a development process. While this could include code, it can also be used for documentation, assets (such as images), and other resources. Being able to test certain conditions and the ability to refactor code without worrying about the code base is what most developers consider a superpower.

Source control is extremely important when working in a team environment. If a developer checks in code and later realizes they made a mistake, source control gives developers a way to revert changes or update a branch and re-commit. Companies not using some type of source control almost always raises a red flag.

In this chapter, we’ll look at common practices developers use in the industry when using source control. We’ll also cover various ways to implement branching workflows for your code as well as examine the different types of branches in each workflow. To finish off the chapter, we’ll review common etiquette among developers when using source control.

In this chapter, we’re going to cover the following topics:

Branching StrategiesCreating short-lived branchesAlways “Get Latest” Before Committing Understanding Common Practices

By the end of this chapter, you’ll have learned the best approach to creating a repository of your code in an organized fashion, along with common guidelines in the developer community.

Technical requirements

While this section touches on a number of guidelines regarding source control, the only requirement for this chapter is a computer with any OS. Git is optional.

If you don’t have Git installed, you can download and install it at the following URL:

https://git-scm.com/

We have used mermaid-js to visually show the branching strategies. As of February 2022, GitHub pages now support Mermaid-js. Some of the sections will include mermaid diagrams to demonstrate the different branching hierarchies.

For more information on Mermaid-js, navigate to the following URL:

https://mermaid-js.github.io

Branching Strategies

In this section, we’ll explore various branching strategies, explaining how each one works, and highlighting the differences between them.

While every company has its unique workflow, we’ll focus on some commonly used strategies in the industry.

With GitFlow being the initial workflow, everyone is familiar with it in the industry and its successors have improved by making minor changes to the workflow.

In the next sections, we’ll discuss each workflow, but first, we have to understand the fundamentals of GitFlow.

GitFlow

One of the most common and most mature workflows in the industry is GitFlow. It was created by Vincent Driessenin 2010.

A minimal Git repository should have the following branches:

main/master/trunk (referred to as main from this point on)develop

The main branch is what you start with when creating a new repository. The purpose of this branch is to always have stable and production-ready code for release at any time.

The develop branch is for writing new code and preventing untested code from being merged into main.

If you’re a standalone developer working on a side project, this may be a suitable workflow. If everything works in develop, you merge your changes into main and deploy your first version.

The good news is you can evolve your branching hierarchy even further. You can easily create additional branches, such as feature, release, or hotfix branches, for a better workflow, which we’ll cover later.

Keep in mind that each branching workflow discussed as follows allows any team, whether it’s 1 developer or 50 developers, to have a solid understanding of GitFlow.

In any source control system, there are usually three types of branches used to assist with managing a software workflow: feature, release, and hotfix branches.

Feature Branches

Feature branching isolates a new feature into a single branch so a developer can write code without worrying about affecting the core code in the develop branch.

In the following example (see Figure 1.1), a team created a GitHub repository. It called its primary branch main and the development branch develop.

Figure 1.1: Feature branches in GitFlow

Once everyone received their tasks, one developer was assigned to create the Settings feature. He created a branch called feature/settings from the develop branch.

Another developer was assigned the Printing feature and created a feature/printing branch also from the develop branch.

Naming Branches

Apart from the standardized main and develop branches, one common way to name branches is to prefix the names. Some examples include the following:

* feature/, features/, or feature-: The branch name should be as descriptive and helpful as possible. For example, feature/1234-settings relates to the Settings feature and includes a task number to reference for possible requirements. Another common method is to use the names or initials of who’s assigned to the feature (feature/jd-settings).

* "bug/<userstory/task number>-<problem>/": This example is helpful for immediately identifying bugs. An example of this technique could be bug/1234-string-overflow. Prefixing a branch with “bugfix” is also acceptable.

Once they are finished and everything’s approved, each developer merges their changes into the develop branch.

Release Branches

Release branches are meant for last-minute polishing, minor bug fixes, and/or preparing for a new release of your software (how exciting!)

Let’s examine how a release branch fits into our previous example. The following diagram shows what a release branch in GitFlow looks like:

Figure 1.2: Release branch in GitFlow

Initially, developers create a feature branch based on what they were assigned. Once they merge their changes to develop, a new release is created from the develop branch. The release branch is merged into main and tagged with the version number. The main branch will now merge into the develop branch so developers have the latest changes in case there were code changes during the release process.

It’s exactly the same as the feature branch, but if you notice, we’re creating the release branch from the develop branch and not from the main branch.

After the release branch is created and confirmed to work as expected, the release branch is merged into the main branch.

Once merged into main, it’s recommended to somehow identify a successful release. By convention, a tag with the version number is the best approach.

Hotfix branches

While most developers don’t make coding mistakes (uh-huh), there are times when immediate changes are required to the main branch.

Going back to our example, it seems there was a problem with a developer’s code. The application bombs when anyone selects the Settings option, making the application unusable. It requires a hotfix branch.

The following diagram shows an example of how to implement a hotfix branch:

Figure 1.3: Hotfix branch in GitFlow

Hotfix branches are created from the main branch and, once the code is verified, need to be merged back into main and also the develop branch.

The long-running branches in GitFlow are main and develop. The short-lived branches include the features, hotfix, and bugfix branches.

Now that we’ve covered GitFlow and its branch types, we’ll look at the next workflow, called GitHub Flow, and how it’s different from GitFlow.

GitHub Flow

Over time, GitFlow has evolved into easier workflows. The first of these workflows was GitHub Flow, which was created in 2011.

GitHub Flow was meant to simplify things by removing the develop branch and creating features off the main branch.

The following diagram shows how feature branches work along with a hotfix branch.

Figure 1.4: Hotfix branch in GitHub flow

In Figure 1.4, two features were created and both features were merged back into main. Immediately, version 1.0.0 was released. After the release of 1.0.0, some text was wrong on the site and the legal team requested for it to be fixed.

One of the developers created a hotfix branch, changed the label, requested a PR, got it approved, merged the change into main, updated the version, and immediately deployed the code to production.

What’s the difference between a hotfix and a feature branch? A hotfix is a branch created from main/master, with the code checked in, reviewed, updated, and immediately merged back into main/master. A feature branch is more of an organized or scheduled approach. The feature branch is created from the develop branch, with the code checked in, reviewed, and merged back into the feature branch. The feature branch is scheduled to be merged into a release branch.

So, where is the release branch? In each workflow, there is a release branch of some kind, which we’ll review as follows. The concept of this branch is to always have a version error-free, tested, and ready to deploy at any time. Some small start-up companies use this type of workflow when starting out. With GitFlow considered as a baseline in the industry, it’s easy to apply the GitFlow concepts when the team grows and is looking for a more structured workflow.

In GitHub flow, the long-running branch here is, again, main, where the short-lived branches are the features, hotfix, and bugfix branches.

After reviewing GitHub flow, let’s move on to the last commonly used branching strategy, called GitLab Flow.

GitLab Flow

The final workflow that we’ll cover is GitLab Flow. Created in 2014, GitLab Flow takes a different approach to the GitFlow workflow and combines feature branches with issue tracking using feature-driven development.

GitLab Flow takes release branches and turns them into stable environment branches, such as production and QA. Of course, you can create as many “environment branches” as necessary. If we had a QA environment branch, this may be used to test the final product. In Figure 1.5, we see the standard feature branches created from the main branch along with two other environment branches (pre-production and production).

Figure 1.5: GitLab Flow

In GitLab Flow, main is considered a testing branch. Whether it’s QA or a manager, it’s a place to test the feature branches.

Similar to GitHub Flow, everything merges into the main branch. When the feature branch is committed, code reviews are conducted (these are mandatory), and merged to main, all tests (yes, all) run. If the tests run for longer than five minutes, configure them to run in parallel.

Once the testing is complete in main, main is pushed to pre-production for further testing and, finally, pushed to production. Since releases in GitLab Flow are based on tags, each tag should create a new release.

If a developer introduced a bug, it would have to be fixed in main first, then the environment branches second. The developer would have to create a bugfix branch, commit with a PR approval, conduct a code review, and merge the code along with running tests related to the bug before they could continue through the workflow.

Once tested in main, it’s tagged and automatically promoted to pre-production and then production. Long-running branches in this workflow include main and the environment branches. Short-lived branches are the features, hotfix, and bugfix branches.

With each strategy we discussed in this section, we’ve seen how each one evolved from the initial GitFlow and (excuse the pun) branched into a better workflow.

The next sections refer to common etiquette when using source control.

Creating short-lived branches

Once you have initialized your repository and created your first branch, you can start writing code for your feature.

While this is exciting, this guideline is meant more for teams as opposed to an individual building a side project. The larger the team, the more critical this becomes to your workflow.

Let’s look at an example using multiple feature branches in Figure 1.6.