Skip to main content

Lessons from Django

I already have experience with the MVC paradigm through previous websites I've built with Django, Flask, and FastAPI.

  • .NET supports hot reload from v6.0

Razor Scaffolds vs Django Templates​

  • Razor Pages: HTML template page with associated C#
    • Layouts: The layout page controls the layout of each page
      • Imports HTML, Javascript and StyleSheets
      • Rendered where @RenderBody() is called
      • Layout property is set in Pages/_ViewStart.cshtml
    • Partials:
    • Templates:
    • Tag Helpers: Enable server-side code to render HTML. Denoted by the @ prefix in the .cshtml file
  • cshtml files : Markup engine language for the razor engine used to render serverside HTML pages. Consider these the equivalent to template files in Django or Jinja2.
    • cshtml.cs files:
    • @page and @model YourApp.Pages.YourFolder.YourPage directives transition html to razor page
      • @page : Can pass in route params
      • @model YourApp.Pages.YourFolder.YourPage specifies the type of model that is passed to the page
  • @RenderBody : placeholder where all the page-specific views show up, wrapped in the layout page
  • @{...} : The { and } characters enclose a block of c# code
    • Can iterate using forloops using @for
      • for loops can iterate over data in the ViewData directory. HTML elements are implicitly returned
  • The ViewData dictionary : K/V store that passes data to the view
  • @namespace Set the namespace in the template
    • Should I structure namespace based on file structure?

Razor Page Models​

Implementation of the Page Controller pattern, where there is a one-to-one mapping between pages and their controllers

  • public IActionResult OnGet(): Initializes state for the page
  • public async Task<IActionResult> OnPostAsync: Run when the page posts form data
  • Page() method: Creates a PageResult object that renders the .cshtml page

Nuget vs pip requirements.txt package managers​

  • Make sure to install versions that are compatible with your dependencies (e.g. .NET version, C# version, etc.)

Models and migrations​

Data Annotations: We can apply data annotations to model fields using attributes in the form of [Annotation] DataType varName

  • Validation with Data Annotation Validators
    • Example validators include:
      • [Required], [StringLength], [RegularExpression], [Range]
  • [Display] attribute: Specifies display name of a field
  • [DataType] attribute: Specifies the type of data

Migrations

# goto Tools > NuGet Package Manager > Package Manager Console
# run in shell: InitialCreate is the name of our first migration. Change the name to whatever the name of your migration will be
Add-Migration InitialCreate
Update-Database

Data context : entry point for the LINQ to SQL framework.

How to set database connections?

  • Use ConnectionStrings in appsettings.json

Databases​

LocalDB: Lightweight user-mode database for dev environment SQL Server Object Explorer (SSOX):

  • Equivalent to admin console in Django
  • Hotkey: Ctrl + \ + Ctrl + SLINQ Queries:
  • LINQ queries are lazily evaluated
  • Can construct lambda expressions on LINQ queries such as conditional filters

How to relate the following to transactions?

  • Db Context:
  • EntityState
  • context.Entry(...).State

Atomic Operations

We need to ensure atomic database operations to prevent race conditions

Pessimistic concurrency: Use database locks to prevent concurrency conflicts

  • con: Complex to implement, performance degrades as users increase Optimistic concurrency: Allows concurrency conflicts to happen, then reacts to rectify them
  • Types of error recovery include:
    • Store-Wins scenario: Data store values take precendence and user is given an error on conflict
    • Client-Wins / Last-In-Wins: Final write overwrites the preceeding writes
    • Managing state for each transaction and db column: Unpractical to implement due to requirement of managing too much state
  • How are conflicts detected?
    • Concurrency token: Property that tracks queries and emits a conflict on update or delete during SaveChanges()
      • Operation can complete if the values match, otherwise throw a DbUpdateConcurrencyException

Database transactions

Atomic workflow using Optimistic Concurrency:

Async Methods:

  • Async methods are the default for .NET Core and EF Core
    • Database action statements are executed asynchronously (not the lazily evaluated operations)
    • EF Core context is not thread safe
    • Verify library packages use async if they call EF Core methods that send queries to the db

Entity Framework​

I am putting model attribute conditions in the models section of the MVC WebAPI page

Entity Framework Core is an ORM for the .NET Core ecosystem

  • Use cases include:
    • Handling network connections and intermediate data
    • Generates SQL and maps data back to POCO (plain old CLR object)
    • Abstraction to allow LINQ queries to work on databases

Ideas in EF Core:

  • Entity: .NET class mapped by EF core to the database

  • Database Context: DbContext used to configure EF core and access the database at runtime

    • Can have multiple DbContext(s) and integrate with different databases in one application
  • DbSet properties on the DbContext are added to the internal model --> Presents the collection of all entities in the context

    • So you don't have to manually add every entity to the model using DbSet as it finds them based on relationships between entities. However, it's best practice to expose a DbSet for each entity if you want to query on them.
  • Visual studio makes creating CRUD APIs very easy. Just define a model then create a scaffold item to controller

    • Default CRUD create scaffold is vulnerable to overposting (changing form inputs to post to fields that should not be updated)
    • Use TryUpdateModelAsync to stop overposting on Edit
    • In MVC --> Bind attribute prevents overposting on create by limiting postable fields
      • Note that BIND clears out existing fields that are not bound, so the TryUpdateModel --> SaveChanges method is recommended for edits

Entity States: What records should be updated on SaveChanges()

  • Added state: Mapped to INSERT
  • Unchanged state: starting state
  • Modified state: Mapped to UPDATE
  • Deleted state: Mapped to DELETE
  • Detached state: Isn't tracked by db context

EF Core Internal Model

Authentication​

Input Validation​

Sanitization

Validate argument against expected format

Handling errors appropriately (see exceptions section)

Exceptions​

HTTP default status codes Types of errors:

  • Upstream errors
  • Validation errors
  • Business logic errors
  • 500 errors

Testing​

Integration testing --> We write these

Performance Monitoring​

Should I use the same techniques?

Documentation​

Plan is to currently add it in the docs repository

Security​

  • TODO:

OData and REST API spec​

Logging​