Breakpoint in ASP.NET MVC View not hit when using RazorGenerator

If your breakpoints in an ASP.NET MVC view are not hit: Check if you are using RazorGenerator for this particular view:

Screenshot of ASP.NET MVC view Properties. Custom tool set to RazorGenerator
RazorGenerator enabled for ASP.NET MVC view

Fix: Temporarily disable Razor Generator removing the “RazorGenerator” text from the Custom Tool property. Make sure to put it back in after your debugging session.

 

Change of connection string in deployed WEB.CONFIG overridden by Application setting

I just had an issue with a deployed ASP.NET app on Azure: I changed the connection string in the deployed web.config using the new App Service Editor in the Azure Portal, but the changes had no effect in my application!

This answer from StackOverflow gave me the hint I needed: My connection string was being overridden by an Application Setting in the Azure App Service. I didn’t even know that it was configured.

To see if you have a connection string defined in your Azure App service log into the Azure Portal, open your App Service and go to Settings -> Application Settings -> Connection strings.

Fixes

  1. Delete the connection string in the Azure application settings. Now you can change the connection string in the web.config using the App Service Editor, for example.
  2. Use the Azure application settings to manage your connection strings. The values defined here will always override the connection strings from your web.config.

Show PDF in browser instead of downloading (ASP.NET MVC) without JavaScript

If I want to display a PDF file in the browser instead of downloading a copy, I can tell the browser via an additional Content-Disposition response header.

This code example assumes that the file content is available as byte-array, reading the content from a database, for example.

// Get action method that tries to show a PDF file in the browser (inline)
public ActionResult ShowPdfInBrowser()
{
  byte[] pdfContent = CodeThatRetrievesMyFilesContent();

  if (pdfContent == null)
  {
    return null;
  }

  var contentDispositionHeader = new System.Net.Mime.ContentDisposition
  {
    Inline = true,
    FileName = "someFilename.pdf"
  };

  Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString());
  return File(pdfContent, System.Net.Mime.MediaTypeNames.Application.Pdf);
}

Please keep in mind that ultimately we don’t have control over the browser. We can politely request to show the PDF inline, but this can be overridden by a user configuration, for example.

Azure App Service: View and Edit the deployed web.config with Kudu

We can use the Azure Portal and Kudu to view and edit the web.config of our deployed app in the App Service:

  • Open the App Service you want to using the Azure web portal.
  • Goto “DEVELOPMENT TOOLS” -> “Advanced Tools” and click on the “Go ->” link.

  • Above the console use the file explorer to navigate to the “site/wwwroot” folder

  • Scroll down and click the pencil icon to open the file

  • You should see the file content in the editor:

Be careful, saved changes have immediate effect and you should absolutely know what you are doing when on a production system!

Security resources for .NET web applications

A collection of web app security links with focus on ASP.NET:

OWASP – The Open Web Application Security project is a worldwide community of professionals interested in security and a good starting point for securing your web apps. Some of the topics: Vulnerability, .NET ProjectCheat sheets, .NET Security Cheat Sheet.

ASP.NET MVC Guidance: Security, Authentication and Authorization  (ASP.NET site)

Security, Authentication, and Authorization in ASP.NET Web API (MS Docs)

ASP.NET Identity – Current MS stack for authentication and authorization in ASP.NET. Check the articles on security and especially the one on deployment, passwords and the cloud.

Troy Hunt – MS MVP, blogger and security expert. I really like his stuff. Take the list of topics of his Hack Yourself First workshop as inspiration, check out his Pluralsight courses and sign up for his newsletter. Love one of his recent posts Passwords Evolved: Authentication Guidance for the Modern Era.

Ten Immutable Laws Of Security (Version 2.0) – Security philosophy 101 from Microsoft. Makes you think.

.NET Blog – General and security-related information.

My own blog entries about security.

Cloud diary tutorial part 1- Get started with ASP.NET MVC, user authentication and the cloud

A video tutorial based on my learnings of ASP.NET MVC 5, ASP.NET Identity, SQL Server and Azure.

Summary: I will show you how to create a very simple web application with user authentication. Users can register, log in, create diary entries (text) and visualize their entries.

In part one we will create, test and refactor the application locally on our computer. Although the app is very simple we will touch a lot of different technologies. You will also see some issues you may experience when starting with ASP.NET MVC in Visual Studio and how to fix them.

In part two we will publish our app to the cloud (Azure). Please subscribe to get notified when part two is finished.

Technology stack

Visual Studio 2017 (Community Edition)
ASP.NET MVC 5
ASP.NET Identity
C#
Git
Entity Framework 6 with Code-First
LINQ to Entities
Azure App Service
Azure SQL Database

Prerequisites

Visual Studio 2017 with the following workloads:

  • ASP.NET and web development
  • Azure development

Content

00 – Introduction

01 – Create ASP.NET MVC 5 application from template

  • Create a new ASP.NET MVC 5 application with ASP.NET Identity
  • Configure authentication (Individual user accounts) for new project
  • Project folders overview
  • Local database folder: App_Data
  • Register user and log into our new application
  • Use “Server Explorer” to show data from local database

02 – Remove unneeded content from application

  • Change title and footer of application
  • Basic HTML tags (title, footer, h1, h2, footer, div)
  • Remove a View and Action Method
  • Commit to source control (local GIT repository)

03 – Create new Controller and View

  • Create a new ASP MVC Controller
  • Create a new ASP MVC View
  • User authentication and security
  • Use of the [Authorize] and [AllowAnonymous] attributes
  • Configure authorization/authentication by default with global filter
  • Refactor our app to use global filter instead of [Authorize] attribute

04 – Display list of fake entries in View

  • Create a model class for diary entry
  • Usage of “prop” code snippet.
  • Create fake data in Controller
  • Display list in View
  • Use of the “ViewBag”
  • Create an HTML table in code

05 – Add form for adding new diary entries

  • Create a Html form using ASP.NET Identity code as template
  • Razor syntax
  • MVC Form @model directive
  • Create a ViewModel for form-data with data validation attributes
  • Use of [Required], [DisplayName] and [StringLength] attributes

06 – Implement Action Method on Controller to handle the form data from HttpPost request

  • Add HttpPost Action method to Controller
  • [HttpPost] and [ValidateAntiForgeryToken] attributes
  • Test Action Method

07 – Store diary entries in database

  • ASP.NET Identity ApplicationUser and ApplicationDbContext overview
  • ASP.NET Identity tables
  • Extend DiaryEntry model class for usage in DbContext
  • Create foreign key property and navigation properties (Entity Framework)
  • Add new DiaryEntry table to DbContext
  • Create new model class from viewmodel
  • Use Entity Framework to insert into DiaryEntries table
  • Show result of data-model change: “Server Error in Application. The model backing the ‘ApplicationDbContext” context has changed since the database was created. Consider using Code First Migrations to update the database”

08 – Enable EF Migrations

  • Add Code First Migrations to update the database
  • Delete SQLServer LocalDB database from App_Data folder
  • Enable, create and apply migrations with Package Manager (“enable-migrations”, “add-migration”, “update-database”)
  • Test adding a new diary entry to the database using our form.

09 – Retrieve data

  • Query database with LINQ to entities query
  • Redirect to GET ActionMethod after the POST with “RedirectToAction”

10 – UX improvement – Login button on homepage

  • Identify user experience issues
  • Use source control (GIT) to access code from a previous version
  • Improve navigation by adding Login-Button on homepage

11 – UX improvement – Move diary to homepage

  • Refactor Controllers and Views to merge homepage and diary page

Part 2 (Publish our app to the cloud) still in the works. Please subscribe to my YouTube channel and blog to get notified when it’s ready!

Credits: Big thanks to John Sonmez from SimpleProgrammer. His “10 Steps to learn Anything” course not only helped me to organize my learning but also motivated me to create this tutorial!

ASP.NET MVC Identity whitelisting vs blacklisting – Don’t trust yourself

Just imagine 2 different scenarios in a ASP.NET MVC app using ASP.NET Identity. In both cases you have an application that requires the user to be logged in.

Scenario 1: Blacklisting

Your authentication-default is “allow anonymous”, which is the default of the ASP.NET MVC 5 template. You create a new Action Method on a controller and forget to add the [authorize] attribute.

Resulting Issue: You have a potential security hole in your application that may remain undetected and possibly exploited.

Scenario 2: Whitelisting

Your global authentication-default is “requires authentication”. You create a new action method on a controller that should be accessible without authentication and forget to add the [AllowAnonymous] attribute.

Resulting issue: You try your application, can’t enter that new page and fix it. In the worst case you didn’t do your homework and a customer/user finds the bug and complains to you.

Which issue would you rather have to deal with?

I personally prefer the whitelisting approach and err on the side of caution.

See also: Enable global authentication with ASP.NET MVC and Identity

 

Enable global authentication with ASP.NET MVC and Identity

To require user authentication for all action methods on all controllers please add the AuthorizeAttribute class to the App_Start/FilterConfig.cs file:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new AuthorizeAttribute()); 
}

To configure an exception and allow anonymous access to an action method: Decorate it with the AllowAnonymousattribute:

[AllowAnonymous]
public ActionResult Index()
{ 
    // do stuff
}