Category: ASP.NET

  • ASP.NET Core MVC CRUD Operations Tutorial

    ASP.NET Core MVC CRUD Operations Tutorial

    This source provides a comprehensive tutorial on building an ASP.NET Core 8 MVC (Model-View-Controller) application from the ground up, focusing on CRUD (Create, Read, Update, Delete) operations. It guides the user through setting up a SQL Server database using Entity Framework Core, covering topics such as project creation, dependency injection, database migrations, and the implementation of web pages for managing student data. The tutorial also explains how to design views with Bootstrap and handle HTTP GET/POST requests for each CRUD function, including troubleshooting common issues like Entity Framework Core tracking errors.

    ASP.NET Core MVC: Student Data CRUD with Entity Framework

    CRUD operations, which stand for Create, Read, Update, and Delete, are fundamental functionalities for managing data in most web and API applications. The sources describe building an ASP.NET Core 8 MVC application from scratch to perform these operations on student data stored in a SQL Server database using Entity Framework Core.

    Here’s a detailed discussion of each CRUD operation as implemented in the described application:

    • Create (Add Student)
    • Purpose: To allow users to add new student records to the database.
    • User Interface: An “Add student page” is created, featuring form inputs for the student’s name, email, phone, and a subscribed option (a boolean checkbox).
    • Controller (StudentsController):An HTTP GET Add action method is used to display the initial add student form.
    • An HTTP POST Add action method handles the form submission. This method receives an AddStudentViewModel as a parameter, which encapsulates the data entered by the user (name, email, phone, subscribed).
    • Data Handling:A Student entity class is defined with properties like ID (a unique identifier, automatically set by Entity Framework Core), Name, Email, Phone Number, and Subscribed (a boolean).
    • The ApplicationDBContext class, which acts as a bridge between Entity Framework Core and the SQL Server database, is injected into the controller using Constructor Injection.
    • Inside the POST Add method, a new Student entity is created using the data from the AddStudentViewModel.
    • The DBContext.Students.AddAsync() method is used to add the new student entity to the context.
    • Finally, DBContext.SaveChangesAsync() is called to persist the changes to the SQL Server database.
    • Read (List Students)
    • Purpose: To display a list of all students currently stored in the database.
    • User Interface: An “All students web page” is created, which shows the ID, name, and email of each student in a table format. Each row also includes an “Edit” button.
    • Controller (StudentsController):An HTTP GET List action method is responsible for retrieving and displaying the student list.
    • Data Handling:The DBContext is used to access the Students collection.
    • The await DBContext.Students.ToListAsync() method retrieves all student records from the database.
    • This list of Student entities is then passed to the List.cshtml view.
    • View (List.cshtml): The view is strongly typed to a List<Student> and uses a foreach loop to iterate through the collection and display each student’s details in a table. A navigation link to “All Students” is also added to the application’s layout page.
    • Update (Edit Student)
    • Purpose: To allow users to view and modify the details of an existing student record.
    • User Interface: An “Edit student web page” is used, which looks similar to the add student page but is pre-populated with the selected student’s current information. The ID field is displayed as read-only.
    • Linking: The “Edit” button on the “All Students” list page is configured to pass the unique ID of the specific student to the edit page’s URL (e.g., /students/edit/{id}).
    • Controller (StudentsController):An HTTP GET Edit action method takes the student’s ID (GUID) as a parameter. It uses await DBContext.Student.FindAsync(ID) (or FirstOrDefaultAsync) to retrieve the student’s current information from the database. If no student is found for the given ID (e.g., it’s a junk ID), a “no student found” message can be displayed. The retrieved Student entity is then passed to the Edit.cshtml view.
    • An HTTP POST Edit action method receives an updated Student model (or AddStudentViewModel) from the submitted form.
    • It first retrieves the existing student record from the database using its ID.
    • Important Note: The source initially used FindAsync, which caused tracking issues during deletion. It was later modified to use DBContext.Students.FirstOrDefaultAsync(x => x.ID == viewModel.ID).AsNoTracking() to avoid Entity Framework Core tracking the entity, ensuring proper deletion later.
    • The properties of the retrieved student entity (name, email, phone, subscribed) are then updated with the new values from the submitted view model.
    • await DBContext.SaveChangesAsync() is called to save these updated details to the database.
    • After a successful update, the user is redirected back to the “All Students” list page (RedirectToAction(“List”, “Students”)).
    • Delete (Delete Student)
    • Purpose: To remove a student record permanently from the database.
    • User Interface: A “Delete” button is added to the “Edit student page”. It is styled with a “danger” class to indicate its destructive action.
    • Controller (StudentsController):An HTTP POST Delete action method is created, which takes the student’s ID (via a Student view model) as a parameter.
    • Data Handling:The method retrieves the student entity to be deleted using await DBContext.Students.FirstOrDefaultAsync(x => x.ID == viewModel.ID).AsNoTracking(). The .AsNoTracking() is crucial here to prevent Entity Framework Core from tracking the entity, which caused errors when attempting to remove an already tracked instance.
    • A check is performed to ensure the student exists (is not null).
    • DBContext.Students.Remove(student) is called to mark the entity for deletion.
    • await DBContext.SaveChangesAsync() is then executed to commit the deletion to the database.
    • After deletion, the user is redirected back to the “All Students” list page.

    These CRUD operations demonstrate the full lifecycle of data management within an ASP.NET Core MVC application, leveraging Entity Framework Core as an ORM (Object-Relational Mapper) to interact with the SQL Server database without writing raw SQL queries. Entity Framework Core handles database connections, instance management, and synchronization between the application’s models and the database tables through techniques like migrations.

    ASP.NET Core 8 MVC CRUD with Entity Framework Core

    ASP.NET Core is a powerful and modern framework for building web applications and APIs. The sources describe its use in creating a beginner-friendly ASP.NET Core 8 MVC application from scratch to perform CRUD (Create, Read, Update, Delete) operations on student data stored in a SQL Server database using Entity Framework Core.

    Here’s a discussion of ASP.NET Core based on the provided information:

    • Core Purpose and Application Type
    • ASP.NET Core is used to create web applications, specifically an MVC (Model-View-Controller) application in the context of the tutorial. It uses the C# language for development.
    • The goal of the described application is to manage student data, allowing users to add, list (view), edit, and delete student records.
    • Project Setup and Structure
    • A new .NET 8 application is created using the MVC template in Visual Studio.
    • An ASP.NET Core MVC application by default provides the following key folders: Models, Views, and Controllers.
    • The Program.cs file is the main file for configuring the application, where services like controllers with views are added to the Builder object.
    • The launchSettings.json file in the Properties folder contains launch-related settings, including URLs for the server to run on.
    • MVC Architecture
    • Controllers: These contain action methods (e.g., Index, Privacy, Add, List, Edit, Delete) which handle incoming requests. They are typically decorated with HTTP GET or HTTP POST attributes to specify the type of request they handle. Action methods can be made asynchronous (async Task<IActionResult>) for operations that involve waiting for I/O, such as database interactions.
    • Views: These are .cshtml (Razor View) files located in folders corresponding to their controllers (e.g., Views/Home for HomeController, Views/Students for StudentsController). They contain HTML markup and can be strongly typed to a model (e.g., AddStudentViewModel, List<Student>, Student) using the @model directive. Bootstrap classes are widely used for styling the HTML elements.
    • Models: These represent the data structures. The application defines Student entity classes (within a Models/Entities folder) with properties like ID (a unique identifier, often a GUID), Name, Email, PhoneNumber, and Subscribed (a boolean flag). View Models (e.g., AddStudentViewModel) are also used to encapsulate data passed between views and controllers, separating it from the domain entities.
    • Routing: By default, routes are configured to map URLs to controller action methods (e.g., /Home/Index is the default homepage). Links between pages often use ASP tags (e.g., asp-controller, asp-action, asp-route-id) to generate correct URLs.
    • Key Features and Development Flow
    • Hot Reloading: Visual Studio automatically refreshes the application in the browser to reflect changes saved in the code, improving development speed.
    • Dependency Injection: ASP.NET Core uses constructor injection to provide instances of classes, such as the ApplicationDBContext, to controllers. This means you don’t have to manually “new up” instances, as the framework handles it.
    • Integration with Entity Framework Core (EF Core):EF Core is a micro ORM (Object-Relational Mapper) that simplifies interaction with databases like SQL Server. It handles database connections and instances, allowing direct interaction with tables through C# classes.
    • NuGet packages like Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.Tools are installed to enable EF Core functionality and migrations.
    • A DBContext class (e.g., ApplicationDBContext) acts as a bridge between EF Core and the database. It inherits from DBContext and contains DbSet properties (e.g., DbSet<Student> Students) which represent collections that map to database tables.
    • Connection strings are defined in appsettings.json and tell the application which SQL Server instance and database to use.
    • Migrations are used to create and update the database schema based on the application’s entity models. Commands like Add-Migration [name] and Update-Database are run in the Package Manager Console to create migration files and then apply them to the database. This ensures the database schema stays in sync with the application’s models.
    • EF Core methods like AddAsync(), ToListAsync(), FindAsync(), FirstOrDefaultAsync(), Remove(), and SaveChangesAsync() are used within controllers to perform the actual CRUD operations by interacting with the DBContext.
    • The .AsNoTracking() method can be crucial when retrieving entities for operations like deletion to prevent EF Core from tracking the entity, which can lead to errors if another instance with the same key is already being tracked.

    Mastering Entity Framework Core in ASP.NET Applications

    Entity Framework Core (EF Core) is a powerful and essential component within the ASP.NET Core ecosystem, primarily functioning as a micro ORM (Object-Relational Mapper) . Its core purpose is to simplify how ASP.NET Core applications interact with databases, such as **SQL Server**, by allowing developers to work with database tables directly through **C# classes (entities)** rather than writing raw SQL queries.

    Here’s a detailed discussion of Entity Framework Core based on the sources:

    • Role as an ORM
    • EF Core makes a developer’s life “very easy” because it handles all the database connections and instances . This means you can interact with database tables directly using C# code.
    • It effectively bridges the gap between your C# application’s models and the underlying SQL Server database “.
    • Installation and Setup
    • To integrate EF Core into an ASP.NET Core project, specific NuGet packages must be installed “. The sources mention:
    • Microsoft.EntityFrameworkCore.SqlServer: For connecting to SQL Server databases “.
    • Microsoft.EntityFrameworkCore.Tools: This package is crucial for migrations, which are used to create and update the database schema “.
    • The DBContext Class: The Bridge to the Database
    • A DBContext class (e.g., ApplicationDBContext) is created, which inherits from DBContext (from Microsoft.EntityFrameworkCore) . This class serves as the **bridge between Entity Framework Core and the database**.
    • Within the DBContext class, DbSet properties are defined . These properties (e.g., `DbSet<Student> Students`) represent **collections** and are used to **reference and access the tables** in the SQL Server database.
    • The DBContext is made available throughout the application using Dependency Injection . It is configured in `Program.cs` using `builder.Services.AddDbContext`, where it’s also told which database to use (e.g., options.UseSqlServer) “.
    • Connection Strings
    • EF Core needs to know how to connect to the database. This is achieved by defining a connection string “.
    • Connection strings are stored in the appsettings.json file . They are key-value pairs, where the key can be descriptive (e.g., “StudentPortal”) and the value contains details like the **server name, database name**, and connection properties (e.g., `trusted_connection=true`, `trustServerCertificate=true`).
    • The application retrieves the connection string from appsettings.json using Builder.Configuration.GetConnectionString in Program.cs “.
    • Migrations: Synchronizing Database Schema
    • Migrations are a key feature of EF Core that allow the database schema to stay in sync with the application’s entity models “.
    • They are executed via the Package Manager Console in Visual Studio “.
    • The process involves two main commands “:
    • Add-Migration [name]: This command creates a migration file (e.g., InitialMigration.cs) . This file contains C# code generated by EF Core that describes the changes needed to create or update the database table(s) based on your `DbSet` properties and entity models. For example, it would define a Students table with ID, Name, Email, Phone, and Subscribed columns “.
    • Update-Database: This command applies the pending migrations to the actual SQL Server database . If the database doesn’t exist, it will be created; otherwise, it will be updated to match the application’s models.
    • Performing CRUD Operations with EF Core
    • EF Core provides asynchronous methods for performing Create, Read, Update, and Delete operations “:
    • Create (Add): New entities (e.g., a Student object) are added to the DBContext using DBContext.Students.AddAsync() . The changes are then persisted to the database by calling `await DBContext.SaveChangesAsync()`.
    • Read (List and Single):
    • To retrieve a list of all students, await DBContext.Students.ToListAsync() is used “.
    • To find a single student by its unique ID, methods like await DBContext.Students.FindAsync(ID) or await DBContext.Students.FirstOrDefaultAsync(x => x.ID == viewModel.ID) are employed “.
    • Update: An existing entity is first retrieved from the database. Its properties are then updated with new values from a view model. The changes are saved to the database by calling await DBContext.SaveChangesAsync() “.
    • Delete: The entity to be deleted is retrieved, and then DBContext.Students.Remove(student) is called to mark it for deletion . `await DBContext.SaveChangesAsync()` then commits this deletion to the database.
    • Handling Tracking Issues (AsNoTracking())
    • A significant detail highlighted in the sources is the use of .AsNoTracking() “.
    • When retrieving an entity using FindAsync or FirstOrDefaultAsync, EF Core tracks that entity . This can lead to errors, especially during deletion, if another instance with the same key is already being tracked.
    • By adding .AsNoTracking() to the query (e.g., DBContext.Students.FirstOrDefaultAsync(x => x.ID == viewModel.ID).AsNoTracking()), you prevent EF Core from tracking the retrieved entity, which resolves conflicts and allows the Remove operation to proceed without error “.

    In summary, Entity Framework Core streamlines database interactions in ASP.NET Core applications by providing an object-oriented way to manage data, handling complex tasks like schema synchronization through migrations, and offering a robust API for performing all fundamental CRUD operations “.

    ASP.NET Core MVC CRUD Operations using .NET 8 and Entity Framework Core – MVC For Beginners Tutorial

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • ASP.NET jQuery Cookbook for Developers

    ASP.NET jQuery Cookbook for Developers

    This text provides excerpts from the second edition of the ASP.NET jQuery Cookbook, originally published in 2011 and updated in 2016 by Packt Publishing. It serves as a practical guide with recipes for integrating jQuery with ASP.NET web forms and MVC applications. Key topics covered include setting up and managing jQuery libraries, utilizing jQuery selectors to interact with controls, handling various events, manipulating the Document Object Model (DOM), adding visual effects, and performing Ajax calls. The book also guides readers on creating and using jQuery plugins, including leveraging NuGet for package management and debugging techniques within Visual Studio.

    Podcast

    Listen or Download Podcast – ASP.NET jQuery Cookbook for Developers

    Exploring jQuery in ASP.NET Applications

    Based on the provided sources, here is a discussion about jQuery:

    jQuery is a lightweight JavaScript library that has transformed the landscape of client scripting in web applications. Developed by John Resig in 2006, it quickly gained popularity due to its cross-browser compatibility and its ability to “get more done with less code”. The library is supported by an active community of developers and has grown significantly. Using jQuery simplifies many client scripting tasks, including event handling, embedding animations, and writing Ajax-enabled pages, contributing to a more interactive experience for the end-user. Its extensible plugin architecture also allows developers to build additional functionalities on top of the core library.

    The library consists of a single JavaScript (.js) file. At the time the source was written, jQuery was available in two major versions: Version 1.x and Version 2.x. While the Application Programming Interface (API) is the same for both, Version 2.x does not support older browsers like IE 6, 7, and 8, whereas Version 1.x continues to support them. You can download jQuery in either uncompressed format (for development and debugging) or compressed format (for production, also known as the minified version). The minified version uses optimization techniques like removing whitespaces and shortening variable names, making it smaller but harder to read. A map file (.min.map) is available to simplify debugging of the minified version by mapping it back to its unbuilt state.

    Including jQuery in an ASP.NET application can be done in several ways:

    • Downloading from jQuery.com and manually adding the file to your project.
    • Using a Content Delivery Network (CDN), which hosts the jQuery library on distributed servers. This can improve performance as users might already have the file cached from visiting other sites that use the same CDN. Available CDNs include jQuery’s CDN, Google CDN, Microsoft CDN, CDNJS CDN, and jsDelivr CDN. Using a CDN means linking directly to the library file hosted online instead of using a local copy. Note that CDNs might take a couple of days to update with the latest jQuery releases.
    • Using the NuGet Package Manager, available with Visual Studio, which simplifies installing and upgrading the library within your project. NuGet typically downloads the debug (.js), release (.min.js), Intellisense (.intellisense.js), and map (.min.map) files into the project’s Scripts folder.
    • Adding jQuery to an empty ASP.NET web project using a script block (<script>) by referencing the local file path. This method requires manual updates if the library version changes and manual switching between debug and release versions.
    • Adding jQuery to an empty ASP.NET web project using the ScriptManager control. This control helps manage script references, automatically switching between debug and release versions based on the <compilation debug=”true”/> setting in web.config. It can also be configured to load jQuery from a CDN if the EnableCdn property is set to true. The ScriptManager uses a ScriptResourceDefinition object, typically defined in the Global.asax file, to map a script name (like “jquery”) to its local and CDN paths for debug and release modes. It also includes a fallback mechanism to load the local copy if the CDN is unavailable.
    • Adding jQuery to an ASP.NET Master Page ensures that all content pages using that Master Page automatically include the library. This can be done by adding the <script> block or ScriptManager control to the Master Page.
    • Adding jQuery programmatically to a web form using the Page.ClientScript.RegisterClientScriptInclude method in the code-behind file. This method adds the script block within the <form> element.
    • In the default ASP.NET Web Application templates, jQuery is often included using the ScriptManager control in the Master Page, leveraging the Microsoft CDN by default, with mapping defined by the AspNet.ScriptManager.jQuery package. This mapping can be changed to use a different CDN, such as Google CDN, by updating the ScriptResourceMapping in the BundleConfig class.
    • In ASP.NET MVC applications, jQuery can be included using the <script> tag in views. A common method is using bundling, which combines multiple script files into a single file to reduce HTTP requests. Bundling is configured in the BundleConfig class using ScriptBundle. Bundling can also be configured to load jQuery from a CDN by setting the UseCdn property and providing the CDN path. A fallback mechanism should be included in the view to load the local file if the CDN fails.

    Once jQuery is included, you can write client-side code to interact with your web page. A common starting point is using the $(document).ready() function, which executes code when the Document Object Model (DOM) is fully loaded.

    jQuery provides powerful features for manipulating elements on a web page:

    • Selectors: These are jQuery constructs used to retrieve elements based on specified conditions. They can return single or multiple elements. Since ASP.NET controls are rendered as HTML elements, they can be selected using standard jQuery selectors. Types of selectors include Basic selectors (by tag, class, ID, or combination), Hierarchy selectors (selecting based on relationships like parent/child), Attribute selectors (selecting based on element attributes), Form selectors (working with form elements), and Position filters (selecting elements based on their position in a collection). Examples of selectors used in the sources include #identifier for selecting by ID, .class for selecting by CSS class, html_tag for selecting by HTML tag, [attribute*=”value”] for selecting by attribute containing a value, :first, :last, :odd, :even, :eq(i), :lt(i), :gt(i) for position filtering. The $(this) object refers to the current jQuery object in a chain or callback.
    • DOM Traversal: jQuery provides methods to navigate the DOM tree, such as accessing parent (.parent(), .parents()), child (.children(), .find()), and sibling (.siblings()) elements.
    • DOM Manipulation: Elements can be added (.append(), .prepend(), .appendTo()), removed (.remove()), or cloned (.clone()) at runtime using client code. Methods like .addClass() and .removeClass() are used to manage CSS classes.
    • Visual Effects and Animations: jQuery simplifies adding visual effects. Built-in methods include .show(), .hide(), .toggle() for displaying elements; .fadeIn(), .fadeOut(), .fadeTo(), .fadeToggle() for fading; and .slideUp(), .slideDown(), .slideToggle() for sliding effects. Custom animations can be created with .animate() by changing numeric CSS properties over time. Animations can be stopped using .stop() or .finish(). The duration of animations can be specified in milliseconds or using keywords like “slow” and “fast”. Specific applications of effects mentioned include animating Menu controls, creating digital clocks, animating AdRotator alt text, animating images in TreeView nodes, creating scrolling text, building vertical accordion menus, and showing/hiding GridView controls. The jQuery UI library provides additional effects like “explode” and enhanced easing methods like “easeOutBounce”.
    • Event Handling: Events occur when a user interacts with the page or during page milestones. An event handler is a function executed when an event occurs. jQuery 1.7+ recommends the .on() method for binding event handlers. It can attach single events, multiple events to one handler, or different events to different handlers. Event delegation is a technique where a single event handler is attached to a parent element to manage events for its children, including future children. This is possible due to event bubbling, where events in a child element travel up the DOM tree. Event bubbling can be stopped using .stopPropagation(). The .one() method attaches an event handler that executes at most once. Events can be triggered programmatically using .trigger(). Data can be passed with events, typically as a JSON string. Events can also use namespacing (e.g., click.myNamespace) to group handlers. Event handlers can be removed using .off(). Examples of events discussed include mouse events (mouseover, mouseout, click, dblclick, mousemove), keyboard events (keyup), and form events (focus, blur, change).
    • Working with Graphics: jQuery aids in integrating graphics by providing utilities for effects, animations, and event handlers on elements like <img>, ImageButton, and ImageMap. Examples include creating spotlight effects on images, zooming images on mouseover, building image scrollers, creating photo galleries (using z-index or ImageMap), using images in Menu controls, creating a 5-star rating control (as a User Control), and previewing image uploads in MVC. The File API (window.File, window.FileReader) and its onloadend event are used for previewing image uploads.
    • Ajax (Asynchronous JavaScript and XML): Ajax allows communication with the server without full page refreshes, updating parts of the page transparently. jQuery simplifies Ajax with methods like the generic .ajax() for various request types (GET, POST, etc.). Global default settings can be configured with .ajaxSetup(). Shortcut methods like .load() (for text/HTML content) and .getJSON() (for JSON data via GET) are also available. jQuery Ajax can be used to consume various server-side endpoints in ASP.NET, including page methods (static/shared methods marked with [WebMethod]), Web services (ASMX), WCF services (Ajax-enabled SVC), Web API (HTTP API), and generic HTTP handlers (ASHX). The $.getJSON() method is particularly useful for retrieving JSON data from endpoints like Web APIs. For WCF services and page methods expecting JSON input, contentType: “application/json; charset=utf-8” and data as a JSON string are used. Accessing returned data from Web Services, WCF Services, and Page Methods often involves accessing a .d property of the response object.
    • Plugins: jQuery’s plugin architecture allows extending the core library. Plugins are JavaScript files included alongside jQuery. They typically provide configurable functionalities. New plugins are published to the NPM (Node Package Manager) repository. Creating a plugin involves defining methods in the jQuery namespace (for utility functions like $.sampleMethod()) or on jQuery.fn (alias for jQuery.prototype, for methods callable on DOM elements like $(“#element”).myMethod()). Using a wrapping function (function($){…})(jQuery) allows using the $ alias safely within the plugin, even if $.noConflict() has been called elsewhere. Plugin methods often use .each() to ensure they operate correctly on collections of matched elements. Good practices for plugins include providing default options using $.extend() to allow customization and returning the this object (the jQuery object) to enable method chaining. Plugins can also define different actions or functionalities based on arguments passed to the method. The jQuery validation plugin is a popular example available from http://jqueryvalidation.org and downloadable via package managers like NuGet or Bower (which requires Node.js, NPM, and Git). This plugin provides methods like .validate() to validate forms based on defined rules and messages, and .resetForm() to clear validations. It offers features like custom error message placement and handling invalid forms.

    This book aims to impart the skill of learning jQuery and using it in ASP.NET applications by exploring diverse recipes for common problems in ASP.NET 4.6 applications. The examples are based on Visual Studio 2015 and jQuery 2.1.4 and were tested in Internet Explorer 11.0.96, Mozilla Firefox 38.0.1, and Google Chrome 47.0.2526. Familiarity with Visual Studio and MS SQL Server is preferred but not mandatory for the reader.

    jQuery and ASP.NET Development Guide

    Based on the sources you provided, ASP.NET is a framework used for creating web applications. The book specifically focuses on writing client script using jQuery in ASP.NET 4.6 applications. Sonal Aneel Allana, the author, has experience teaching in areas including .NET and ASP.NET.

    The sources describe how to integrate and use the jQuery library within ASP.NET Web Forms and MVC applications. The book covers various aspects of using jQuery with ASP.NET, including:

    • Getting Started with downloading and including jQuery in ASP.NET 4.6 Web and MVC projects. This involves understanding CDNs, using NuGet Package Manager, adding jQuery via script blocks, using the ScriptManager control, adding it to ASP.NET Master Pages, and adding it programmatically to web forms. The default Web Application template in ASP.NET also includes a reference to jQuery, typically using the ScriptManager control.
    • Using jQuery Selectors with ASP.NET Controls. When an ASP.NET page is viewed in a browser, controls are rendered as HTML elements, making them selectable with standard jQuery selectors. The book demonstrates selecting controls by ID, CSS class, HTML tag, attribute, or position in the DOM. Selectors can also be used in ASP.NET MVC applications.
    • Event Handling Using jQuery in ASP.NET. This includes responding to mouse, keyboard, and form events, as well as using event delegation and detaching events.
    • DOM Traversal and Manipulation in ASP.NET. Techniques covered include accessing parent, child, or sibling elements, refining selection using filters, and adding or removing elements at runtime.
    • Visual Effects in ASP.NET Sites. Recipes discuss creating animation effects on various ASP.NET controls like Panel, AdRotator, TreeView, Menu, and GridView.
    • Working with Graphics in ASP.NET Sites and MVC. This involves applying effects like zooming and scrolling to images and building components like image galleries, image previews, and rating controls using jQuery. ASP.NET server controls such as Image, ImageButton, and ImageMap, as well as plain HTML image elements in MVC, can be manipulated.
    • Ajax Using jQuery in ASP.NET. The book explains how to make Ajax calls to interact with server-side components such as page methods, Web services (.asmx), WCF services (.svc), Web API, MVC controllers, and HTTP handlers (.ashx).

    To work with the examples discussed, requirements include Visual Studio 2015, MS SQL Server 2014, the Northwind database, the jQuery library, the jQuery UI library, a web browser, NPM, and Bower. The book is aimed at ASP.NET developers who want to use jQuery to write client scripts for cross-browser compatibility. While familiarity with Visual Studio and MS SQL Server is preferred, it is not compulsory.

    Mastering jQuery Selectors in ASP.NET

    Based on the sources, jQuery selectors are fundamental constructs used to retrieve elements on a web page based on a specified condition. They provide a mechanism to access web page elements when writing client scripts, which is essential for manipulating these elements. While standard JavaScript allows accessing elements by their unique IDs using methods like document.getElementById(), selectors offer more flexibility, enabling developers to select elements based on attributes other than ID, or to retrieve and manipulate multiple elements simultaneously.

    Selectors are particularly relevant in the context of ASP.NET development because when an ASP.NET page is viewed in a browser, the server controls are rendered as HTML elements. This conversion means that standard jQuery selectors can be applied to manipulate these rendered ASP.NET controls just like any other HTML element. The sources provide a table illustrating the mapping of common ASP.NET controls to their rendered HTML elements and tags, such as GridView rendering as <table>, Button as <input type=”submit”/>, and Label as <span>. Selectors are also usable in ASP.NET MVC applications as they typically use raw HTML markups or HTML helper methods to render content.

    The sources classify jQuery selectors into several broad types:

    • Basic selectors: These are similar to CSS selectors and are used to retrieve elements based on their HTML tag, CSS class, element ID, or a combination. Examples include selecting all elements ($(“*”)), all <div> elements ($(“div”)), all elements with a specific CSS class ($(“.highlight”)), an element with a specific ID ($(“#footer”)), or a combination.
    • Hierarchy selectors: Also resembling CSS selectors, these are used to select child or descendant elements within the structure of the Document Object Model (DOM) tree. Examples include selecting all <p> elements inside <div>s ($(“div p”)) or immediate children <p> of <div>s ($(“div > p”)).
    • Attribute selectors: These selectors retrieve elements based on the attributes they possess. Examples include selecting all <a> elements with an href attribute ($(“a[href]”)), or those whose href attribute contains ($(“*=”)), starts with ($(“^=”)), or ends with ($(“$=”) a specific string.
    • Form selectors: Specifically designed to work with various form elements like inputs, checkboxes, and radio buttons. Examples include selecting elements by type ($(“:button”), “:checkbox”, “:radio”), all form elements ($(“:input”)), or elements based on state (“:checked”, “:selected”, “:enabled”, “:disabled”).
    • Position filters: These selectors retrieve elements based on their position within a collection, often relative to siblings. Examples include selecting the first element in a collection (:first), the last (:last), those at an odd or even index (:odd, :even), at a specific index (:eq(i)), or with an index less than (:lt(i)) or greater than (:gt(i)) a certain value.

    Anonymous functions are frequently used in conjunction with selectors, often passed as arguments to other functions that operate on the selected elements.

    The sources provide several recipes demonstrating the practical application of these selectors within ASP.NET applications:

    • Using the ID selector (#identifier) to access controls like TextBox, RadioButtonList, DropDownList, CheckBoxList, CheckBox, and Button in a web form. This often involves using the ASP.NET ClientID property to get the rendered HTML ID.
    • Employing the CSS class selector (.class) to work with controls like Image, Panel, and BulletedList.
    • Selecting controls like GridView by their rendered HTML tag ($(“html_tag”)), often combined with attribute filters or hierarchy selectors to target specific parts like rows (<tr>) or cells (<td>).
    • Accessing controls like Hyperlink based on their attributes, such as the href attribute rendered from the NavigateUrl property.
    • Selecting list items (<option> rendered from ListItem in ListBox or DropDownList) or other elements based on their position within the DOM, using position filters like :first-child, :last-child, :lt(), :gt(), and :nth-child.
    • Using selectors to dynamically enable or disable controls on a web form.
    • Demonstrating the use of various selectors within ASP.NET MVC applications.

    A link to http://api.jquery.com/category/selectors is mentioned as a resource to find out more about different types of jQuery selectors.

    jQuery Event Handling Fundamentals

    Based on the sources, event handling is a fundamental concept in client scripting using jQuery in ASP.NET applications.

    An event is defined as an action that occurs when the user interacts with the web page or when certain milestones are completed, such as a page loading in the browser. Examples include moving the mouse, pressing a key, clicking a button or link, keying in text in a field, or submitting a form. Events can be user- or system-initiated.

    An event handler is a function that is executed when a specific event occurs. Writing or binding an event handler for a particular event allows developers to program the desired actions in response to user or system interactions. jQuery eases client scripting tasks, including event handling, adding to the interactive experience for the end user.

    When working with events, event delegation is an important mechanism. It allows you to attach a single event handler to a parent element instead of attaching individual event handlers to each child element. This approach optimizes the number of event handlers on the page. Event delegation is also useful for wiring events to child elements that do not exist when the page initially loads but are added later at runtime.

    Event delegation is made possible because of event bubbling. Event bubbling is the process where an event occurring in a child element travels up the Document Object Model (DOM) tree to its parent, then to its parent’s parent, and so on, until it reaches the root element (the window). For example, a click event on a table cell (<td>) bubbles up through the table row (<tr>), the table (<table>), and eventually to the <body>, <html>, and window elements. The parent element can intercept the event as it bubbles up, allowing a single handler on the parent to manage events for its descendants. jQuery provides a .stopPropagation() method to prevent an event from bubbling further up the DOM tree.

    jQuery offers several methods for binding events. Prior to jQuery 1.7+, methods like .bind(), .live(), and .delegate() were used. However, these are now deprecated, and the .on() method is recommended for event binding in jQuery 1.7+.

    The .on() method can be used in various ways:

    • Attaching a single event to a handler: For example, $(“#btnTest”).on(“click”, function(){…});.
    • Attaching multiple events to a handler: The same handler can respond to multiple events listed with spaces, like $(“#imgTest”).on(“mouseover mouseout”, function(){…});.
    • Attaching different events to different handlers: An object can be passed mapping event names to handler functions, for example, $(“#imgTest”).on({ mouseover: function(){…}, mouseout: function(){…} });.
    • Event delegation: By specifying a selector as a second argument, the handler is attached to the parent element but only executed for descendant elements matching the selector. For example, $(“#tblTest”).on(“click”, “tr”, function(){…}); attaches the click handler to the table, but it only runs when a table row (<tr>) inside the table is clicked. This is demonstrated in a recipe to attach events to dynamically added rows.
    • Passing data to events: Data can be passed as a JSON string or other data types when binding the event, which can then be accessed in the event handler. This is demonstrated in a recipe using the .trigger() method.

    Specific types of events discussed in the sources include:

    • Mouse events: Such as mouseover (when the mouse pointer enters an element) and mouseout (when it leaves an element). The .hover() method is a shortcut for binding mouseover and mouseout handlers. A recipe demonstrates handling these events to display a custom tooltip for text boxes.
    • Keyboard events: Such as keyup (when a key is released). Other keyboard events mentioned are keydown and keypress. A recipe uses the keyup event to create a character count for a text area.
    • Form events: Such as focus (when an element receives focus) and blur (when an element loses focus). A recipe uses these events to apply styles and display background text or validation errors on form controls.

    In the context of ASP.NET, when a page is viewed in the browser, server controls are rendered as HTML elements. This means that standard jQuery event handling techniques, including the use of selectors and the .on() method, can be applied to these rendered HTML elements corresponding to ASP.NET controls.

    To ensure an event handler is executed at most once, the .one() method can be used. Once the event is triggered and the handler is executed, the handler is automatically detached from the element. This is shown in a recipe for a “See More…” link that should only work once.

    jQuery’s .trigger() method allows events to be invoked programmatically. This means client-side code can simulate user actions or system events. A recipe demonstrates using .trigger() to simulate a click on an “Edit” link in a GridView row when the user double-clicks the row itself.

    Events can also have event data passed along with them and can utilize event namespacing. Namespacing allows multiple handlers to be attached to the same event type for the same element without interfering with each other; handlers can then be triggered or detached based on their namespace. A recipe illustrates passing data as a JSON object and using namespacing (click.radioclick1, click.radioclick2) to trigger different alert or confirm boxes based on which radio button was clicked.

    Finally, the .off() method is used to detach event handlers from elements. It can remove specific handlers, all handlers for a particular event type, or all handlers (including namespaced ones) depending on how it is used. A recipe shows how to use .off() to remove focus and blur event handlers from text boxes when a checkbox is unchecked.

    DOM Traversal and Manipulation with jQuery

    Based on the sources, DOM manipulation is a key concept when working with client scripts like jQuery in ASP.NET applications.

    The Document Object Model (DOM) is presented as a representation of web pages in a structured, tree-like format. Each part of the web page is a node in this tree, and these nodes have properties, methods, and event handlers. The web page itself is the document object, accessible via window.document. HTML elements on the page become element nodes, such as <head> or <body>, which can have children nodes like <table>, <div>, or <input>. The DOM is described as an object-oriented model that is language-independent, offering a common Application Programming Interface (API) that allows programming languages like JavaScript to manipulate the style, structure, and content of web pages.

    jQuery provides many methods for interacting with the DOM, including manipulating elements.

    One specific aspect of DOM manipulation discussed is adding and removing DOM elements. jQuery offers methods to perform these actions at runtime using client code.

    The sources illustrate adding DOM elements using the .clone() method. This method creates a deep copy of the matched elements, including their descendants and text nodes. When cloning elements, it’s necessary to update properties like ID, name, and value of the cloned elements and their children to avoid duplicates. The cloned elements can then be added to the DOM using methods like .appendTo(), which inserts the elements at the end of a target element. A recipe demonstrates cloning a Panel control (addPanel CSS class) and its contents, updating the IDs and names of the cloned elements, and appending them to a container div.

    For removing DOM elements, the jQuery method .remove() is used. This method not only removes the matched elements but also their descendants, and it removes all related data and events associated with them. A recipe shows how to remove a dynamically added Panel control using its ID and the .remove() method after user confirmation.

    The sources also touch upon other manipulation strategies, such as adding items to controls at runtime. This involves using methods like .prepend() to insert content at the beginning of a matched element or .append() to insert content at the end. The $.map() function can be used to transform data (like an array of strings) into an array of DOM elements (<option> or <li>) before appending/prepending them. This is demonstrated in a recipe for adding items to ListBox, DropDownList, and BulletedList controls dynamically.

    While focusing on manipulation, the sources also reference DOM traversal as a related concept. Traversal methods allow accessing elements in the DOM tree, such as parent, child, or sibling elements. Examples of traversal methods mentioned or used in the context of accessing controls (though not explicitly manipulation methods) include .parent() to get the immediate parent, .children() for immediate descendants, .find() for descendants matching a filter, .siblings() for elements on the same level, .next() for the immediate sibling, and filtering selections using methods like .filter(). These traversal methods are often used before performing manipulation on the selected elements.

    Chapter 4 of the source material is specifically dedicated to “DOM Traversal and Manipulation in ASP.NET”, covering recipes on adding/removing elements, accessing parent/child controls, accessing sibling controls, refining selection using filters, and adding items to controls at runtime.

    Download PDF Book

    Read or Download PDF Book – ASP.NET jQuery Cookbook for Developers

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Building Dynamic Responsive Web Applications with ASP.NET MVC

    Building Dynamic Responsive Web Applications with ASP.NET MVC

    This collection of text excerpts is from Jamie Munro’s book, “ASP.NET MVC 5 with Bootstrap and Knockout.js: Building Dynamic, Responsive Web Applications,” published by O’Reilly Media in 2015. The book provides a practical guide to building modern web applications using these three technologies. It covers foundational concepts such as MVC architecture, integrating Bootstrap for responsive design, and utilizing Knockout.js for dynamic client-side interactions. Later sections explore working with data, implementing robust code architecture with filters and services, and building a complete shopping cart application as a comprehensive example.

    Podcast

    Listen or Download Podcast – Building Dynamic Responsive Web Applications with ASP.NET MVC

    Building Responsive Web Applications with ASP.NET MVC 5

    Based on the sources provided, ASP.NET MVC 5 is a framework that implements the Model-View-Controller (MVC) architecture pattern. In the context of web development, MVC is described as an architecture pattern where the Model manages the application’s data, often representing database tables. The View contains the visual representation, typically using HTML, CSS, and JavaScript. The Controller acts as the middleman, requesting data from the Model and passing it to the View for display, or receiving data from the View and passing it to the Model for saving. The book uses ASP.NET MVC 5 (or the MVC framework) frequently, often just referring to it as MVC.

    The book utilizes ASP.NET MVC 5 for several key tasks in building dynamic, responsive web applications:

    • To build sophisticated server-side web applications.
    • To interact with a database.
    • To dynamically render HTML.

    ASP.NET MVC 5 has evolved significantly since its initial release in March 2009 and is now considered a technology leader with many useful features readily available.

    The book focuses on combining ASP.NET MVC 5 with Bootstrap (a front-end framework) and Knockout.js (a JavaScript library implementing the Model-View-ViewModel pattern). ASP.NET MVC 5 serves as the server-side component, interacting with a database and rendering dynamic HTML. Knockout.js enhances responsive web design by adding snappy client-side interactions driven by the server-side application built with ASP.NET MVC 5.

    The book guides the reader through using ASP.NET MVC 5 by starting with creating a new project using the MVC template in Visual Studio. This template preloads useful files and folders, including a default shared layout view and a HomeController with basic actions (Index, About, Contact). Controllers in ASP.NET MVC extend the base Controller class, and actions typically return an ActionResult type. The ViewBag property is introduced as a way to pass data dynamically from the Controller to the View. Views, often .cshtml files, contain a mix of HTML and C# using Razor syntax to render dynamic content. Shared layouts, like _Layout.cshtml, contain reusable HTML elements common across multiple pages, and views are inserted into this layout when the RenderBody function is called.

    URL routing in ASP.NET MVC 5 maps URLs to specific controllers and actions. A default route is configured when a project is created, following a {controller}/{action}/{id} pattern with defaults for Home controller and Index action. This can be configured in App_Start/RouteConfig.cs. Starting with MVC 5, attribute routing is also available, allowing routes to be defined directly on controller actions or controllers using the [Route] attribute. This approach can be beneficial for creating more convenient or SEO-friendly URLs. Attribute routing supports prefixes ([RoutePrefix]) and constraints (e.g., :int, :min(0)) to make routing more specific and intelligent.

    For data persistence, ASP.NET MVC projects commonly integrate with databases, often using an ORM like Entity Framework (EF). Visual Studio provides built-in support for EF when scaffolding controllers and views. Scaffolding is a feature that allows rapid creation of web pages with basic CRUD (Create-Read-Update-Delete) functionality based on a model and data context.

    The book also covers various global filters available in ASP.NET MVC 5, which allow applying consistent behavior across requests. These include:

    • Authentication filters: New in MVC 5, responsible for validating credentials.
    • Authorization filters: Determine if an authenticated user is allowed to access a resource.
    • Action filters: Execute code before or after a controller action.
    • Result filters: Execute code when a result is executing or has finished executing, before being returned.
    • Exception filters: Handle errors that occur during a request. These filters can be registered globally or applied using attributes on specific controllers or actions.

    ASP.NET MVC can be integrated with Web API, which is used for building RESTful web applications. Web API controllers extend the base ApiController class. When integrating Web API with MVC, the Web API controller often serves as the entry point for interacting with a resource (Model), and the View is typically a JSON or XML representation of the resource. This allows for dynamic updates to the user interface without full-page reloads, as demonstrated in updating the list of authors example. Web API controllers leverage HTTP Status Codes (like 2xx for success, 4xx for client errors, 5xx for server errors) to provide feedback on API requests.

    A key concept discussed in the book is the “fat model, skinny controller” approach, which aims to place business logic in the Model (or supporting layers like services and behaviors) rather than the Controller. This promotes reusability and maintainability. Layers like Services (middleman for data fetching/saving), Behaviors (logic execution), Repositories (common queries), Orchestrations (coordinating services), and Unit of Work (managing database transactions) can be used to achieve separation of concerns within the “fat model”. The example refactors the AuthorsController to use a separate AuthorService and QueryOptionsCalculator behavior to demonstrate this principle.

    The final part of the book demonstrates these concepts by building a shopping cart application, showcasing how ASP.NET MVC 5 works together with Bootstrap and Knockout.js to create dynamic and responsive web pages. This includes building data models, implementing layouts using partial views and HtmlHelper methods, displaying lists of books, and adding, updating, and deleting cart items with dynamic UI updates using Knockout.js and Web API [Chapters 14-18].

    Building Web Apps with Bootstrap and ASP.NET MVC

    Based on the sources provided, Bootstrap is an HTML, CSS, and JavaScript framework used to create consistent-looking, responsive websites. Its primary purpose is to help developers build sleek and responsive views that render well on a variety of modern devices. By combining Bootstrap with server-side ASP.NET MVC and client-side Knockout.js, the framework allows for the rapid development of complex, dynamic, and responsive web applications. The book focuses on using ASP.NET MVC 5 with Bootstrap and Knockout.js to bring dynamic server-side content and responsive web design together.

    Bootstrap provides a set of custom components that facilitate building an incredible user experience using easy-to-implement HTML, CSS, and JavaScript. Many common Bootstrap components are automatically installed with MVC 5 applications and are immediately seen in action within the default project layout.

    Specific components and features discussed include:

    • Responsive Layout: Bootstrap provides a responsive web layout that automatically adjusts pages based on screen resolution.
    • Menus: Bootstrap defines menu structures using div with the navbar class, ul with the nav class, and li tags for elements. It includes features like inverse coloring (navbar-inverse), fixing the menu to the top (navbar-fixed-top), responsive collapsing for small devices (navbar-collapse, collapse, navbar-toggle), drop-downs (dropdown, dropdown-toggle, dropdown-menu, divider), and integrating elements like search boxes (navbar-form, navbar-right). Different styles like “pill” menus (nav-pills) are also available.
    • Buttons: Bootstrap includes six different themed buttons: Default, Primary, Success, Info, Warning, and Danger, which are created using the btn class along with a theme-specific class like btn-success. These classes can be applied to button tags, links, or submit buttons. Buttons can also be grouped (btn-group) and include drop-downs.
    • Alerts: The framework provides styled alert messages (Success, Info, Warning, Danger) using the alert class and a theme-specific class. Alerts can optionally be made dismissible using the alert-dismissible class and a close button with data-dismiss=”alert”.
    • Forms: Bootstrap provides classes for styling form elements and integrates with MVC client-side validation using jQuery.
    • Tables: Classes like table-bordered, table-striped, and table-hover can be used to style tables for better readability.
    • Pagination: A pagination component is used to create navigation links like “Next” and “Previous”, including styling to disable links on the first or last page.
    • Modals: Bootstrap modals can be used to display content, such as delete confirmations, in a dialog window over the current page. They are structured with classes like modal, modal-dialog, modal-content, modal-header, modal-body, and modal-footer.
    • Glyphicons: Bootstrap provides a set of icons (glyphicons) that can be easily included using span tags with appropriate classes, such as glyphicon glyphicon-sort or glyphicon glyphicon-trash.
    • Jumbotron: This feature is used to create a prominent display area or call-to-action, often seen near the top of a page.

    A significant advantage of using Bootstrap is that the developers have already written, organized, and tested much of the repetitive CSS code across a variety of web browsers. This saves developers time and provides confidence that the website will work consistently, allowing them to focus on building more sophisticated application features. The implementation effort for features like alert messages is also greatly alleviated.

    Bootstrap is automatically installed with MVC 5 project templates and can be managed or updated using the NuGet Package Manager in Visual Studio. Its core CSS is typically located in Content/bootstrap.css. The book notes that some features demonstrated align with Bootstrap version 3.3 documentation.

    While the book explores many components, it mentions that its examples “barely scratch the surface” of the numerous components Bootstrap offers. More complex components requiring JavaScript interaction are often covered in conjunction with Knockout.js integration. Bootstrap theming customization is noted as being outside the book’s scope.

    Understanding Knockout.js for Dynamic Web UIs

    Based on the provided sources, Knockout.js is an open source JavaScript library that allows developers to create dynamic and rich web applications. It is built with the Model-View-ViewModel (MVVM) pattern, and its primary purpose is to provide data binding between your ViewModel and your user interface (the View).

    The sources emphasize several key aspects and benefits of using Knockout.js:

    • Purpose and Benefits:
    • Knockout.js helps implement a complex user interface that responds to user interactions.
    • It enhances responsive web design with snappy client-side interactions driven by the server-side ASP.NET MVC application.
    • It provides sophisticated logic to automatically update the user interface based on user interaction.
    • It is described as lightweight and doesn’t try to be an all-in-one framework; it serves the single purpose of data binding.
    • Accomplishing tasks with Knockout.js takes very little time compared to writing plain JavaScript.
    • Its features are thoroughly tested in a variety of browsers, offering confidence that the web application will work consistently.
    • Integrating Knockout.js with Web API for dynamic UI updates without full-page reloads results in a much smoother user interface.
    • MVVM Implementation:
    • Implementing Knockout involves three distinct things: a view (HTML/CSS/JavaScript), a ViewModel (JavaScript code containing data), and telling Knockout to perform the data binding (ko.applyBindings).
    • The ViewModel should be organized to make it easy to represent how your View uses the data, distinct from how data might be stored in a database Model.
    • Core Concepts:
    • Data Binding: Achieved using easy-to-implement HTML attributes like data-bind. Various bindings are discussed and demonstrated, including:
    • text: Updates the text content of an element.
    • value: Binds the value of form input elements.
    • submit: Binds the submit event of a form to a function in the ViewModel.
    • visible: Controls the visibility of an element.
    • foreach: Repeats a block of HTML for each element in an array.
    • attr: Sets any HTML attribute dynamically.
    • css: Dynamically adds or removes CSS classes.
    • textInput: Similar to value but tracks every character change.
    • Observables: Special JavaScript variables that Knockout tracks for changes. When an observable changes, any UI element bound to it is automatically updated, and vice versa. Observables are accessed as functions to get or set their value (variable()), although Knockout is intelligent enough to handle this automatically in some contexts (like checking truthiness). Being mindful of how many observables are created is mentioned as important.
    • Observable Arrays: Observable variables specifically for arrays, tracking when items are added, removed, or replaced. UI elements bound to an observable array (like with foreach) update automatically when the array changes.
    • Computed Observables / Pure Computed: Functions whose values are automatically calculated based on the values of other observables they depend on. They update data bindings whenever their dependencies change. pureComputed is noted for avoiding unnecessary re-evaluations. Examples include calculating totals or determining CSS classes based on state.
    • Custom Features:
    • Custom Extenders: Add reusable custom behavior to observable properties. They can perform calculations or other logic when the observable’s value changes. The subTotal extender is demonstrated.
    • Custom Bindings: Encapsulate reusable UI logic and interaction with the ViewModel that goes beyond the built-in bindings. They are registered using ko.bindingHandlers. The isDirty binding (showing a button when a value changes) and appendToHref binding (dynamically appending a value to a link’s href) are demonstrated.
    • Custom Components: Encapsulate both a piece of HTML (template) and its corresponding ViewModel into a reusable, self-contained unit. They are registered using ko.components.register and can accept parameters. The upsert-cart-item component is demonstrated.
    • Integration with ASP.NET MVC and Web API:
    • Knockout ViewModels often receive data from the server-side ASP.NET MVC application, typically by serializing MVC Models or ViewModels to JSON using Razor and a helper extension, and then instantiating the JavaScript ViewModel with this data.
    • AJAX calls, often to Web API controllers returning JSON, are used to dynamically update the data in the Knockout ViewModel, which in turn updates the UI without full page reloads. HTTP Status Codes from Web API provide feedback on these requests.
    • Usage and Best Practices:
    • Knockout.js is installed using the NuGet Package Manager in Visual Studio and its script is included in the HTML layout, often via bundling and minification.
    • Using var self = this; in JavaScript ViewModels is presented as a way to easily reference other methods or properties within the ‘class’.
    • Applying Knockout bindings to a limited scope (e.g., a specific HTML element) is possible and can be useful when adding multiple Knockout bindings on the same page.
    • While Knockout is capable of powering dynamic interfaces, it’s suggested to use it sparingly where dynamic interaction is required, rather than on every page, as standard MVC views with Razor are sufficient otherwise.
    • The concept of single-page web applications, often built with libraries like Knockout, is mentioned, along with the idea that they make sense in certain situations (single focus) but not others (when page context changes).

    In summary, Knockout.js is presented as a valuable JavaScript library that simplifies building dynamic and responsive user interfaces by implementing the MVVM pattern through data binding, observables, and reusable components, particularly when integrated with ASP.NET MVC and Web API for server-side data handling.

    ASP.NET Web API: Building RESTful Applications

    Drawing on the provided sources and our conversation history, Web API is a technology within the ASP.NET framework used to build RESTful web applications. In this context, REST is described as a software architecture pattern commonly used for creating APIs or client-server applications.

    Here’s a discussion of Web API based on the sources:

    • Purpose and Integration with MVC and Knockout.js: Web API is easily integrated into the MVC architecture pattern, allowing for reuse between your MVC and Web API projects. The book demonstrates combining ASP.NET MVC, Bootstrap, and Knockout.js to build dynamic and responsive web applications. Specifically, integrating Knockout.js with Web API allows for dynamic UI updates without full-page reloads. This results in a much smoother user interface because Web API returns only JSON data (or XML) which Knockout then uses to dynamically update UI elements by data binding to observable properties.
    • Views in Web API: Unlike traditional MVC views that render HTML, the View in Web API is often a JSON or XML representation of the resource being interacted with. Knockout works particularly well with JSON data.
    • ViewModels as a Prerequisite: ViewModels are a prerequisite for Web API controllers because models are often the view. Data models that contain a circular relationship (like an author having many books and a book having one author) cannot be used directly in the return from a Web API action.
    • Setup and Controllers:
    • Web API can be included when a new MVC project is created in Visual Studio by selecting the Web API checkbox.
    • If not included initially, it can be installed later via the NuGet Package Manager, for instance, by using the command Install-Package Microsoft.AspNet.WebApi.
    • Installing via NuGet requires manual configuration in the App_Start folder. A WebApiConfig.cs file must be created to register Web API routes, and the Global.asax.cs file needs to be updated to configure these routes on application start.
    • Web API controllers are classes that extend a base ApiController class, similar to how MVC controllers extend the Controller class.
    • Routing and HTTP Verbs:
    • A default route for Web API is configured, typically using a template like api/{controller}/{id}. This means all Web API URLs are often prefixed with api/.
    • Web API controllers utilize common HTTP verbs associated with RESTful applications, such as GET, POST, PUT, and DELETE. When interacting with a RESTful API, the URL often stays consistent, and the request type (verb) changes to indicate the desired operation (e.g., POST for creating, PUT for editing).
    • Attribute routing ([Route]) can also be applied to Web API actions.
    • HTTP Status Codes: RESTful applications built with Web API heavily rely on HTTP Status Codes to provide feedback to the integrator. Common successful requests include 200 OK, 201 Created, and 204 No Content (2xx range). Client error requests (4xx range) include 400 Bad Request (for invalid input data), 401 Unauthorized, 404 Not Found, and 405 Method Not Allowed, often accompanied by helpful error messages in the response body. Server error requests (5xx range) include 500 Internal Server Error, 501 Not Implemented, and 503 Service Unavailable, also potentially with error details.
    • Filters: Web API supports the creation of global filters, similar to MVC.
    • Action filters can be used for tasks like global Web API validation. An Action filter can check if the ModelState.IsValid and, if not, immediately terminate the request and return a 400 Bad Request with details about the validation issues.
    • Exception filters are used for error handling. A global Exception filter can intercept exceptions and build a new HTTP response with a specific HTTP Status Code and tailored content based on the type of exception that occurred (e.g., returning a 404 Not Found for an ObjectNotFoundException or a generic 500 Internal Server Error for unknown exceptions).
    • Usage in Examples: The sources demonstrate using Web API controllers for:
    • Updating the listing of authors, performing sorting and paging via an AJAX request to a Web API controller that returns only an updated list of authors (JSON data). This data is then used by Knockout bindings to dynamically redraw the table.
    • Handling the saving (add/edit) of author data via AJAX requests. These requests use the POST or PUT verbs and send data as JSON. The Web API controller accepts the ViewModel, maps it to the data model, saves it, and returns a result (like 204 No Content for updates or 201 Created with the new item’s ID for additions).
    • Handling the saving (add/update/delete) of shopping cart items via AJAX requests using POST, PUT, or DELETE verbs.

    Building Data Models with Entity Framework

    Based on the sources, data model building is a fundamental aspect of creating web applications, particularly within the Model-View-Controller (MVC) architecture pattern, where the Model manages the data for the application. In the context of the provided material, data model building is closely tied to using Entity Framework (EF), an ORM (Object-Relational-Mapper), to interact with a database. An ORM like Entity Framework simplifies database access by converting a database table into a model, allowing it to be used like any other class in a project.

    The sources outline three different workflows for setting up and using Entity Framework within a project, which influence how you build your data models:

    • Database First: This workflow is used when you have an existing database or want complete control over database creation and maintenance. You create an EDMX file that stores your data schema, data models, and their relationships in XML. Visual Studio provides a designer for this. Creating the database tables manually is required before generating the models from it. This approach is considered very convenient when you want full control over database changes while still using an ORM.
    • Model First: Similar to Database First, models and relationships are maintained in an EDMX file. However, you manually create the models and define relationships using the Visual Studio designer, and then tell EF to create the necessary database tables, columns, and keys based on this design.
    • Code First: With Code First, you manually create your Model classes, and Entity Framework can automatically create the database and tables based on these classes if a database does not exist. You can also use EF tools to create initial Code First classes from an existing database. The power of Code First Migrations is highlighted as extremely convenient for automatically updating your database when your models change. The book’s examples primarily use the Code First approach because it translates better for demonstration purposes.

    Regardless of the workflow chosen, interacting with your models (adding, editing, deleting, and fetching data) will be the same.

    Specific Data Models in the Shopping Cart Example: For the practical shopping cart example, five data models are defined using the Code First approach:

    • Author Model: Contains information like Id, FirstName, LastName, and Biography. It also includes a virtual ICollection<Book> Books for the relationship where an Author can have many Books. A new feature introduced is the [NotMapped] attribute, used for a FullName property that concatenates FirstName and LastName; EF knows not to persist this property to the database.
    • Book Model: Stores details about a book including Id, AuthorId, CategoryId, Title, Isbn, Synopsis, Description, ImageUrl, ListPrice, SalePrice, and a Featured boolean. It contains foreign key properties (AuthorId, CategoryId) and virtual navigation properties (virtual Author Author, virtual Category Category) representing the relationships where a Book has one Author and one Category.
    • Category Model: Contains an Id and Name. It also includes a virtual ICollection<Book> Books for the relationship where a Category can have many Books.
    • Cart Model: Includes an Id and a SessionId. The SessionId is a unique identifier for the user’s cart. This property is decorated with [Index(IsUnique=true)] to create a unique database index for performance when searching, and [StringLength(255)] because indices are not compatible with the default nvarchar(max) for string fields. It has a virtual ICollection<CartItem> CartItems relationship.
    • CartItem Model: Contains Id, CartId, BookId, and Quantity. It primarily consists of relationships to the Cart and Book models via foreign keys and virtual navigation properties (virtual Cart Cart, virtual Book Book).

    Data models typically represent one or more tables within a database. Fields named Id are automatically recognized by Entity Framework as primary keys by convention. Similarly, fields with a related class name and “Id” (like AuthorId) are created as foreign keys. Virtual properties in models, especially navigation properties, are common for enabling features like lazy loading, where related data is only fetched when it is actually accessed, reducing upfront querying.

    Usage of Data Models:

    • Controllers: Controllers interact with data models to fetch or save data, often via a Database Context (DbContext) or a Service layer. They might perform data sanitation and validation based on model properties.
    • ViewModels: Data models are distinct from ViewModels. ViewModels are organized based on how the View uses the data, whereas Models represent how data is stored (e.g., in a database). Controllers are responsible for converting data models to ViewModels for the View, and vice versa when processing input. Returning a data model with a circular relationship (like Author having many Books and Book having one Author) directly from a Web API action is not possible, highlighting the need for ViewModels in such cases.
    • Services and Repositories: In a “fat model, skinny controller” architecture, services and repositories handle the business logic and data access, working with data models. The BookContext (the EF DbContext) is often owned by the service layer in this pattern.

    In summary, data model building in this context involves defining classes that map to database structures, often using Entity Framework’s conventions and attributes, and understanding their role in the overall application architecture alongside controllers, services, and viewmodels.

    Download PDF Book

    Read or Download PDF Book – Building Dynamic Responsive Web Applications with ASP.NET MVC

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog