<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Shekhar Tarare</title>
    <description>The latest articles on Forem by Shekhar Tarare (@shekhartarare).</description>
    <link>https://forem.com/shekhartarare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1119740%2F8aecdb99-0363-48cd-8467-939e3c03e325.jpg</url>
      <title>Forem: Shekhar Tarare</title>
      <link>https://forem.com/shekhartarare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shekhartarare"/>
    <language>en</language>
    <item>
      <title>A Simple Guide to Destructuring in JavaScript: Learn with Easy Examples</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Tue, 15 Oct 2024 20:39:49 +0000</pubDate>
      <link>https://forem.com/shekhartarare/a-simple-guide-to-destructuring-in-javascript-learn-with-easy-examples-574g</link>
      <guid>https://forem.com/shekhartarare/a-simple-guide-to-destructuring-in-javascript-learn-with-easy-examples-574g</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;JavaScript has a feature called destructuring that allows you to easily extract values from arrays or properties from objects and assign them to variables. Destructuring makes it easier to work with data, and it’s an essential tool for beginners learning JavaScript.&lt;br&gt;
In this post, we’ll break down destructuring with super simple examples so you can understand it in no time.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Destructuring?
&lt;/h2&gt;

&lt;p&gt;Imagine you have a box full of toys, and you want to take some toys out of the box and play with them. Instead of picking up each toy individually, destructuring allows you to grab the specific toys (or data) you need in one go!&lt;br&gt;
In JavaScript, destructuring lets you unpack values from arrays or extract properties from objects into variables. It’s a clean and convenient way to handle data, especially when working with complex arrays or objects.&lt;/p&gt;
&lt;h2&gt;
  
  
  Destructuring Arrays
&lt;/h2&gt;

&lt;p&gt;Let’s start with array destructuring. Arrays are like lists that hold multiple values, and destructuring allows you to take values from an array and assign them to variables in a single line of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Basic Array Destructuring&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['apple', 'banana', 'orange'];
// Destructuring the array
let [fruit1, fruit2, fruit3] = fruits;
console.log(fruit1); // Output: apple
console.log(fruit2); // Output: banana
console.log(fruit3); // Output: orange
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have an array called fruits, and we use destructuring to assign the values to fruit1, fruit2, and fruit3. Instead of accessing each element manually, destructuring lets us do it all at once!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2: Skipping Array Elements&lt;/strong&gt;&lt;br&gt;
You can also skip elements in an array using destructuring. Let’s say you only want the first and third fruit from the fruits array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['apple', 'banana', 'orange'];
// Skipping the second element
let [fruit1, , fruit3] = fruits;
console.log(fruit1); // Output: apple
console.log(fruit3); // Output: orange
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, by leaving a blank space (just a comma) in the destructuring pattern, we skip the second element (banana) and go straight to orange.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 3: Default Values in Array Destructuring&lt;/strong&gt;&lt;br&gt;
What if the array doesn’t have enough elements? You can set default values to avoid getting undefined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let colors = ['red'];
// Setting a default value for the second color
let [color1, color2 = 'blue'] = colors;
console.log(color1); // Output: red
console.log(color2); // Output: blue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since colors only has one element (red), the second variable (color2) gets the default value of ‘blue’.&lt;/p&gt;

&lt;h2&gt;
  
  
  Destructuring Objects
&lt;/h2&gt;

&lt;p&gt;Now, let’s move on to object destructuring. Objects are like containers that store key-value pairs, and destructuring helps you pull out specific properties easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 4: Basic Object Destructuring&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let person = {
  name: 'John',
  age: 30,
  job: 'developer'
};
// Destructuring the object
let { name, age, job } = person;
console.log(name); // Output: John
console.log(age);  // Output: 30
console.log(job);  // Output: developer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the person object has three properties: name, age, and job. Destructuring allows us to extract these properties into separate variables with the same names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 5: Assigning to New Variable Names&lt;/strong&gt;&lt;br&gt;
What if you want to assign these properties to variables with different names? You can do that easily with object destructuring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let car = {
  brand: 'Toyota',
  model: 'Corolla',
  year: 2020
};
// Assigning to new variable names
let { brand: carBrand, model: carModel, year: carYear } = car;
console.log(carBrand); // Output: Toyota
console.log(carModel); // Output: Corolla
console.log(carYear);  // Output: 2020
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we used brand: carBrand to assign the brand property to a new variable called carBrand, and similarly for model and year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 6: Default Values in Object Destructuring&lt;/strong&gt;&lt;br&gt;
Just like with arrays, you can set default values when destructuring objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let student = {
  name: 'Alice'
};
// Setting default value for age
let { name, age = 18 } = student;
console.log(name); // Output: Alice
console.log(age);  // Output: 18 (since age wasn't in the object)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the student object doesn’t have an age property, it defaults to 18.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 7: Nested Destructuring&lt;/strong&gt;&lt;br&gt;
Sometimes, objects can have other objects inside them. This is where nested destructuring comes in handy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let user = {
  name: 'Bob',
  address: {
    city: 'New York',
    zip: 10001
  }
};
// Destructuring nested object
let { name, address: { city, zip } } = user;
console.log(name);  // Output: Bob
console.log(city);  // Output: New York
console.log(zip);   // Output: 10001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we not only destructured the name property but also the city and zip from the nested address object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Destructuring?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Cleaner Code: Destructuring allows you to write cleaner and more readable code.&lt;/li&gt;
&lt;li&gt;Easier Data Handling: It’s much easier to extract data from arrays and objects without needing to write a lot of repetitive code.&lt;/li&gt;
&lt;li&gt;Default Values: You can set default values for variables, which helps prevent errors when values are missing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Destructuring is a powerful and simple feature in JavaScript that makes working with arrays and objects much easier. By using destructuring, you can write cleaner, more efficient code while saving time and reducing errors. Whether you’re a beginner or just learning JavaScript, destructuring is something you’ll use often in your coding journey.&lt;br&gt;
Start experimenting with destructuring, and see how it can simplify your code! Happy coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding the Spread Operator in JavaScript: A Simple Guide for Beginners</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Tue, 15 Oct 2024 18:06:13 +0000</pubDate>
      <link>https://forem.com/shekhartarare/understanding-the-spread-operator-in-javascript-a-simple-guide-for-beginners-43fd</link>
      <guid>https://forem.com/shekhartarare/understanding-the-spread-operator-in-javascript-a-simple-guide-for-beginners-43fd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;JavaScript is a fun programming language, and one of its most exciting features is the spread operator. If you’re just starting out with coding, or even if you’re a kid interested in learning JavaScript, don’t worry! I’ll break this concept down in the simplest way possible, with examples to help you understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Spread Operator?
&lt;/h2&gt;

&lt;p&gt;The spread operator looks like three dots (…). Just like how spreading butter across bread makes it cover everything evenly, the spread operator in JavaScript “spreads” or expands elements like arrays or objects, making them easy to work with.&lt;/p&gt;

&lt;p&gt;Imagine you have a bag of marbles. Instead of taking out each marble one by one, you can just pour them all out at once. That’s kind of what the spread operator does! It takes the items inside something (like an array or object) and “spreads” them out so you can work with them individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Do We Use the Spread Operator?
&lt;/h2&gt;

&lt;p&gt;The spread operator is most commonly used with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arrays (which are like lists of things)&lt;/li&gt;
&lt;li&gt;Objects (which are like containers that hold information)&lt;/li&gt;
&lt;li&gt;Functions (which are like recipes that perform a task)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s dive into each one with examples!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Spread Operator with Arrays
&lt;/h2&gt;

&lt;p&gt;An array is a list of items. Imagine you have two baskets of fruits and you want to combine all of them into one big basket. The spread operator can help you do that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Combining Arrays&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits1 = ['apple', 'banana'];
let fruits2 = ['orange', 'grape'];
// Using the spread operator to combine them into one array
let allFruits = [...fruits1, ...fruits2];
console.log(allFruits); // Output: ['apple', 'banana', 'orange', 'grape']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the spread operator takes the fruits from both fruits1 and fruits2 and combines them into one big basket called allFruits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2: Copying an Array&lt;/strong&gt;&lt;br&gt;
The spread operator also helps when you want to make a copy of an array. This is useful when you don’t want to change the original array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let originalArray = [1, 2, 3];
let copiedArray = [...originalArray];
console.log(copiedArray); // Output: [1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, you’ve made a copy of originalArray and stored it in copiedArray. Now you can change one without affecting the other!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Spread Operator with Objects
&lt;/h2&gt;

&lt;p&gt;Objects in JavaScript are like containers that store data in key-value pairs. The spread operator can be used to copy or combine objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 3: Copying an Object&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let person = { name: 'John', age: 25 };
// Copying the object using the spread operator
let copiedPerson = { ...person };
console.log(copiedPerson); // Output: { name: 'John', age: 25 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like with arrays, this makes a copy of the person object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 4: Combining Objects&lt;/strong&gt;&lt;br&gt;
Let’s say you want to combine two objects: one has personal details, and the other has contact details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let personalInfo = { name: 'Alice', age: 30 };
let contactInfo = { phone: '123-4567', email: 'alice@example.com' };
// Combining the objects
let completeInfo = { ...personalInfo, ...contactInfo };
console.log(completeInfo);
// Output: { name: 'Alice', age: 30, phone: '123-4567', email: 'alice@example.com' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the spread operator, we’ve combined personalInfo and contactInfo into a single object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Spread Operator with Functions
&lt;/h2&gt;

&lt;p&gt;The spread operator can also be used with functions to pass multiple arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 5: Passing an Array to a Function&lt;/strong&gt;&lt;br&gt;
If you have a function that expects multiple arguments, but you have them stored in an array, the spread operator can help spread the array elements as separate arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function addNumbers(a, b, c) {
  return a + b + c;
}
let numbers = [1, 2, 3];
// Using the spread operator to pass the array elements as arguments
let sum = addNumbers(...numbers);
console.log(sum); // Output: 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, numbers is an array, and the spread operator passes its values as arguments to the addNumbers function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use the Spread Operator?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Simplicity: It reduces the need for loops or complex code.&lt;/li&gt;
&lt;li&gt;Readability: It makes your code cleaner and easier to understand.&lt;/li&gt;
&lt;li&gt;Flexibility: It works well with both arrays and objects, making it very versatile.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The spread operator (…) is one of the coolest features of JavaScript! It helps you easily handle arrays, objects, and even functions. Whether you’re combining, copying, or spreading things out, the spread operator has you covered.&lt;/p&gt;

&lt;p&gt;The next time you need to work with arrays or objects, try using the spread operator — it will make your life much easier!&lt;/p&gt;

&lt;p&gt;By now, you should have a good understanding of how the spread operator works. Happy coding, and don’t forget to experiment with your own examples!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Integrating Stripe Checkout in an ASP.NET Core 8 Application: A Step-by-Step Guide</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Sat, 06 Jul 2024 09:16:29 +0000</pubDate>
      <link>https://forem.com/shekhartarare/integrating-stripe-checkout-in-an-aspnet-core-8-application-a-step-by-step-guide-1ijl</link>
      <guid>https://forem.com/shekhartarare/integrating-stripe-checkout-in-an-aspnet-core-8-application-a-step-by-step-guide-1ijl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will walk through the process of integrating Stripe Checkout into an ASP.NET Core NET Core 8 application. This guide will cover everything from setting up a new ASP.NET Core NET Core 8 project to creating a Stripe checkout session. This is ideal for developers looking to implement a seamless payment gateway in their web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up a New ASP.NET Core 8 Project
&lt;/h2&gt;

&lt;p&gt;First, let's create a new ASP.NET Core 8 project.&lt;br&gt;
Select the template ASP.NET Core Web App (Model-View-Controller). Give a project name and click Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3innrdggw44kszsbeu93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3innrdggw44kszsbeu93.png" alt="Create a new project" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select .NET 8 and click on Create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiw5amu4p5up9e1wkoy0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiw5amu4p5up9e1wkoy0m.png" alt="Additional info" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Adding Stripe Library
&lt;/h2&gt;

&lt;p&gt;Next, we need to add the Stripe library to our project. This will allow us to interact with the Stripe API.&lt;/p&gt;

&lt;p&gt;Go to Tools &amp;gt; NuGet Package Manager &amp;gt; Manage NuGet Packages for Solution. Search for stripe. net and install the latest version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwyudesndg08wzyfbuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwyudesndg08wzyfbuk.png" alt="Install package" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Configuring Stripe
&lt;/h2&gt;

&lt;p&gt;To use Stripe, we need to configure it with our secret key. Add your Stripe secret key in the appsettings.json file.&lt;/p&gt;

&lt;p&gt;Open appsettings.json and add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Stripe": {
        "SecretKey": "your_stripe_secret_key"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a StripeSettings class to represent this configuration in your  application. This class should be placed in your Models or Configuration folder. I am placing this is Models:&lt;br&gt;
StripeSettings.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace StripeCheckoutDemo.Models
{
    public class StripeSettings
    {
        public string? SecretKey { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update Program.cs to configure Stripe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Stripe;
using StripeCheckoutDemo.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
// Configure Stripe settings
builder.Services.Configure&amp;lt;StripeSettings&amp;gt;(builder.Configuration.GetSection("Stripe"));
StripeConfiguration.ApiKey = builder.Configuration["Stripe:SecretKey"];
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
    name: "checkout",
    pattern: "checkout/{action=Index}/{id?}",
    defaults: new { controller = "Checkout", action = "Index" });
app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Creating a Model for the Form Data
&lt;/h2&gt;

&lt;p&gt;Create a model to capture the form data for the Stripe checkout session.&lt;/p&gt;

&lt;p&gt;Add a new class CheckoutFormModel.cs in the Models folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace StripeCheckoutDemo.Models
{
    public class CheckoutFormModel
    {
        public string? ProductName { get; set; }
        public string? ProductDescription { get; set; }
        public long Amount { get; set; }
        public string? Currency { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Creating the Checkout Session Endpoint
&lt;/h2&gt;

&lt;p&gt;Create an endpoint to handle the form submission and create a Stripe checkout session. Also add a action methods for success and cancel.&lt;br&gt;
Add a new controller CheckoutController.cs in the Controllers folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using Stripe.Checkout;
using Stripe;
using StripeCheckoutDemo.Models;
namespace StripeCheckoutDemo.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CheckoutController : Controller
    {
        private readonly IConfiguration _configuration;
        public CheckoutController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        [HttpPost("create-checkout-session")]
        public IActionResult CreateCheckoutSession([FromBody] CheckoutFormModel model)
        {
            StripeConfiguration.ApiKey = _configuration["Stripe:SecretKey"];
            var options = new SessionCreateOptions
            {
                PaymentMethodTypes = new List&amp;lt;string&amp;gt; { "card" },
                LineItems = new List&amp;lt;SessionLineItemOptions&amp;gt;
            {
                new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        Currency = model.Currency,
                        ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name = model.ProductName,
                            Description = model.ProductDescription,
                        },
                        UnitAmount = model.Amount,
                    },
                    Quantity = 1,
                },
            },
                Mode = "payment",
                SuccessUrl = $"{Request.Scheme}://{Request.Host}/checkout/success",
                CancelUrl = $"{Request.Scheme}://{Request.Host}/checkout/cancel",
            };
            var service = new SessionService();
            var session = service.Create(options);
            return Ok(new { sessionId = session.Id });
        }
        [HttpGet("success")]
        public IActionResult Success()
        {
            return View();
        }
        [HttpGet("cancel")]
        public IActionResult Cancel()
        {
            return View();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Creating the Checkout Form
&lt;/h2&gt;

&lt;p&gt;Create a simple form using Bootstrap to capture the product details and amount for the Stripe checkout.&lt;br&gt;
Update the Index.cshtml file in the Views/Home folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page
@model CheckoutFormModel
@using StripeCheckoutDemo.Models
&amp;lt;form id="payment-form"&amp;gt;
    &amp;lt;div class="form-group pt-2"&amp;gt;
        &amp;lt;label for="productName"&amp;gt;Product Name&amp;lt;/label&amp;gt;
        &amp;lt;input type="text" class="form-control" id="productName" name="productName" placeholder="Enter product name" required&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="form-group pt-2"&amp;gt;
        &amp;lt;label for="productDescription"&amp;gt;Product Description&amp;lt;/label&amp;gt;
        &amp;lt;input type="text" class="form-control" id="productDescription" name="productDescription" placeholder="Enter product description" required&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="form-group pt-2"&amp;gt;
        &amp;lt;label for="amount"&amp;gt;Amount (in cents)&amp;lt;/label&amp;gt;
        &amp;lt;input type="number" class="form-control" id="amount" name="amount" placeholder="Enter amount" required&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="form-group pt-2"&amp;gt;
        &amp;lt;label for="currency"&amp;gt;Currency&amp;lt;/label&amp;gt;
        &amp;lt;select class="form-control" id="currency" name="currency" required&amp;gt;
            &amp;lt;option value="inr"&amp;gt;INR&amp;lt;/option&amp;gt;
            &amp;lt;!-- Add more currencies as needed --&amp;gt;
        &amp;lt;/select&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;button type="button" class="btn btn-primary mt-2" id="checkout-button"&amp;gt;Checkout&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
@section scripts {
    &amp;lt;script src="https://js.stripe.com/v3/"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
        var stripe = Stripe('enter_publishable_key');
        document.getElementById('checkout-button').addEventListener('click', function () {
            fetch('/checkout/create-checkout-session', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    productName: document.getElementById('productName').value,
                    productDescription: document.getElementById('productDescription').value,
                    amount: document.getElementById('amount').value,
                    currency: document.getElementById('currency').value
                })
            })
                .then(function (response) {
                    return response.json();
                })
                .then(function (session) {
                    return stripe.redirectToCheckout({ sessionId: session.sessionId });
                })
                .then(function (result) {
                    if (result.error) {
                        alert(result.error.message);
                    }
                })
                .catch(function (error) {
                    console.error('Error:', error);
                });
        });
    &amp;lt;/script&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Creating the Success Page
&lt;/h2&gt;

&lt;p&gt;Create a simple success page which will be shown after payment is done.&lt;br&gt;
Update the Success.cshtml file in the Views/Checkout folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{
    ViewData["Title"] = "Payment Successful";
}
&amp;lt;h2&amp;gt;Payment Successful&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Thank you for your purchase! Your payment has been successfully processed.&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 8: Creating the Cancel Page
&lt;/h2&gt;

&lt;p&gt;Create a simple cancel page which will be shown after payment is canceled.&lt;br&gt;
Update the Cancel.cshtml file in the Views/Checkout folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{
    ViewData["Title"] = "Payment Canceled";
}
&amp;lt;h2&amp;gt;Payment Canceled&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Your payment has been canceled. Please try again or contact support if you need assistance.&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 9: Running the Application
&lt;/h2&gt;

&lt;p&gt;Finally, run your  application to see the Stripe checkout integration in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete code on GitHub:
&lt;/h2&gt;

&lt;p&gt;Please find &lt;a href="https://github.com/ShekharTarare/Integrating-Stripe-Checkout-Dotnet-Core" rel="noopener noreferrer"&gt;here&lt;/a&gt; the complete code used in this blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You've successfully integrated Stripe Checkout into your ASP.NET Core NET Core 8 application. This guide provided step-by-step instructions to set up the project, configure Stripe, and create a checkout session. Now you can easily accept payments through Stripe in your web application.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>stripe</category>
      <category>aspdotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Creating an Umbraco Backoffice Accessor for Conditional Page Rendering</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Sat, 06 Jul 2024 07:42:41 +0000</pubDate>
      <link>https://forem.com/shekhartarare/creating-an-umbraco-backoffice-accessor-for-conditional-page-rendering-4f1k</link>
      <guid>https://forem.com/shekhartarare/creating-an-umbraco-backoffice-accessor-for-conditional-page-rendering-4f1k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Umbraco is a popular CMS that offers extensive customization and security features. One of the critical aspects of managing an Umbraco site is ensuring that only authenticated users can access certain parts of the site. In this guide, we'll create an accessor to check the user's authentication status in the Umbraco backoffice and use it in a view to conditionally display content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of ASP.NET Core.&lt;/li&gt;
&lt;li&gt;An existing Umbraco installation. (Check &lt;a href="https://shekhartarare.com/Archive/2024/6/how-to-create-a-new-umbraco-project" rel="noopener noreferrer"&gt;this&lt;/a&gt; blog to create a new umbraco 13 project)&lt;/li&gt;
&lt;li&gt;Visual Studio or any other C# IDE.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Umbraco Backoffice User Accessor
&lt;/h2&gt;

&lt;p&gt;First, we need to create an accessor that checks the user's authentication status in the backoffice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Define the IBackofficeUserAccessor Interface&lt;/strong&gt;&lt;br&gt;
This interface exposes the authentication status of the backoffice user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Security.Claims;
namespace YourNamespace
{
    public interface IBackofficeUserAccessor
    {
        ClaimsPrincipal BackofficeUser { get; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;br&gt;
This code defines an interface called IBackofficeUserAccessor with a property BackofficeUser of type ClaimsPrincipal. This interface will be implemented to access the user's claims.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Implement the BackofficeUserAccessor Class&lt;/strong&gt;&lt;br&gt;
This class implements the IBackofficeUserAccessor interface to retrieve the backoffice user's authentication status. There are some extra logging added to log errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using System.Security.Claims;
namespace YourNamespace
{
    public class BackofficeUserAccessor : IBackofficeUserAccessor
    {
        private readonly IOptionsSnapshot&amp;lt;CookieAuthenticationOptions&amp;gt; _cookieOptionsSnapshot;
        private readonly IHttpContextAccessor _httpContextAccessor;

        private readonly ILogger&amp;lt;BackofficeUserAccessor&amp;gt; _logger;
        public BackofficeUserAccessor(
            IOptionsSnapshot&amp;lt;CookieAuthenticationOptions&amp;gt; cookieOptionsSnapshot,
            IHttpContextAccessor httpContextAccessor,
            ILogger&amp;lt;BackofficeUserAccessor&amp;gt; logger
        )
        {
            _cookieOptionsSnapshot = cookieOptionsSnapshot;
            _httpContextAccessor = httpContextAccessor;
            _logger = logger; 
        }

        public ClaimsIdentity BackofficeUser
        {
            get
            {
                var httpContext = _httpContextAccessor.HttpContext;
                if (httpContext == null)
                {
                    _logger.LogWarning("BackofficeAUserAccessor: HttpContext is null.");
                    return new ClaimsIdentity();
                }

                CookieAuthenticationOptions cookieOptions = _cookieOptionsSnapshot.Get(Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType);

                string? backOfficeCookie = httpContext.Request.Cookies[cookieOptions.Cookie.Name!];
                if (string.IsNullOrEmpty(backOfficeCookie))
                {
                    _logger.LogWarning("BackofficeAUserAccessor: BackOffice cookie is null or empty.");
                    return new ClaimsIdentity();
                }
                AuthenticationTicket? unprotected;
                try
                {
                    unprotected = cookieOptions.TicketDataFormat.Unprotect(backOfficeCookie!);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "BackofficeAUserAccessor: Failed to unprotect the BackOffice cookie.");
                    return new ClaimsIdentity();
                }
                if (unprotected == null)
                {
                    _logger.LogWarning("BackofficeAUserAccessor: Unprotected authentication ticket is null.");
                    return new ClaimsIdentity();
                }
                ClaimsIdentity? backOfficeIdentity = unprotected.Principal.GetUmbracoIdentity();
                if (backOfficeIdentity == null)
                {
                    _logger.LogWarning("BackofficeAUserAccessor: BackOffice identity is null.");
                }
                else
                {
                    _logger.LogInformation("BackofficeAUserAccessor: User authenticated.");
                }
                return backOfficeIdentity;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Class Declaration&lt;/strong&gt;: BackofficeUserAccessor class implements the IBackofficeUserAccessor interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constructor&lt;/strong&gt;: The constructor accepts IOptionsSnapshot and IHttpContextAccessor to access cookie options and the current HTTP context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BackofficeUser Property&lt;/strong&gt;: This property checks if the current HTTP context is null. If not, it retrieves the backoffice  authentication cookie and checks if it's empty. If the cookie is valid, it unprotects the cookie and retrieves the user's claims principal. If not, it returns an empty claims principal.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Register the Accessor in Program.cs&lt;/strong&gt;&lt;br&gt;
Register the BackofficeUserAccessor in the dependency injection container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using InstallingUmbracoDemo;
using Umbraco.Cms.Core.Services;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Register IHttpContextAccessor
builder.Services.AddHttpContextAccessor();
// Register the BackofficeUserAccessor
builder.Services.AddTransient&amp;lt;IBackofficeUserAccessor, BackofficeUserAccessor&amp;gt;();

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddDeliveryApi()
    .AddComposers()
    .Build();
WebApplication app = builder.Build();
await app.BootUmbracoAsync();
app.UseUmbraco()
    .WithMiddleware(u =&amp;gt;
    {
        u.UseBackOffice();
        u.UseWebsite();
    })
    .WithEndpoints(u =&amp;gt;
    {
        u.UseInstallerEndpoints();
        u.UseBackOfficeEndpoints();
        u.UseWebsiteEndpoints();
    });
await app.RunAsync();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the Backoffice User Accessor in a Controller and View
&lt;/h2&gt;

&lt;p&gt;We can now use the BackofficeUserAccessor directly in our controller and views to conditionally render content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use BackofficeUserAccessor in a Controller&lt;/strong&gt;&lt;br&gt;
Inject the IBackofficeUserAccessor into your controller to check the user's  authentication status.&lt;/p&gt;

&lt;p&gt;YourController.cs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
namespace YourNamespace.Controllers
{
    public class YourController : Controller
    {
        private readonly IBackofficeUserAccessor _backofficeUserAccessor;
        public YourController(IBackofficeUserAccessor backofficeUserAccessor)
        {
            _backofficeUserAccessor = backofficeUserAccessor;
        }
        public IActionResult YourAction()
        {
            if (!_backofficeUserAccessor.BackofficeUser.IsAuthenticated)
            {
                return Unauthorized("You are not authorized to view this page.");
            }
            return View();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Constructor Injection:&lt;/strong&gt; The YourController class receives an instance of IBackofficeUserAccessor via its constructor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Check:&lt;/strong&gt; In the YourAction method, the user's  authentication status is checked using _backofficeUserAccessor. BackofficeUser. IsAuthenticated. If the user is not authenticated, it returns an Unauthorized result; otherwise, it renders the view.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Use BackofficeUserAccessor in a View&lt;/strong&gt;&lt;br&gt;
Use the IBackofficeUserAccessor directly in your Razor view to conditionally render content.&lt;/p&gt;

&lt;p&gt;YourView.cshtml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@inject YourNamespace.IBackofficeUserAccessor BackofficeUserAccessor
@if (BackofficeUserAccessor.BackofficeUser.IsAuthenticated)
{
    &amp;lt;h1&amp;gt;Welcome, authenticated user!&amp;lt;/h1&amp;gt;
    &amp;lt;!-- Your protected content goes here --&amp;gt;
}
else
{
    &amp;lt;h1&amp;gt;You are not authorized to view this content.&amp;lt;/h1&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Dependency Injection in View:&lt;/strong&gt; The BackofficeUserAccessor is injected into the view using the @inject directive.&lt;br&gt;
&lt;strong&gt;Conditional Rendering:&lt;/strong&gt; The view checks if the user is authenticated using BackofficeUserAccessor. BackofficeUser. IsAuthenticated. If the user is authenticated, it displays the protected content; otherwise, it shows an unauthorized message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Complete code:
&lt;/h2&gt;

&lt;p&gt;You can check the complete code &lt;a href="https://github.com/ShekharTarare/Umbraco-Backoffice-Accessor" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I have used  Umbraco 13.4.0 in the project. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these steps, you have created a backoffice user accessor that checks if a user is logged into the  Umbraco backoffice and used it to conditionally render content in your views. This ensures that only authenticated users can access specific parts of your site, enhancing its security.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>umbraco</category>
      <category>filter</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Securing Your Hangfire Dashboard in ASP.NET Core 8: Adding an Authorization Filter</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Sat, 06 Jul 2024 07:01:12 +0000</pubDate>
      <link>https://forem.com/shekhartarare/securing-your-hangfire-dashboard-in-aspnet-core-8-adding-an-authorization-filter-363g</link>
      <guid>https://forem.com/shekhartarare/securing-your-hangfire-dashboard-in-aspnet-core-8-adding-an-authorization-filter-363g</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In our previous blog post, we explored a step-by-step guide to scheduling API calls with Hangfire in ASP.NET Core. Now, we’ll enhance our application by adding an authorization filter to secure the Hangfire dashboard. This guide will walk you through implementing an authorization filter that ensures only authenticated users can access the Hangfire dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Authorization Filter to Hangfire Dashboard
&lt;/h2&gt;

&lt;p&gt;To restrict access to the Hangfire dashboard, create a custom authorization filter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a custom authorization filter class:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Hangfire.Dashboard;
using Microsoft.AspNetCore.Http;
public class MyAuthorizationFilter : IDashboardAuthorizationFilter
{
    public bool Authorize(DashboardContext context)
    {
        var httpContext = context.GetHttpContext();
        return httpContext.User.Identity.IsAuthenticated;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MyAuthorizationFilter class implements the IDashboardAuthorizationFilter interface provided by Hangfire.&lt;/li&gt;
&lt;li&gt;The Authorize method checks if the user is authenticated by accessing the HttpContext through context.GetHttpContext().&lt;/li&gt;
&lt;li&gt;It returns true if the user is authenticated (httpContext.User.Identity.IsAuthenticated), allowing access to the Hangfire dashboard; otherwise, it returns false, denying access.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Update the Program.cs to include the custom authorization filter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Hangfire;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext&amp;lt;ApplicationDbContext&amp;gt;(options =&amp;gt;
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddIdentity&amp;lt;IdentityUser, IdentityRole&amp;gt;()
    .AddEntityFrameworkStores&amp;lt;ApplicationDbContext&amp;gt;()
    .AddDefaultTokenProviders();
builder.Services.AddHangfire(config =&amp;gt; 
    config.UseSqlServerStorage(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHangfireServer();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
    Authorization = new[] { new MyAuthorizationFilter() }
});
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;builder.Services.AddHangfire (config =&amp;gt; config. UseSqlServerStorage (builder.Configuration. GetConnectionString (“DefaultConnection”))) configures Hangfire to use SQL Server for job storage.&lt;/li&gt;
&lt;li&gt;builder.Services.AddHangfireServer() adds Hangfire’s background processing server to the services collection.&lt;/li&gt;
&lt;li&gt;app.UseHangfireDashboard(“/hangfire”, new DashboardOptions { Authorization = new[] { new MyAuthorizationFilter() } }) configures the Hangfire dashboard to use the custom authorization filter we created earlier.&lt;/li&gt;
&lt;li&gt;The Authorization property of DashboardOptions is set to an array containing an instance of MyAuthorizationFilter, ensuring that only authenticated users can access the Hangfire dashboard.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following this guide, you have successfully added an authorization filter to secure the Hangfire dashboard in your ASP.NET Core 8 application. This setup ensures that only logged-in users can access sensitive scheduling data, enhancing the security of your application.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>aspdotnet</category>
      <category>hangfire</category>
      <category>api</category>
    </item>
    <item>
      <title>Step-by-Step Guide to Scheduling API Calls with Hangfire in ASP.NET Core</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Sat, 06 Jul 2024 06:47:40 +0000</pubDate>
      <link>https://forem.com/shekhartarare/step-by-step-guide-to-scheduling-api-calls-with-hangfire-in-aspnet-core-106l</link>
      <guid>https://forem.com/shekhartarare/step-by-step-guide-to-scheduling-api-calls-with-hangfire-in-aspnet-core-106l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the last blog post, we created a test API in ASP.NET Core NET Core. If you haven’t checked that, here’s the &lt;a href="https://shekhartarare.com/Archive/2024/6/creating-a-simple-asp-dotnet-core-api" rel="noopener noreferrer"&gt;link&lt;/a&gt; for that blog. In this blog post, we’ll walk you through the steps to integrate Hangfire in your ASP.NET Core NET Core project to schedule an API to run daily. Hangfire is a powerful library that simplifies background job processing in .NET applications, making it an excellent choice for scheduling tasks. Follow along to learn how to set up Hangfire and configure it to run your API on a daily basis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Hangfire for Background Jobs in ASP.NET Core?
&lt;/h2&gt;

&lt;p&gt;Before diving into the implementation, let’s understand why Hangfire is a preferred choice for background jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Use&lt;/strong&gt;: Hangfire is simple to set up and use, allowing you to focus on your application’s core functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: It can handle a large number of jobs and is scalable to meet your application’s demands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: Hangfire ensures that jobs are executed even after server restarts, providing reliability for critical tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard&lt;/strong&gt;: It comes with a built-in dashboard for monitoring jobs, making it easy to track and manage background processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Scheduling Provided by Hangfire
&lt;/h2&gt;

&lt;p&gt;Hangfire supports various types of background jobs, making it flexible to use in different scenarios. Here are the main types of scheduling it provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fire-and-Forget Jobs&lt;/strong&gt;: These jobs are executed only once and almost immediately after creation. They are useful for tasks that need to be done quickly and don’t need to be repeated.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BackgroundJob.Enqueue(() =&amp;gt; Console.WriteLine("Fire-and-forget job executed!"));


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delayed Jobs&lt;/strong&gt;: These jobs are executed only once but not immediately. They are scheduled to run after a specified delay.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BackgroundJob.Schedule(() =&amp;gt; Console.WriteLine("Delayed job executed!"), TimeSpan.FromDays(1));



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recurring Jobs&lt;/strong&gt;: These jobs are executed many times on a specified CRON schedule. They are useful for tasks that need to run on a regular basis.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

RecurringJob.AddOrUpdate(() =&amp;gt; Console.WriteLine("Recurring job executed!"), Cron.Daily);



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuations&lt;/strong&gt;: These jobs are executed when their parent job has finished. They are useful for workflows where a job depends on the successful completion of another job.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

var jobId = BackgroundJob.Enqueue(() =&amp;gt; Console.WriteLine("Parent job executed!"));
BackgroundJob.ContinueWith(jobId, () =&amp;gt; Console.WriteLine("Continuation job executed!"));


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2019 or later&lt;/li&gt;
&lt;li&gt;. NET Core SDK installed&lt;/li&gt;
&lt;li&gt;Basic knowledge of ASP.NET Core NET Core&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step-by-Step Guide to Integrate Hangfire
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a New ASP.NET Core Web API Project&lt;/strong&gt;&lt;br&gt;
First, create a new ASP.NET Core project or open an existing one. If you don’t have any project, then follow the steps mentioned &lt;a href="https://shekhartarare.com/Archive/2024/6/creating-a-simple-asp-dotnet-core-api" rel="noopener noreferrer"&gt;here&lt;/a&gt; to create one. I have also added the steps for creating a test API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install Hangfire NuGet package&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Tools &amp;gt; NuGet Package Manager &amp;gt; Manage NuGet Packages for Solution…&lt;/li&gt;
&lt;li&gt;Search for Hangfire and install the latest one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hzx6jnozg6z9jel04o0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hzx6jnozg6z9jel04o0.png" alt="Install hangfire"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for System.Data.SqlClient and install the latest one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mw30uz156whd923czs7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mw30uz156whd923czs7.png" alt="Install sqlclient"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a database for using with Hangfire&lt;/strong&gt;&lt;br&gt;
Open SSMS and create a new Database. You can use the existing one also.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnojjthjj5gknxlfz35t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnojjthjj5gknxlfz35t.png" alt="Create db"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Add connection string to appsettings.json&lt;/strong&gt;&lt;br&gt;
In the appsettings.json file, add the connection string for your SQL Server:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "TestDatabase": "Server=SHEKHAR\\SQLEXPRESS;Database=HangfireDemo;TrustServerCertificate=True;User Id=adminuser;Password=adminuser;"
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Configure Hangfire in Program.cs&lt;/strong&gt;&lt;br&gt;
Modify the Program.cs file to configure Hangfire:&lt;/p&gt;

&lt;p&gt;I have added the steps on the comments.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

using Hangfire;
using Hangfire.SqlServer;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Step 1 -&amp;gt; Hangfire configuration with SQL Server storage

var connectionString = builder.Configuration.GetConnectionString("TestDatabase"); 
builder.Services.AddHangfire(config =&amp;gt;
{
    config.UseSqlServerStorage(connectionString, new SqlServerStorageOptions
    {
        CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
        SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
        QueuePollInterval = TimeSpan.Zero,
        UseRecommendedIsolationLevel = true,
        DisableGlobalLocks = true
    });
});
// Step 2 -&amp;gt; Add Hangfire's server.
builder.Services.AddHangfireServer();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
//Step 3 -&amp;gt; Added the dashboard url
app.UseHangfireDashboard("/hangfire");
app.Run();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Create a Background Job to Call the API&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a background job that calls your API. For this example, I am using my API endpoint which is &lt;a href="https://localhost:7282/api/TestApi" rel="noopener noreferrer"&gt;https://localhost:7282/api/TestApi&lt;/a&gt;. We need to create a service to call this endpoint and then schedule it with Hangfire.&lt;/li&gt;
&lt;li&gt;Create a new service class ApiCallService.cs and add the below code:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

namespace TestApi
{
    public class ApiCallService
    {
        private readonly HttpClient _httpClient;
        public ApiCallService(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }
        public async Task CallApiEndpointAsync()
        {
            var response = await _httpClient.GetAsync("https://localhost:7282/api/TestApi");
            response.EnsureSuccessStatusCode();
            // Log success or handle the response as needed
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Register the HttpClient and ApiCallService in Program.cs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

builder.Services.AddHttpClient&amp;lt;ApiCallService&amp;gt;();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Schedule the job in Program.cs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// Schedule the job to call the API endpoint
RecurringJob.AddOrUpdate&amp;lt;ApiCallService&amp;gt;("call-api-endpoint", service =&amp;gt; service.CallApiEndpointAsync(), Cron.Daily); // Adjust the schedule as needed



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Final Program.cs code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

using Hangfire;
using Hangfire.SqlServer;
using TestApi;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Step 1 -&amp;gt; Hangfire configuration with SQL Server storage
var connectionString = builder.Configuration.GetConnectionString("TestDatabase"); 
builder.Services.AddHangfire(config =&amp;gt;
{
    config.UseSqlServerStorage(connectionString, new SqlServerStorageOptions
    {
        CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
        SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
        QueuePollInterval = TimeSpan.Zero,
        UseRecommendedIsolationLevel = true,
        DisableGlobalLocks = true
    });
});
// Step 2 -&amp;gt; Add Hangfire's server.
builder.Services.AddHangfireServer();
// Register httpclient
builder.Services.AddHttpClient&amp;lt;ApiCallService&amp;gt;();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
//Step 3 -&amp;gt; Added the dashboard url
app.UseHangfireDashboard("/hangfire");
// Schedule the job to call the API endpoint
RecurringJob.AddOrUpdate&amp;lt;ApiCallService&amp;gt;("call-api-endpoint", service =&amp;gt; service.CallApiEndpointAsync(), Cron.Daily); // Adjust the schedule as needed
app.Run();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Run and Monitor Your Application&lt;/strong&gt;&lt;br&gt;
After running the project. You will see some new tables got created in the database. Hangfire creates those to track the jobs and to perform other things:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnld23gq38t8sqdg1hee7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnld23gq38t8sqdg1hee7.png" alt="DB Created"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access the Hangfire Dashboard at &lt;a href="https://localhost:7282/hangfire/" rel="noopener noreferrer"&gt;https://localhost:7282/hangfire/&lt;/a&gt; to monitor your background jobs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vihcg4fwecohci22et0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vihcg4fwecohci22et0.png" alt="Hangfire dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Recurring Jobs tab to see all the recurring jobs. Currently it’s showing only one which we have scheduled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F747wmvndgg60xgl40azf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F747wmvndgg60xgl40azf.png" alt="Recurring job"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Jobs &amp;gt; Succeeded to see the status of the jobs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr4queigdlr23uog0c65.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr4queigdlr23uog0c65.png" alt="Succeeded job"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get more details click on that job:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j76h2a6nqywszvqubb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j76h2a6nqywszvqubb0.png" alt="More detail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final code on GitHub:
&lt;/h2&gt;

&lt;p&gt;Here’s the GitHub &lt;a href="https://github.com/ShekharTarare/Schedule-API-Call-With-Hangfire" rel="noopener noreferrer"&gt;link&lt;/a&gt; for the repo where all the code has been added.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following this guide, you have integrated Hangfire into your . NET 8 project and scheduled an API call using Hangfire with SQL Server as the storage provider. This setup ensures your API is called regularly according to the specified schedule. For more advanced Hangfire configurations and storage options, refer to the &lt;a href="https://www.hangfire.io/" rel="noopener noreferrer"&gt;official Hangfire documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>hangfire</category>
      <category>api</category>
      <category>webdev</category>
      <category>aspdotnet</category>
    </item>
    <item>
      <title>Creating a Simple ASP.NET Core Web API for Testing Purposes</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Fri, 05 Jul 2024 16:16:18 +0000</pubDate>
      <link>https://forem.com/shekhartarare/creating-a-simple-aspnet-core-web-api-for-testing-purposes-36f7</link>
      <guid>https://forem.com/shekhartarare/creating-a-simple-aspnet-core-web-api-for-testing-purposes-36f7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ASP.NET Core NET Core is a powerful framework for building web APIs. In this tutorial, we will walk you through creating a simple API for testing. Whether you are a beginner or looking to refresh your knowledge, this guide will help you set up a basic web API project in no time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, ensure you have the following installed on your development machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio (2019 or later)&lt;/li&gt;
&lt;li&gt;.NET Core SDK (I am using 8 for this tutorial)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Guide to Creating a Simple ASP.NET Core API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a New Web API Project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Visual Studio.&lt;/li&gt;
&lt;li&gt;Click on Create a new project.&lt;/li&gt;
&lt;li&gt;Select the template ASP.NET Core NET Core Web API Application and click Next.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhyqoigjrj4ow04esr37v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhyqoigjrj4ow04esr37v.png" alt="Create a new project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name your project and click Next.&lt;/li&gt;
&lt;li&gt;Provide Additional information. I am selecting . NET 8.0 as a framework. Click Create.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfufkq8p8z92h1j60ywc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfufkq8p8z92h1j60ywc.png" alt="additional info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the project gets created. You will find one controller by default available called WeatherForecastController.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38jyp42zbxn2dbft5fpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38jyp42zbxn2dbft5fpo.png" alt="api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create our API&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right click on Controllers &amp;gt; Add &amp;gt; Controller.&lt;/li&gt;
&lt;li&gt;Click on API on the left and select API Controller — Empty.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyjy5t9dvgaayizcc69l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyjy5t9dvgaayizcc69l.png" alt="Create controller"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give it a name and click on Add.&lt;/li&gt;
&lt;li&gt;Add the following code. I am adding one get method which is just returning “Hello World!”.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace TestApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TestApiController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new { Message = "Hello, World!" });
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Run the Application&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press F5 to run the application.&lt;/li&gt;
&lt;li&gt;You will see the Swagger UI with your API endpoints listed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziphv05qq7vxq5mvsvv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziphv05qq7vxq5mvsvv0.png" alt="run project"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Step 4: Test the API Endpoints&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the Swagger UI, you can test the endpoints.&lt;/li&gt;
&lt;li&gt;Click on execute and it will give the data as response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi6k8sasz32ke7yfhllf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi6k8sasz32ke7yfhllf.png" alt="test api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you want to check which URL it’s hitting then open developer tools and go to network tab. Click on execute button for the endpoint and you will see one request on the network. Click on it. On the Headers tab, you will get the Request URL. That’s the API URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmk0h84jgr0j5avrua47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmk0h84jgr0j5avrua47.png" alt="Inspect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can even run the URL on the new tab and it will give the response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe651gxo7yfenmsq1lz3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe651gxo7yfenmsq1lz3c.png" alt="Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You’ve successfully created a simple ASP.NET Core NET Core API for testing purposes. This basic setup can serve as a foundation for more complex APIs. Remember, practice makes perfect, so continue experimenting and building upon what you’ve learned.&lt;/p&gt;

&lt;p&gt;In the next blog, we will schedule this test API call with Hangfire. Here’s the &lt;a href="https://shekhartarare.com/Archive/2024/6/step-by-step-guide-to-scheduling-api-calls-with-hangfire" rel="noopener noreferrer"&gt;link&lt;/a&gt; for that blog.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>aspdotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create an API in Umbraco in 5 Minutes: A Quick Guide for Developers</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Fri, 05 Jul 2024 14:26:39 +0000</pubDate>
      <link>https://forem.com/shekhartarare/create-an-api-in-umbraco-in-5-minutes-a-quick-guide-for-developers-32cj</link>
      <guid>https://forem.com/shekhartarare/create-an-api-in-umbraco-in-5-minutes-a-quick-guide-for-developers-32cj</guid>
      <description>&lt;h2&gt;
  
  
  Why Create an API in Umbraco?
&lt;/h2&gt;

&lt;p&gt;APIs (Application Programming Interfaces) allow different software systems to communicate with each other. By creating an API in Umbraco, you can enable external applications to interact with your website’s content, offering enhanced functionality and improved user experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Umbraco installation&lt;/li&gt;
&lt;li&gt;Visual Studio or your preferred IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Set Up Your Umbraco Project
&lt;/h2&gt;

&lt;p&gt;First, ensure your Umbraco project is set up correctly. If you haven’t installed Umbraco yet, follow the steps mentioned &lt;a href="https://shekhartarare.com/Archive/2024/6/how-to-create-a-new-umbraco-project" rel="noopener noreferrer"&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create the API Controller
&lt;/h2&gt;

&lt;p&gt;Add a New Folder called Controllers: Add a new class file and name it MyAPIController.cs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kbuswyo7cf8wq51yx9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kbuswyo7cf8wq51yx9i.png" alt="Create an api controller"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write the API Code:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;using Microsoft.AspNetCore.Mvc;&lt;br&gt;
using Umbraco.Cms.Web.Common.Controllers;&lt;br&gt;
namespace InstallingUmbracoDemo.Controllers&lt;br&gt;
{&lt;br&gt;
    public class MyAPIController : UmbracoApiController&lt;br&gt;
    {&lt;br&gt;
        [HttpGet]&lt;br&gt;
        public string GetGreeting()&lt;br&gt;
        {&lt;br&gt;
            return "Hello, Umbraco API!";&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Step 3: Test Your API&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;We don’t need to do anything about routing. Umbraco will automatically handle that for us. Now, let’s test our API:&lt;/p&gt;

&lt;p&gt;Open your browser and navigate to &lt;a href="http://yourdomain.com/umbraco/api/myapi/getgreeting" rel="noopener noreferrer"&gt;http://yourdomain.com/umbraco/api/myapi/getgreeting&lt;/a&gt;. You should see the message “Hello, Umbraco API!”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla3kefyu2xkfm0s176xk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla3kefyu2xkfm0s176xk.png" alt="Final output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating an API in Umbraco is quick and easy, allowing you to expand the functionality of your website and integrate with external systems. By following the steps outlined in this guide, you can set up a basic API in just 5 minutes without the need for additional routing configuration.&lt;/p&gt;

&lt;p&gt;For more advanced Umbraco tutorials and tips, stay tuned to our blog and feel free to leave your questions in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>umbraco</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Create a New Umbraco Project: A Step-by-Step Guide</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Fri, 05 Jul 2024 12:58:49 +0000</pubDate>
      <link>https://forem.com/shekhartarare/how-to-create-a-new-umbraco-project-a-step-by-step-guide-4bel</link>
      <guid>https://forem.com/shekhartarare/how-to-create-a-new-umbraco-project-a-step-by-step-guide-4bel</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Umbraco
&lt;/h2&gt;

&lt;p&gt;Umbraco is a highly versatile and user-friendly CMS that allows developers to create dynamic websites and applications. Known for its flexibility and extensive customization options, Umbraco is ideal for a range of projects from small blogs to large enterprise solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, ensure you have the following prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2019 or later&lt;/li&gt;
&lt;li&gt;NET SDK installed (version 8)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing Umbraco
&lt;/h2&gt;

&lt;p&gt;To install Umbraco, follow these steps:&lt;br&gt;
&lt;strong&gt;Step 1: Install Umbraco Template&lt;/strong&gt;&lt;br&gt;
dotnet new install Umbraco.Templates::13.4.0 to install the project templates. After installing that, you will see the umbraco templates while creating a new project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fits7loqk7x7ipyk0o97v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fits7loqk7x7ipyk0o97v.png" alt="Install umbraco template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a New Project&lt;/strong&gt;&lt;br&gt;
Open Visual Studio and create a new Umbraco Project. Name your project and choose the appropriate location. Select the Framework and fill other additional information if needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyotgduqgbpff3fzwjyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyotgduqgbpff3fzwjyu.png" alt="Create a new project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Your project
&lt;/h2&gt;

&lt;p&gt;Run the project. You will get the below screen. Add your details and click on Change database if you don’t want to use SQLite and click on Install.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyftrnck054o6kdzf797k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyftrnck054o6kdzf797k.png" alt="Install umbraco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will get the below screen. Add your credentials and login.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtao2d5d2ttkrv46iaqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtao2d5d2ttkrv46iaqi.png" alt="Login screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After login, this screen will come:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdec0nnsl2oymzestl2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdec0nnsl2oymzestl2a.png" alt="After login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating a new Umbraco project is straightforward and highly customizable, making it a great choice for developers of all levels. By following this step-by-step guide, you can set up your Umbraco project and start building dynamic, content-rich websites.&lt;/p&gt;

&lt;p&gt;If you found this guide helpful, consider sharing it with others looking to get started with Umbraco. Happy coding!&lt;/p&gt;

</description>
      <category>umbraco</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Step-by-Step Guide to Reading CSV Files in ASP.NET Core</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Fri, 05 Jul 2024 12:33:08 +0000</pubDate>
      <link>https://forem.com/shekhartarare/step-by-step-guide-to-reading-csv-files-in-aspnet-core-5ca</link>
      <guid>https://forem.com/shekhartarare/step-by-step-guide-to-reading-csv-files-in-aspnet-core-5ca</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Reading and displaying data from a CSV file is a common requirement in web applications applications. In this guide, we’ll walk through the steps to build an ASP.NET Core NET Core 8 application that reads a CSV file uploaded by a user and displays the data in a styled HTML table. We’ll also cover error handling to manage any issues that may arise during the file processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a New ASP.NET Core Web Application
&lt;/h2&gt;

&lt;p&gt;Start by creating a new ASP.NET Core Web Application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new webapp -n CsvReaderApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Install CsvHelper Package
&lt;/h2&gt;

&lt;p&gt;Install the CsvHelper package which will help us read the CSV file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package CsvHelper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Add the User Model
&lt;/h2&gt;

&lt;p&gt;Create a new folder called Models and add a User.cs file. The headers of the CSV file and the fields here should match as we will be getting the data into this model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CsvReaderApp.Models
{
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Add the CsvService Class
&lt;/h2&gt;

&lt;p&gt;Create a new folder called Services and add a CsvService.cs file. This class will be responsible for parsing the CSV file and converting it to a list of User objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CsvHelper;
using CsvHelper.TypeConversion;
using CsvReaderApp.Models;
using System.Globalization;
namespace CsvReaderApp.Services
{
    public class CsvService
    {
        public IEnumerable&amp;lt;User&amp;gt; ReadCsvFile(Stream fileStream)
        {
            try
            {
                using (var reader = new StreamReader(fileStream))
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    var records = csv.GetRecords&amp;lt;User&amp;gt;();
                    return records.ToList();
                }
            }
            catch (HeaderValidationException ex)
            {
                // Specific exception for header issues
                throw new ApplicationException("CSV file header is invalid.", ex);
            }
            catch (TypeConverterException ex)
            {
                // Specific exception for type conversion issues
                throw new ApplicationException("CSV file contains invalid data format.", ex);
            }
            catch (Exception ex)
            {
                // General exception for other issues
                throw new ApplicationException("Error reading CSV file", ex);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Create the CsvImporterController
&lt;/h2&gt;

&lt;p&gt;Create a new folder called Controllers and add a CsvImporterController.cs file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CsvReaderApp.Models;
using CsvReaderApp.Services;
using Microsoft.AspNetCore.Mvc;
namespace CsvReaderApp.Controllers
{
    [Route("[controller]")]
    public class CsvImporterController : Controller
    {
        private readonly CsvService _csvService;
        public CsvImporterController(CsvService csvService)
        {
            _csvService = csvService;
        }
        [HttpGet("")]
        [HttpGet("Index")]
        public IActionResult Index()
        {
            return View(new List&amp;lt;User&amp;gt;());
        }
        [HttpPost("")]
        [HttpPost("Index")]
        public IActionResult Index(IFormFile csvFile)
        {
            if (csvFile != null &amp;amp;&amp;amp; csvFile.Length &amp;gt; 0)
            {
                using (var stream = csvFile.OpenReadStream())
                {
                    try
                    {
                        var users = _csvService.ReadCsvFile(stream).ToList();
                        return View(users); // Return users list to the view
                    }
                    catch (ApplicationException ex)
                    {
                        ModelState.AddModelError(string.Empty, ex.Message);
                    }
                    catch (Exception ex)
                    {
                        ModelState.AddModelError(string.Empty, $"An unexpected error occurred: {ex.Message}");
                    }
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Please select a valid CSV file.");
            }
            return View(new List&amp;lt;User&amp;gt;());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Create the View
&lt;/h2&gt;

&lt;p&gt;Right click on the Index action method on controller and click on Add View and give it a name as Index.cshtml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@model IEnumerable&amp;lt;CsvReaderApp.Models.User&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;CSV File Upload&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="~/css/site.css"&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        &amp;lt;h1&amp;gt;Upload CSV File&amp;lt;/h1&amp;gt;
        &amp;lt;form asp-controller="Home" asp-action="Upload" method="post" enctype="multipart/form-data"&amp;gt;
            &amp;lt;div class="form-group"&amp;gt;
                &amp;lt;input type="file" name="csvFile" class="form-control" required&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;button type="submit" class="btn btn-primary"&amp;gt;Upload&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
        @if (Model != null &amp;amp;&amp;amp; Model.Any())
        {
            &amp;lt;h2&amp;gt;User List&amp;lt;/h2&amp;gt;
            &amp;lt;table class="table"&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th&amp;gt;Id&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Email&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                &amp;lt;tbody&amp;gt;
                    @foreach (var user in Model)
                    {
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;@user.Id&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;@user.Name&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;@user.Email&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    }
                &amp;lt;/tbody&amp;gt;
            &amp;lt;/table&amp;gt;
        }
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Configure Services and Routing
&lt;/h2&gt;

&lt;p&gt;I am using .NET 8. Here, we don’t have the Startup.cs file. Instead, we have to configure services and routing in the Program.cs file. Open the Program.cs file and update it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CsvReaderApp.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddTransient&amp;lt;CsvService&amp;gt;(); // Register CsvService
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapControllerRoute(
        name: "default",
        pattern: "{controller=CsvImporter}/{action=Index}/{id?}");
app.UseAuthorization();
app.MapRazorPages();
app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 8: Add CSS for Styling
&lt;/h2&gt;

&lt;p&gt;Create a wwwroot/css/site.css file to style the form and table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html {
    font-size: 14px;
}
@media (min-width: 768px) {
    html {
        font-size: 16px;
    }
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
html {
    position: relative;
    min-height: 100%;
}
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 20px;
    margin-bottom: 60px;
}
.container {
    max-width: 800px;
    margin: 0 auto;
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1, h2 {
    text-align: center;
}
form {
    margin-bottom: 20px;
}
.form-group {
    margin-bottom: 15px;
}
.form-control {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
}
.btn-primary {
    background-color: #007bff;
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
    .btn-primary:hover {
        background-color: #0056b3;
    }
.table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
}
    .table th, .table td {
        padding: 12px;
        border: 1px solid #ccc;
    }
    .table th {
        background-color: #f2f2f2;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Output:
&lt;/h2&gt;

&lt;p&gt;As we have added a routing, you will get the output here in this URL: &lt;a href="https://localhost:7039/csvimporter" rel="noopener noreferrer"&gt;https://localhost:7039/csvimporter&lt;/a&gt;. This is how it looks after selecting the file and clicking on upload:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9fs4p5mfkml1tojqldo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9fs4p5mfkml1tojqldo.png" alt="Final output" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete Code on GitHub
&lt;/h2&gt;

&lt;p&gt;For the complete code with a csv file for testing, you can visit the GitHub repository. Feel free to clone or download the project and experiment with it further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these steps, you can create an ASP.NET Core NET Core 8 application that allows users to upload CSV files and displays the data in a styled HTML table. This setup includes proper error handling to manage any issues that may arise during file processing. Happy coding!&lt;/p&gt;

</description>
      <category>aspdotnet</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Resolving the "Length of LOB Data (78862) to be Replicated Exceeds Configured Maximum 65536" Error</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Fri, 07 Jun 2024 22:19:22 +0000</pubDate>
      <link>https://forem.com/shekhartarare/resolving-the-length-of-lob-data-78862-to-be-replicated-exceeds-configured-maximum-65536-error-bfb</link>
      <guid>https://forem.com/shekhartarare/resolving-the-length-of-lob-data-78862-to-be-replicated-exceeds-configured-maximum-65536-error-bfb</guid>
      <description>&lt;h2&gt;
  
  
  Understanding the Error
&lt;/h2&gt;

&lt;p&gt;The error indicates that the LOB data size (78862 bytes) exceeds the configured maximum limit (65536 bytes) set for replication in SQL Server. This typically happens during the replication process, leading to the failure of data transfer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Causes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Default Configuration Limits:&lt;/strong&gt; SQL Server has default settings for the maximum size of LOB data that can be replicated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large Data Inserts:&lt;/strong&gt; Inserting large multimedia files or extensive text data can exceed the default LOB size limit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inadequate Configuration Settings:&lt;/strong&gt; The database settings might not be optimized for handling large LOB data, resulting in replication issues.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solutions to Resolve the Error
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Adjusting the 'max text repl size' Configuration Option&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server provides a simple yet effective way to handle large LOB data during replication by adjusting the max text repl size configuration option. Here's how you can do it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EXEC sp_configure 'max text repl size', &amp;lt;desired_value&amp;gt;;
RECONFIGURE;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace  with the desired maximum size. You can also set it to -1 for the maximum supported size (2 GB).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After making the configuration changes, restart the SQL Server service to apply the modifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adjusting max text repl size Through SQL Server Management Studio&lt;/strong&gt;&lt;br&gt;
Additionally, you can adjust another setting in SQL Server to accommodate larger LOB data during replication. This setting is called max text repl size. Here's how you can change it through SQL Server Management Studio (SSMS):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open SQL Server Management Studio (SSMS):&lt;/strong&gt;&lt;br&gt;
Launch SSMS and connect to your SQL Server instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Right-click the server and select Properties:&lt;/strong&gt;&lt;br&gt;
In the Object Explorer, right-click on the server name and &lt;br&gt;
select Properties from the context menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go to the Advanced page:&lt;/strong&gt;&lt;br&gt;
In the Server Properties window, select the Advanced tab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Change the max text replication size:&lt;/strong&gt;&lt;br&gt;
In the Miscellaneous section, find the Max Text Replication &lt;br&gt;
Size option and change it to the desired value. You can set &lt;br&gt;
it to -1 for the maximum supported size (2 GB).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apply and restart:&lt;/strong&gt;&lt;br&gt;
Click OK to apply the changes and then restart the SQL Server &lt;br&gt;
service for the changes to take effect.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Adjusting max text repl size Works
&lt;/h2&gt;

&lt;p&gt;By adjusting both the max text repl size and max text repl size configuration options, you're ensuring that SQL Server can handle larger LOB data sizes during replication. This prevents the error from occurring and enables seamless replication processes for your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Don't let the "Length of LOB data to be replicated exceeds configured maximum" error halt your database replication efforts. With simple adjustments to the max text repl size configuration option in SQL Server, both through SQL scripts and SQL Server Management Studio, you can overcome this hurdle and ensure seamless replication processes.&lt;/p&gt;

</description>
      <category>sqlserver</category>
      <category>tutorial</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Troubleshooting “The File Does Not Have an App Associated with It” Error in Visual Studio</title>
      <dc:creator>Shekhar Tarare</dc:creator>
      <pubDate>Wed, 22 May 2024 15:39:10 +0000</pubDate>
      <link>https://forem.com/shekhartarare/troubleshooting-the-file-does-not-have-an-app-associated-with-it-error-in-visual-studio-5eib</link>
      <guid>https://forem.com/shekhartarare/troubleshooting-the-file-does-not-have-an-app-associated-with-it-error-in-visual-studio-5eib</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Visual Studio is a powerful integrated development environment (IDE) used by developers worldwide to build applications, including ASP.NET MVC web projects. However, you may encounter an error message stating, “The file does not have an app associated with it for performing the action. Please install an app or if one is already installed, create an association in the default apps settings page.” This issue prevents the project from launching in a web browser, disrupting your workflow. This blog post will delve into the possible causes of this error and provide comprehensive solutions to resolve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Error:
&lt;/h2&gt;

&lt;p&gt;The error message indicates that Visual Studio is unable to find or use a suitable application (web browser) to open the web project. This problem can stem from several underlying issues, including misconfigured default browser settings, project properties, or issues with the Visual Studio installation itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Repair Visual Studio&lt;/strong&gt;&lt;br&gt;
Sometimes, repairing Visual Studio can resolve underlying configuration issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Visual Studio Installer: From the Start Menu, open the Visual Studio Installer.&lt;/li&gt;
&lt;li&gt;Select More Options: Find your version of Visual Studio and click on More (three dots).&lt;/li&gt;
&lt;li&gt;Choose Repair: Select Repair and follow the prompts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;2. Verify Default Browser Settings in Windows&lt;/strong&gt;&lt;br&gt;
The first step is to ensure that you have a default browser set in Windows. Here’s how you can do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Settings: Press Windows + I to open the Settings window.&lt;/li&gt;
&lt;li&gt;Go to Apps: Navigate to Apps &amp;gt; Default apps.&lt;/li&gt;
&lt;li&gt;Set Default Browser: Under the Web browser section, select your preferred browser from the list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;3. Configure the Default Browser in Visual Studio&lt;/strong&gt;&lt;br&gt;
Next, ensure that Visual Studio is configured to use the correct browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Options: In Visual Studio, go to Tools &amp;gt; Options.&lt;/li&gt;
&lt;li&gt;Navigate to Web Browser: Under Environment, select Web Browser.&lt;/li&gt;
&lt;li&gt;Set Default Browser: Ensure your preferred browser is selected as the default.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;4. Check Project Debug Settings&lt;/strong&gt;&lt;br&gt;
Your project settings may need adjustment to properly start the web browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Project Properties: Right-click on your project in Solution Explorer and select Properties.&lt;/li&gt;
&lt;li&gt;Go to Web Tab: Navigate to the Web tab.&lt;/li&gt;
&lt;li&gt;Verify Start Action: Ensure that Start Action is set to Current Page or Specific Page with a valid URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;5. Reinstall the Browser&lt;/strong&gt;&lt;br&gt;
Reinstalling your browser can fix file association issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Uninstall Browser: Uninstall your current browser through Settings &amp;gt; Apps &amp;gt; Apps &amp;amp; features.&lt;/li&gt;
&lt;li&gt;Reinstall Browser: Download and reinstall the latest version of your preferred browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;6. Check File Associations&lt;/strong&gt;&lt;br&gt;
Ensure that .htm and .html files are associated with your web browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Settings: Press Windows + I to open the Settings window.&lt;/li&gt;
&lt;li&gt;Go to Apps: Navigate to Apps &amp;gt; Default apps.&lt;/li&gt;
&lt;li&gt;Choose Default Apps by File Type: Scroll down and select Choose default apps by file type.&lt;/li&gt;
&lt;li&gt;Set Associations: Ensure that .htm and .html are associated with your preferred browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;7. Clear Visual Studio Cache&lt;/strong&gt;&lt;br&gt;
Clearing the Visual Studio cache can sometimes resolve issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close Visual Studio: Ensure Visual Studio is closed.&lt;/li&gt;
&lt;li&gt;Delete Cache: Delete the contents of %LOCALAPPDATA%\Microsoft\VisualStudio&amp;lt;version&amp;gt;\ComponentModelCache.&lt;/li&gt;
&lt;li&gt;Restart Visual Studio: Open Visual Studio again and try running your project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;8. Launch Project Manually&lt;/strong&gt;&lt;br&gt;
As a temporary workaround, you can manually launch your browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run Without Debugging: Press Ctrl + F5 to run your project in Visual Studio.&lt;/li&gt;
&lt;li&gt;Open Browser: Manually open your preferred browser.&lt;/li&gt;
&lt;li&gt;Navigate to URL: Enter the project URL (usually &lt;a href="http://localhost:" rel="noopener noreferrer"&gt;http://localhost:&lt;/a&gt;) in the browser’s address bar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;9. Check IIS Express Configuration&lt;/strong&gt;&lt;br&gt;
If you’re using IIS Express, verify its configuration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Options in Visual Studio: Go to Tools &amp;gt; Options.&lt;/li&gt;
&lt;li&gt;Navigate to Web Projects: Under Projects and Solutions, select Web Projects.&lt;/li&gt;
&lt;li&gt;Enable 64-bit IIS Express: Ensure Use the 64 bit version of IIS Express for web sites and projects is checked if applicable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Encountering the “The file does not have an app associated with it” error in Visual Studio can be frustrating, but by systematically addressing the potential causes, you can resolve the issue and get back to your development work. Whether it’s adjusting your default browser settings, configuring project properties, or repairing your Visual Studio installation, these solutions cover the most common reasons for this error. If you continue to experience problems, consider reaching out to the Visual Studio community or support for further assistance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In my case, the issue was resolved by repairing Visual Studio.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>visualstudio</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
