European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core 9.0 Hosting - HostForLIFE :: Optimizing System Performance and Safety.Threading.Incorporate C and .NET 9

clock July 22, 2024 08:09 by author Peter

Using a dedicated object instance of the System, developers may now improve performance and security in their multithreaded applications with the release of.NET 9 and C# 13.Threading.type of lock. The advantages of utilizing this new feature, the newly introduced compiler warnings, and the best practices for locking in earlier.NET and C# versions are all covered in this article.

System.Threading.Lock: Why Use It?
Locking a dedicated object instance of the System, starting with C# 13 and.NET 9.Threading.It is advisable to choose a lock type for best results. In multithreaded contexts, this particular lock object is intended to reduce overhead and enhance concurrency.

Warnings from compilers for increased safety
The compiler now raises warnings if a known Lock object is cast to a different type and locked in order to improve code safety. By ensuring that locks are utilized correctly and preventing potential misuse, this lowers the possibility of deadlocks and contention problems.

Best practices for Locking in Older versions

If you're working with an older version of .NET and C#, it's essential to follow best practices to avoid common pitfalls in multithreading. Here are some guidelines.

  • Use a Dedicated Object Instance: Always lock on a dedicated object instance that isn't used for another purpose. This helps prevent unintended side effects and conflicts.
  • Avoid Using Common Instances as Lock Objects
  • Avoid this: Locking on this can lead to issues as callers might also lock the same object, causing deadlocks.
  • Avoid Type Instances: Type instances obtained via the type operator or reflection can be accessed from different parts of the code, leading to unintended locks.
  • Avoid string Instances: Strings, including string literals, might be interned, causing different parts of the application to inadvertently share the same lock object.
  • Minimize Lock Duration: Hold a lock for the shortest time possible to reduce lock contention. This practice ensures that other threads are not blocked for extended periods, improving overall application performance.

Example of using System.Threading.Lock
Here's an example of how to use the new System.Threading.Lock in .NET 9 and C# 13.

public class MyClass
{
    private readonly System.Threading.Lock _lock = new();
    public void CriticalSection()
    {
        lock (_lock)
        {
            // Critical code here
        }
    }
}


Example
The following example defines an Account class that synchronizes access to its private balance field by locking on a dedicated balance lock instance. Using the same instance for locking ensures that two different threads can't update the balance field by calling the Debit or Credit methods simultaneously. The sample uses C# 13 and the new Lock object. If you're using an older version of C# or an older .NET library, lock an instance of an object.
using System;
using System.Threading.Tasks;
public class Account
{
    // Use `object` in versions earlier than C# 13
    private readonly System.Threading.Lock _balanceLock = new();
    private decimal _balance;
    public Account(decimal initialBalance) => _balance = initialBalance;
    public decimal Debit(decimal amount)
    {
        if (amount < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount), "The debit amount cannot be negative.");
        }
        decimal appliedAmount = 0;
        lock (_balanceLock)
        {
            if (_balance >= amount)
            {
                _balance -= amount;
                appliedAmount = amount;
            }
        }
        return appliedAmount;
    }
    public void Credit(decimal amount)
    {
        if (amount < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount), "The credit amount cannot be negative.");
        }

        lock (_balanceLock)
        {
            _balance += amount;
        }
    }
    public decimal GetBalance()
    {
        lock (_balanceLock)
        {
            return _balance;
        }
    }
}
class AccountTest
{
    static async Task Main()
    {
        var account = new Account(1000);
        var tasks = new Task[100];
        for (int i = 0; i < tasks.Length; i++)
        {
            tasks[i] = Task.Run(() => Update(account));
        }
        await Task.WhenAll(tasks);
        Console.WriteLine($"Account's balance is {account.GetBalance()}");
        // Output:
        // Account's balance is 2000
    }
    static void Update(Account account)
    {
        decimal[] amounts = { 0, 2, -3, 6, -2, -1, 8, -5, 11, -6 };
        foreach (var amount in amounts)
        {
            if (amount >= 0)
            {
                account.Credit(amount);
            }
            else
            {
                account.Debit(Math.Abs(amount));
            }
        }
    }
}

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Single Sign-On (SSO) for Applications Built with ASP.NET Core

clock July 16, 2024 07:17 by author Peter

A centralized user authentication system called Single Sign-On (SSO) enables users to log in just once and access numerous apps. By eliminating the need for several passwords and lowering the possibility of password fatigue, SSO improves user comfort and security. This article explores utilizing IdentityServer4 to provide SSO in an ASP.NET Core application.

Comprehending SSO
A central identity provider (IdP) is given authentication duties by SSO. The service sends the user to the IDP for authentication when they try to access it. The IDP provides a token that the service uses to confirm the user's identity after successful authentication.

Why Use SSO?
Improved User Experience: Users log in once to access multiple applications.
Enhanced Security: Centralized authentication reduces password-related risks.
Simplified Management: Administrators manage a single authentication system.
Compliance: Easier to enforce security policies and compliance requirements.

Implementing SSO with ASP.NET Core and IdentityServer4
Step 1. Setting Up IdentityServer4

Create a new ASP.NET Core project
dotnet new mvc -n SSOApp
cd SSOApp


Add IdentityServer4 NuGet package
dotnet add package IdentityServer4
dotnet add package IdentityServer4.AspNetIdentity

Configure IdentityServer4 in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(Config.IdentityResources)
    .AddInMemoryApiResources(Config.ApiResources)
    .AddInMemoryClients(Config.Clients)
    .AddAspNetIdentity<ApplicationUser>();
services.AddAuthentication()
    .AddGoogle("Google", options =>
    {
        options.ClientId = "your-client-id";
        options.ClientSecret = "your-client-secret";
    });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
});
}


Define Identity Resources, API Resources, and Clients in Config. cs
public static class Config
{
public static IEnumerable<IdentityResource> IdentityResources =>
    new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
    };
public static IEnumerable<ApiResource> ApiResources =>
    new List<ApiResource>
    {
        new ApiResource("api1", "My API")
    };
public static IEnumerable<Client> Clients =>
    new List<Client>
    {
        new Client
        {
            ClientId = "client",
            AllowedGrantTypes = GrantTypes.ClientCredentials,
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },
            AllowedScopes = { "api1" }
        }
    };
}


Step 2. Setting Up a Client Application
Create a new ASP.NET Core MVC project
dotnet new mvc -n ClientApp
cd ClientApp

Add necessary NuGet packages
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.AspNetCore.Authentication.Cookies

Configure authentication in Startup. cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = "https://localhost:5001";
    options.ClientId = "client";
    options.ClientSecret = "secret";
    options.ResponseType = "code";
    options.SaveTokens = true;
    options.Scope.Add("api1");
    options.Scope.Add("offline_access");
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
});
}


Step 3. Testing the SSO Implementation
Run the IdentityServer4 and Client applications.
dotnet run --project SSOApp
dotnet run --project ClientApp


Access the Client application: Navigate to the Client application URL (e.g., https://localhost:5002).
Initiate Login: Click the login button to redirect you to the IdentityServer4 login page.
Authenticate: Provide your credentials, and upon successful authentication, you will be redirected back to the Client application with the SSO session established.

Conclusion

Implementing Single Sign-On in ASP.NET Core applications using IdentityServer4 significantly improves user experience and security. By centralizing authentication, you streamline user management and enhance overall security. This article provides a comprehensive guide to setting up SSO in your ASP.NET Core applications, paving the way for a more efficient and secure authentication process.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Acquire Problem Solving Skills Multiple apps at once are not supported by ASP.NET Core

clock July 8, 2024 09:25 by author Peter

This is a brief guide for people who use IIS and.NET Core. Two.NET Core applications operating on the same instance of IIS must each have its own Application Pool in order for the issue to be raised. Multiple apps in the same app pool are not supported by ASP.NET Core, according to HTTP Error 500.35. Take these actions.

1. Make a fresh pool

2. If you are adding a new application, select the created Application Pool, in this example, NewPool.

3. If the application is already deployed, alter the Basic Settings to the new Application Pool.

I hope these tips help you.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Examining the GetItems() Method in.NET 8 to Handle Randomness

clock July 3, 2024 07:08 by author Peter

The Random class's GetItems() method is one of the potent new features introduced in.NET 8. Working with randomness should be simpler, more effective, and intuitive with this approach. This post will go over the uses, functionality, and improvements that the GetItems() method may provide to your.NET projects.

Table of Contents

  1. Introduction to the GetItems() Method
  2. Basic Usage
  3. Practical Applications
  4. Comparing Traditional Methods with GetItems()
  5. Best Practices
  6. Conclusion

Overview of the GetItems() Procedure
The Random class in.NET 8 now has a new method called GetItems(). It lets you choose a predetermined number of objects at random from a collection. This can be very helpful in situations where you need to add some unpredictability to your application or shuffle data or create random samples.

Standard Usage

Using the GetItems() function is simple. This is the fundamental syntax:

public static T[] GetItems<T>(this Random random, IList<T> list, int count);

  • random: An instance of the Random class.
  • list: The collection from which items are to be selected.
  • count: The number of random items to select.

Here’s a simple example to illustrate its usage.
Random random = new Random();
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] randomNumbers = random.GetItems(numbers, 3);
foreach (var number in randomNumbers)
{
    Console.WriteLine(number);
}


In this example, GetItems() selects three random numbers from the numbers list.

Practical Applications

Random Sampling in Surveys
Suppose you're conducting a survey and need to randomly select participants from a list. The GetItems() method makes this easy:
List<string> participants = new List<string> { "Alice", "Bob", "Charlie", "David", "Eve" };
string[] selectedParticipants = random.GetItems(participants, 2);
Console.WriteLine("Selected Participants:");
foreach (var participant in selectedParticipants)
{
    Console.WriteLine(participant);
}


Random Shuffling of Cards
In game development, shuffling a deck of cards is a common requirement. Using GetItems(), you can shuffle cards effortlessly:
List<string> deck = new List<string> { "2H", "3H", "4H", ..., "KS", "AS" };
string[] shuffledDeck = random.GetItems(deck, deck.Count);
Console.WriteLine("Shuffled Deck:");
foreach (var card in shuffledDeck)
{
    Console.WriteLine(card);
}


Comparing Traditional methods with GetItems()
Before GetItems(), achieving similar functionality required more verbose and less readable code. Here’s how you might have done it traditionally:
Random random = new Random();
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<int> selectedNumbers = new List<int>();
HashSet<int> usedIndices = new HashSet<int>();
while (selectedNumbers.Count < 3)
{
    int index = random.Next(numbers.Count);
    if (usedIndices.Add(index))
    {
        selectedNumbers.Add(numbers[index]);
    }
}
foreach (var number in selectedNumbers)
{
    Console.WriteLine(number);
}


Using GetItems(), the same task is simplified.
int[] randomNumbers = random.GetItems(numbers, 3);
foreach (var number in randomNumbers)
{
    Console.WriteLine(number);
}


Best Practices

  • Validate Parameters: Ensure the count parameter does not exceed the size of the list to avoid exceptions.
  • Seed Control: For reproducible results, initialize the Random class with a fixed seed.
  • Performance Considerations: For very large collections, be mindful of performance implications when using GetItems() frequently.

Conclusion
The GetItems() method in .NET 8 is a welcome addition for developers who frequently work with random data selections. By providing a concise and efficient way to select random items from a collection, it simplifies code and enhances readability. Whether you’re developing games, conducting surveys, or implementing any feature requiring randomness, GetItems() is a tool that can significantly streamline your development process.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Comprehending.NET Session Management

clock June 26, 2024 07:05 by author Peter

A crucial component of web programming is keeping state across several queries. Because HTTP is stateless, developers must put in place ways to store user data. Sessions are useful in this situation. This post will explain sessions, explain how they function in.NET, and offer real-world examples to demonstrate how to use them.

A session: what is it?

A session is a type of server-side data storage that allows data to be maintained between requests made by the same user. Web applications depend on sessions to save many state variables, including user preferences, shopping cart contents, and authentication status. A distinct session ID is assigned to each session, forwarded to the client, and returned with each new request.

How Sessions Work in .NET

  • Session Initialization: When a user accesses a web application for the first time, a new session is created, and a unique session ID is generated. This ID is stored in a cookie on the client side.
  • Data Storage: The session object is used to store data on the server side, tied to the session ID.
  • Subsequent Requests: The client sends the session ID back to the server with each request. The server retrieves the session data using this ID.
  • Session Termination: Sessions can be terminated explicitly by the application, or they can expire after a period of inactivity.

Enabling and Using Sessions in ASP.NET Core
To use sessions in an ASP.NET Core application, you need to configure the session middleware. Here’s a step-by-step guide:
Step 1. Configure session state
Middleware for managing session state is included in the framework. To enable the session middleware, Program.cs must contain:

  • Any of the IDistributedCache memory caches. The IDistributedCache implementation is used as a backing store for the session. For more information, see Distributed Caching in ASP.NET Core.
  • A call to AddSession
  • A call to UseSession

The following code shows how to set up the in-memory session provider with a default in-memory implementation of IDistributedCache:
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});
app.UseSession();


The preceding code sets a short timeout to simplify testing.
The order of middleware is important. Call UseSession after UseRouting and before MapRazorPages and MapDefaultControllerRoute. See Middleware Ordering.

HttpContext.Session is available after the session state is configured.

HttpContext.The session can't be accessed before UseSession has been called.

A new session with a new session cookie can't be created after the app has begun writing to the response stream. The exception is recorded in the web server log and not displayed in the browser.

Step 2. Set and Get Session Data
The following example shows how to set and get an integer and a string:
public class IndexModel : PageModel
{
    public const string SessionKeyName = "_Name";
    public const string SessionKeyAge = "_Age";
    private readonly ILogger<IndexModel> _logger;
    public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
    }
    public void OnGet()
    {
        if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
        {
            HttpContext.Session.SetString(SessionKeyName, "The Doctor");
            HttpContext.Session.SetInt32(SessionKeyAge, 73);
        }
        var name = HttpContext.Session.GetString(SessionKeyName);
        var age = HttpContext.Session.GetInt32(SessionKeyAge).ToString();
        _logger.LogInformation("Session Name: {Name}", name);
        _logger.LogInformation("Session Age: {Age}", age);
    }
}


The following example retrieves the session value for the IndexModel.SessionKeyName key (_Name in the sample app) in a Razor Pages page:
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)


Serialize objects data
All session data must be serialized to enable a distributed cache scenario, even when using the in-memory cache. String and integer serializers are provided by the extension methods of ISession. Complex types must be serialized by the user using another mechanism, such as JSON.

Use the following sample code to serialize objects:
public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T? Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}


Benefits of Using Sessions

  • State Management: Sessions help maintain the state across multiple requests, which is essential for features like user authentication and shopping carts.
  • Security: Data stored in sessions is kept on the server, reducing the risk of client-side manipulation.
  • Convenience: Sessions simplify the development of stateful web applications by providing an easy way to store and retrieve user-specific data.

Conclusion
One of.NET's most useful features for handling state in web applications is sessions. They offer a practical and safe means of storing user-specific information for usage in response to various requests. You may improve user experience and keep a smooth user interface during the user's visit to your web application by using sessions correctly. By successfully utilizing and comprehending sessions, you can create powerful, stateful online applications that enhance user experience. Sessions are an essential tool in the toolbox of any web developer, whether they are using distributed cache storage for scalability or in-memory storage for simplicity.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core 9.0 Hosting - HostForLIFE :: How Can I Use My Current Tools to Migrate to.NET 8?

clock June 20, 2024 08:00 by author Peter

The technology framework varies according on the context in which the program will run, as is common with Microsoft technology, which comes with numerous environments like Desktop, Web, Mobile apps, etc. Thus, the application needs to be planned and built based on the environment. But difficulties will now arise.

Step 1: Please verify that the current application target framework is in place before moving to the higher version. After selecting Solution Properties, check as shown below.

Step 2: To access the upgrade button menu, simply perform a right-click on the solution.


Step 3: The window for the upgrade assistant will appear and ask what has to be done next to upgrade the project.


Step 4: You'll be prompted to choose the target framework in this window.

Step 5: At this point, you may choose which components to upgrade to the newest target framework or migrate to an updated version of.

Step 6: As I pick every component, the system will verify and either provide you with the most recent code alteration or advise you to make the necessary adjustments. Improvement is underway. It will require some time to finish and provide the report.

Step 7: The report is now generated and displayed in the window for the upgrading assistant. Please take the example below into consideration. The project output will vary if the project is an enterprise application.

Step 8: The Visual Studio output window allows the developer to view the current status.

After the DotNet or.Net upgrade assistant is finished, we must follow its recommendations and make changes to the code base. Step 7 indicates that the.net8-windows target framework does not support MVVMLight. Thus, we must decide and update such packages. In this case, CommunityToolkit is an alternative to MVVMLight.Since MVVM is available in Nuget, the codebase must also be modified.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: The .NET Core Null Object Design Pattern

clock June 10, 2024 09:13 by author Peter

The Null Object Pattern is a behavioral design pattern that provides an object to stand in for the missing object in an interface. It's a way to offer an alternate action in situations when a null object would raise a null reference exception. In this post, we'll go deeply into the C# Null Object Pattern and gradually advance to more complicated scenarios.

The Pattern of Null Object Design What's that?
The use of the Null object pattern is one design strategy that facilitates the use of potentially undefined dependencies. This is done by using instances of a concrete class that implements a recognized interface in place of null references. Together with concrete classes that extend it and a null object class that provides a do-nothing version of the class that can be used anyplace we need to verify the null value, an abstract class detailing the various actions to be performed is constructed.

The Null Object Design Pattern's constituent parts
Customer

The client is the code that depends on an object that either implements a Dependency interface or extends an abstract DependencyBase class. The client uses this item to complete a task. The client shouldn't need to know which kind of object it is working with in order to handle both real and null objects in the same manner.

DependencyBase or Abstract Dependency
An abstract class or interface called DependencyBase specifies the methods that must be implemented by all concrete dependents, including the null object. The contract that all dependencies have to abide by is defined by this class.

Dependency or Real Dependency

The Client may utilize this class as a functional dependency. It is not necessary for the client to know if Dependency objects are actual or null in order to interact with them.

NullObject or Null Dependency
This is the class of null objects that the client may utilize as a dependency. While it implements every member specified by the DependencyBase abstract class, it lacks functionality. A null or non-existent dependency in the system is represented by a NullObject. Methods on a NullObject can be securely called by the client without resulting in errors or requiring null checks.

As an illustration,
Abstract Dependency

Here is the code for the ICar.cs file.
public interface ICar
{
    void Drive();

    void Stop();
}

Real Dependency
Here is the code for the SedanCar.cs file.
public class SedanCar : ICar
{
    public void Drive()
    {
        Console.WriteLine("Drive the sedan car.");
    }

    public void Stop()
    {
        Console.WriteLine("Stop the sedan car.");
    }
}

Null Object Dependency
Here is the code for the NullCar.cs file.
public class NullCar : ICar
{
    public void Drive()
    {

    }

    public void Stop()
    {

    }
}

Client

Here is the code for the CarService.cs file.
public class CarService(ICar car)
{
    private readonly ICar _car = car;

    public void Run()
    {
        Console.WriteLine($"Start run method. {nameof(ICar)}: {_car}");
        _car.Drive();
        _car.Stop();

        Console.WriteLine($"Complete run method. {nameof(ICar)}: {_car}");
        Console.WriteLine();
    }
}


Program
Here is the code for the Program.cs file.
var sedanCar = new SedanCar();
var carService = new CarService(sedanCar);

carService.Run();

var nullCar = new NullCar();
carService = new CarService(nullCar);

carService.Run();

Output

When to apply the Design Pattern for Null Objects?
When you want to provide a default or no-op implementation of an object's functionality to avoid null checks and handle null references gracefully, you can use the Null Object Design Pattern. The following situations call for the application of the Null Object Design Pattern.

  • Default Behavior: This is the behavior you want to give an object in the event that its real implementation is unavailable or inappropriate.
  • Avoid Null Checks: When you want to provide a null object implementation that may be used safely in place of a null reference, you can avoid having to do explicit null checks in your code.
  • Consistent Interface: In situations when you need to give customers access to an interface that stays the same whether they are working with real or null objects.
  • Simplifying Client Code: When you wish to spare client code from handling null references by letting them handle null objects in the same manner as actual objects.

When the Null Object Design Pattern should not be used?
The Null Object Design Pattern might not be appropriate in the following situations.

  • Sophisticated Behavior: The Null Object Design Pattern is meant to provide simple default behavior; therefore, it might not be acceptable when the null object needs to implement sophisticated behavior or store state.
  • Performance Considerations: It could be preferable to handle null references directly in the code if generating and utilizing null objects significantly increases overhead or complexity in the system.
  • Confusion with Real Objects: Explicit null checks may be preferable in order to improve the readability and clarity of the code if there is a chance that null objects and real objects could be confused in the system.

Summary
A solid method for handling the lack of objects is provided by the Null Object Pattern, a design pattern. It lowers the possibility of runtime mistakes and simplifies client code by offering a default behavior and doing away with the necessity for null checks. To improve stability and maintainability, the Null Object Pattern can be a useful tool when building a new system or restructuring an old one.

We learned the new technique and evolved together.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.


 



European ASP.NET Core 9.0 Hosting - HostForLIFE :: The One Behind Concurrency in C#

clock June 6, 2024 09:31 by author Peter

Applications developed today do not make use of the System Thread class.Threading straight. It means you are still keeping legacy code if you see it in one of your projects. Is learning Thread API worthwhile? Well, that's a different subject altogether. The Thread API was introduced in.NET 1.0, as we well know, but it was not very user-friendly. Why then is it preferable not to utilize it?

  • The underlying API that gives you direct control over everything is called Thread API. Although this choice seems appealing, you can become frustrated if you have more influence over something you don't understand.
  • Gaining mastery over Thread API was not an easy feat. It has a rich history that you must really understand by delving into the OS's intricacies. It does seem a little frightening, but the Thread API makes you think in terms of Threads rather than jobs. Instead of focusing about building threads, developers should consider writing concurrent programming. Thread is an implementation detail and a physical concept.
  • The process of creating a thread is costly.
  • From the standpoint of understandability and maintainability, using Thread API introduces more complexity.

Microsoft introduced the ThreadPool class in.NET 2.0, which is an improvement over the Thread API. Isolating us from the Thread notion was the main advancement toward Threading. It is not necessary for you to consider threads. As a developer, you ought to consider tasks that need to be parallelized.

A wrapper around your threads is called ThreadPool.

Why is it a superior choice?

  • You are no longer "the owner" of Threads thanks to ThreadPool. There is no need for manual development, intricate procedures, thread management issues, deadlock, etc. What do you think? You were the main issue, not a thread:)
  • When and why to create threads are managed by ThreadPool. Put simply, let's say we have five approaches. You should use multithreading to run them. To run them, you require five methods, but ThreadPool might need to use two or three threads to finish your job. If you use a traditional thread API, the limit is determined by the thread count you utilize.
internal class Program
{
    static void Main(string[] args)
    {
        new Thread(ComplexTask).Start();
        Thread.Sleep(1000);
        new Thread(ComplexTask).Start();
        Thread.Sleep(1000);
        new Thread(ComplexTask).Start();
        Thread.Sleep(1000);
        new Thread(ComplexTask).Start();
        Thread.Sleep(1000);
        Console.ReadLine();
    }

    static void ComplexTask()
    {
        Console.WriteLine($"Running complex task in Thread={Environment.CurrentManagedThreadId}");
        //Thread.Sleep(40);
        Console.WriteLine($"Finishing complex task in Thread={Environment.CurrentManagedThreadId}");
    }
}


Here is the result

Every operation is a Thread, and it is not an optimized way of using it.

ThreadPool isolates us from The Thread stuff and provides a simple API to enter multithreading mode. Let’s modify our code and try to understand the value of using ThreadPool instead of Thread directly.
internal class Program
{
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem((x) => ComplexTask());
        Thread.Sleep(1000);
        ThreadPool.QueueUserWorkItem((x) => ComplexTask());
        Thread.Sleep(1000);
        ThreadPool.QueueUserWorkItem((x) => ComplexTask());
        Thread.Sleep(1000);
        ThreadPool.QueueUserWorkItem((x) => ComplexTask());
        Thread.Sleep(1000);

        Console.ReadLine();
    }
    static void ComplexTask()
    {
        Console.WriteLine($"Running complex task in Thread={Environment.CurrentManagedThreadId}");
        //Thread.Sleep(40);
        Console.WriteLine($"Finishing complex task in Thread={Environment.CurrentManagedThreadId}");
    }
}

As you have probably noticed, ThreadPool optimizes the use of Thread. ThreadPool will utilize an existing thread rather than start a new one if any of them are free. Hold on a minute... Can we perform the same procedure together? Can we really execute the same Thread twice? Let's give it a shot.

You can’t run the same Thread twice but somehow ThreadPool can. ThreadPool can reuse Threads and it helps not to create a Thread every time when you have a block of code to run in multithreading mode. In classical .NET, depending on its version and your CPU architecture the capacity of Worker threads is different.

I have an x64 Intel processor running the most recent version of.NET (.NET 8) with 32767 worker threads with 1000 completion post threads. Typically, ThreadPool begins with just one thread in it. It may automatically increase Threads based on the circumstances. ThreadPool allows you to check the available threads.

In my case, I’m using the latest .NET ( .NET 8) with an x64 intel processor, and I have 32767 worker Threads with 1000 completion post Threads.

ThreadPool usually starts with 1 Thread in the pool. Depending on the context, it may automatically increase Threads. You can Check available threads in ThreadPool.
internal class Program
{
    static void Main(string[] args)
    {
        ThreadCalculator();
        for (int i = 0; i < 10; i++)
        {
            ThreadPool.QueueUserWorkItem((x) => ComplexTask());
        }
        Thread.Sleep(15);
        ThreadCalculator();
        Console.ReadLine();
    }
    static void ThreadCalculator()
    {
        ThreadPool.GetAvailableThreads(out int workerThreads, out int completionPortThreads);
        Console.WriteLine($"worker threads = {workerThreads}, " +
            $"and completion Port Threads = {completionPortThreads}");
    }
    static void ComplexTask()
    {
        Console.WriteLine($"Running complex task in Thread={Environment.CurrentManagedThreadId}");
        //Thread.Sleep(40);
        Console.WriteLine($"Finishing complex task in Thread={Environment.CurrentManagedThreadId}");
    }
}

The most used API in ThreadPool is, of course, QueueUserWorkItem. It has a generic version, also.
Well, we have another great concept called completion post Threads that we need to cover.

ThreadPool.QueueUserWorkItem is a method in C# that allows you to schedule tasks for execution in a thread pool. Here's a breakdown of its functionality:

Purpose

Schedule tasks to run asynchronously without creating and managing individual threads.
Leverages a pool of pre-created threads, improving performance and resource management.

How it works
You provide a delegate (like Action or WaitCallback) that represents the work you want to be done.
Optionally, you can pass an object containing data to be used by the delegate.

ThreadPool.QueueUserWorkItem adds the delegate and data (if provided) to the thread pool's queue.

When a thread from the pool becomes available, it picks up the first item from the queue and executes the delegate with the provided data.

Benefits or Why to Use It

Performance Boost: Reusing threads avoids the overhead of creating and destroying them for each task.
Resource Optimization: Maintains a controlled number of threads, preventing system overload.
Simplified Concurrency Management: The thread pool handles scheduling and ensures tasks are executed efficiently.

Additional notes
The thread pool can dynamically adjust the number of threads based on workload.
Tasks are queued if all threads are busy, ensuring none are dropped.

ThreadPool.QueueUserWorkItem has overloads, including a generic version for type safety and an option to influence thread selection.

Ok, but what about completion port Threads?
The concept of completionPortThreads within the ThreadPool class in C# might not be directly exposed as you might expect.
The ThreadPool class internally manages two types of threads.

  • Worker Threads: These handle general-purpose tasks submitted through QueueUserWorkItem.
  • I/O Completion Port Threads (Completion Port Threads): These are specialized threads optimized for processing asynchronous I/O operations.

Purpose of completion port threads
Asynchronous I/O operations typically involve waiting for network requests, file access, or other external events. Completion port threads efficiently wait for these events using a system mechanism called I/O Completion Ports (IOCP).

When an I/O operation completes, the corresponding completion port thread is notified, and it can then dequeue and process the completed task.

What is the value?

  • Improved performance for asynchronous I/O bound tasks.
  • Completion port threads avoid busy waiting, reducing CPU usage while waiting for I/O events.
  • Dedicated threads for I/O operations prevent worker threads from being blocked, improving overall responsiveness.

Important Notes
You don't directly control completionPortThreads. The ThreadPool class manages its number dynamically based on the system workload. Methods like ThreadPool.SetMinThreads and ThreadPool.GetAvailableThreads allow you to indirectly influence the minimum number of worker and completion port threads, but there's no separate control for each type.

Who Uses the ThreadPool in C#?
The ThreadPool is a fundamental mechanism in C# for efficiently managing threads. It provides a pool of worker threads that can be reused by various parts of your application, including:

  • Task Parallel Library (TPL): When you create Task or Task<TResult> objects, the TPL typically schedules them to run on ThreadPool threads by default. This enables parallel execution of tasks without the need to explicitly manage threads.
  • Asynchronous Programming: Asynchronous operations like those using the async and await keywords often rely on the ThreadPool to execute the actual work in the background while the main thread remains responsive.
  • Parallel Programming: Libraries like the Parallel For loop (Parallel.For) and PLINQ (Parallel LINQ) often leverage the ThreadPool to distribute work items across multiple threads.

Benefits of Using the ThreadPool

  • Reduced Thread Creation Overhead: Creating threads can be expensive. The ThreadPool eliminates this overhead by creating a pool of threads upfront and reusing them as needed.
  • Improved Performance: By efficiently managing threads, the ThreadPool can enhance the responsiveness and throughput of your application, especially when dealing with concurrent tasks.
  • Simplified Thread Management: The ThreadPool handles thread creation, destruction, and idle thread management, freeing you from these complexities.

When to consider alternatives

  • Long-Running Operations: If your work items are long-running (e.g., several seconds or more), use dedicated threads or the TaskFactory.StartNew method with a custom thread creation option might be more suitable to avoid saturating the ThreadPool and affecting overall application performance.
  • Specialized Thread Requirements: If your tasks require specific thread priority or affinity, you might need to create dedicated threads with the desired settings.

Conclusion
The ThreadPool is a valuable tool for concurrent programming in C#. It offers a convenient and efficient way to manage threads, especially for short-lived, CPU-bound tasks. By understanding how the ThreadPool works and its appropriate use cases, you can create well-structured and performant C# applications.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Understanding SOLID Principles in .NET Core

clock June 3, 2024 08:19 by author Peter

The five SOLID design principles in object-oriented programming are intended to improve the readability, flexibility, and maintainability of software systems. We'll go into great detail about each SOLID principle in this blog article, using.NET Core examples.

1. The principle of single responsibility (SRP)
According to the Single Responsibility Principle, a class should only have one duty or responsibility, or one cause to change.

As an illustration
Take into consideration the User class, which manages emailing people and storing user data in a database. Due to the class's various responsibilities, this violates the SRP.

Bad Example
public class User
{
    public void Save()
    {
        // Saving user to the database
    }

    public void SendEmail()
    {
        // Sending email to the user
    }
}


Good Example
public class User
{
    public void Save()
    {
        // Saving user to the database
    }
}

public class EmailService
{
    public void SendEmail(User user)
    {
        // Sending email to the user
    }
}


2. Open/Closed Principle (OCP)
The Open/Closed Principle states that software entities should be open for extension but closed for modification. This means that classes should be designed in a way that allows new functionality to be added without changing existing code.

Example
Consider a class Area Calculator that calculates the area of shapes. Initially, it only supports rectangles. To adhere to the OCP, we can refactor the code to allow adding new shapes without modifying the existing AreaCalculator class.

Bad Example
public class Rectangle
{
    public double Width { get; set; }
    public double Height { get; set; }
}

public class AreaCalculator
{
    public double CalculateArea(Rectangle[] shapes)
    {
        double area = 0;

        foreach (var shape in shapes)
        {
            area += shape.Width * shape.Height;
        }

        return area;
    }
}


Good Example

public abstract class Shape
{
    public abstract double Area();
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public override double Area()
    {
        return Width * Height;
    }
}

public class AreaCalculator
{
    public double CalculateArea(Shape[] shapes)
    {
        double area = 0;

        foreach (var shape in shapes)
        {
            area += shape.Area();
        }

        return area;
    }
}


3. Liskov Substitution Principle (LSP)
The Liskov Substitution Principle states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program.

Example
Consider a Rectangle class and a Square class where a Square inherits from Rectangle. Violating the LSP would mean that substituting a Square object for a Rectangle object could lead to unexpected behavior.

Bad Example
public class Rectangle
{
    public virtual double Width { get; set; }
    public virtual double Height { get; set; }
}

public class Square : Rectangle
{
    private double _side;

    public override double Width
    {
        get => _side;
        set
        {
            _side = value;
            Height = value;
        }
    }

    public override double Height
    {
        get => _side;
        set
        {
            _side = value;
            Width = value;
        }
    }
}

Good Example
public abstract class Shape
{
    public abstract double Area();
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public override double Area()
    {
        return Width * Height;
    }
}

public class Square : Shape
{
    public double Side { get; set; }

    public override double Area()
    {
        return Side * Side;
    }
}


4. Interface Segregation Principle (ISP)

The Interface Segregation Principle states that clients should not be forced to depend on interfaces they don’t use. It emphasizes breaking interfaces into smaller, more specific ones.

Example
Consider an IWorker interface that contains both Work() and TakeBreak() methods. This forces all implementing classes to implement both methods, even if they don’t need them.

Bad Example
public interface IWorker
{
    void Work();
    void TakeBreak();
}

public class Programmer : IWorker
{
    public void Work()
    {
        // Programming tasks
    }

    public void TakeBreak()
    {
        // Taking a break
    }
}

Good Example
public interface IWorker
{
    void Work();
}

public interface IBreakable
{
    void TakeBreak();
}

public class Programmer : IWorker, IBreakable
{
    public void Work()
    {
        // Programming tasks
    }

    public void TakeBreak()
    {
        // Taking a break
    }
}


5. Dependency Inversion Principle (DIP)
The Dependency Inversion Principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

Example

Consider a UserManager class that directly depends on a Logger class. This creates a tight coupling between the two classes, making it difficult to change the logging implementation.

Bad Example
public class Logger
{
    public void Log(string message)
    {
        // Logging implementation
    }
}

public class UserManager
{
    private Logger _logger;

    public UserManager()
    {
        _logger = new Logger();
    }
}


Good Example
public interface ILogger
{
    void Log(string message);
}

public class Logger : ILogger
{
    public void Log(string message)
    {
        // Logging implementation
    }
}

public class UserManager
{
    private ILogger _logger;

    public UserManager(ILogger logger)
    {
        _logger = logger;
    }
}


Conclusion
You can produce software architectures that are more flexible, scalable, and maintainable by comprehending and implementing the SOLID principles in your.NET Core applications. Writing clear, modular, and testable code is made easier by following these guidelines, which eventually improves software quality and developer efficiency.

HostForLIFE ASP.NET Core 8.0.4 Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: .NET Core Integrating FullCalendar in .NET Core App with JavaScript

clock May 28, 2024 08:06 by author Peter

In order to improve user experience, interactive and user-friendly interface design is essential in modern web development. The integration of dynamic calendars for planning, scheduling, and event management is one typical requirement. To do this, "Integrating FullCalendar in.NET Core Applications with JavaScript" is the best resource. A feature-rich calendar interface may be accessed through the sophisticated JavaScript library FullCalendar, and scalable web applications can be built with a solid backend architecture provided by.NET Core.

From basic setup to sophisticated customisation, this tutorial will lead you through the process of incorporating FullCalendar into your.NET Core application. You will discover how to organize events, make responsive and interactive calendars, and alter the calendar's look to suit your own requirements using JavaScript. Regardless of the complexity of your event management system or scheduling tool, this article will provide you with the knowledge and abilities to integrate FullCalendar with.NET Core with ease, giving your web application a polished and functional calendar solution.

Step 1. Create the calendar view
Create a View for the Calendar
Create a new Razor view named Calendar.cshtml in the Views/Home directory and include the FullCalendar setup.

Initialize the JS and CSS file as the below attachment.
<div class="col-lg-5 ">
    <div class="w-100 m-t-6 task-calendar">
        <div class="card mb-0">
            <div class="card-header">
                <div>
                    <h5>Task Calendar</h5>
                    <span class="d-inline-block calender-date"></span>
                </div>
                <div>

                    <!-- Status badges will be dynamically appended here -->
                </div>
            </div>


            <div class="card-body p-3">
                <div class="table-scrol">
                    <table class="table table-bordered mb-0 tblTaskDetails">
                        <thead>
                            <tr>
                                <th>Sl#</th>
                                <th>Activity</th>
                                <th>Region</th>
                                <th>Mines</th>
                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>


Step 2. Write the Javascript code
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
    var calendarEl = document.getElementById('calendar');

    var calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'dayGridMonth',
        headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        events: function (fetchInfo, successCallback, failureCallback) {
            $.ajax({
                url:"@Url.Action("FetchCalenderData", "User")",
                method: 'GET',
                dataType: 'json',
                success: function (response) {
                    if (response.status === "Successful") {
                        // Aggregate events by date and status
                        var aggregatedEvents = {};
                        response.data.forEach(function (item) {
                            var date = item.actionDate;
                            var status = item.actionStatus;

                            if (!aggregatedEvents[date]) {
                                aggregatedEvents[date] = {};
                            }
                            if (!aggregatedEvents[date][status]) {
                                aggregatedEvents[date][status] = 0;
                            }
                            aggregatedEvents[date][status]++;
                        });

                        // Transform aggregated data into FullCalendar event format
                        var events = [];
                        for (var date in aggregatedEvents) {
                            for (var status in aggregatedEvents[date]) {
                                events.push({
                                    title: status + ' (' + aggregatedEvents[date][status] + ')',
                                    start: date,
                                    extendedProps: {
                                        status: status,
                                        statusCount: aggregatedEvents[date][status]
                                    }
                                });
                            }
                        }

                        successCallback(events);
                    } else {
                        console.log('Error: Data status is not successful');
                        failureCallback();
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log('Error: ' + textStatus);
                    failureCallback();
                }
            });
        },
        eventClick: function (info) {
            var status = info.event.extendedProps.status;
            var clickedDate = info.event.start;

            /*Date Formating For Send To DB for Filter*/
            const CurrentDateForDB = new Date(clickedDate);
            const year = CurrentDateForDB.getFullYear();
            const month = String(CurrentDateForDB.getMonth() + 1).padStart(2, '0');
            const day = String(CurrentDateForDB.getDate()).padStart(2, '0');
            const ClickedformattedDate = `${year}-${month}-${day}`;
            /*END*/

            var options = { day: 'numeric', month: 'short', year: 'numeric' };
            var formattedDate = clickedDate.toLocaleDateString('en-US', options);
            // Make an AJAX call with the status name
            $.ajax({
              url: "@Url.Action("FetchActivityDtlsByStatus", "User")",
                method: 'GET',
                data: { ActivityStatus: status, ActivityDate: ClickedformattedDate },
                success: function (response) {
                    console.log(response);

                    if (response.status === "Successful") {
                        var tbody = $('.tblTaskDetails tbody');
                        tbody.empty(); // Clear existing rows

                        response.data.forEach(function (item, index) {
                            var row = '<tr>' +
                                '<td>' + (index + 1) + '</td>' +
                                '<td>' + item.activiTyName + '</td>' +
                                '<td>' + item.regionName + '</td>' +
                                '<td>' + item.minesName + '</td>' +
                                '</tr>';
                            tbody.append(row);
                        });


                        if (clickedDate) {
                            $('.calender-date').text(formattedDate);
                        } else {
                            $('.calender-date').text('No Date Clicked');
                        }

                        // Clear existing status badges
                        $('.card-header div:nth-child(2)').empty();

                        // Display all unique statuses
                        var statusColors = {
                            'Approved': 'text-bg-success',
                            'Open': 'text-bg-primary',
                            'InProgress': 'text-bg-warning'
                        };

                        var uniqueStatuses = [...new Set(response.data.map(item => item.activityStatus))];
                        uniqueStatuses.forEach(function (status) {
                            var badgeClass = statusColors[status] || 'text-bg-secondary'; // Default color if status is not mapped
                            var statusBadge = '<h5>Status</h5><span class="badge ' + badgeClass + ' calender-status">' + status + '</span>';
                            $('.card-header div:nth-child(2)').append(statusBadge);
                        });

                    } else {
                        alert('Error: Data status is not successful');
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log('Error: ' + textStatus);
                }
            });


        }
    });

    calendar.render();
});
</script>

Step 3. Write the Controller code
#region------------------------Calendar View-------------------------------------
/// <summary>
/// CalenderView Page
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult CalenderView()
{
    return View();
}

/// <summary>
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IActionResult> FetchCalenderData()
{
    FetchCalendarData fcdaTa = new FetchCalendarData();
    try
    {
        using (var httpClient = new HttpClient(_clientHandler))
        {
            var response = await httpClient.PostAsJsonAsync(_options._apiRootURL + "User/GetCalendarData", fcdaTa);
            if (response.StatusCode.ToString() != "ServiceUnavailable")
            {
                string apiResponse = await response.Content.ReadAsStringAsync();
               var  ResultData = JsonConvert.DeserializeObject<FetchCalendarDataInfo>(apiResponse);
                return Json(ResultData);
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    return Json("");
}


/// <summary>
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IActionResult> FetchActivityDtlsByStatus(FetchActivityDetailsData fcdaTa)
{
    try
    {
        using (var httpClient = new HttpClient(_clientHandler))
        {
            var response = await httpClient.PostAsJsonAsync(_options._apiRootURL + "User/GetActivityDtlsByStatus", fcdaTa);
            if (response.StatusCode.ToString() != "ServiceUnavailable")
            {
                string apiResponse = await response.Content.ReadAsStringAsync();
                var ResultData = JsonConvert.DeserializeObject<FetchActivityDetailsDataInfo>(apiResponse);
                return Json(ResultData);
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    return Json("");
}
#endregion-----------------------------------------------------------------------


Step 4. Page load JSON response
{
    "status": "Successful",
    "data": [
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Open"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Open"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Approved"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Open"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Approved"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Open"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-23",
            "actionStatus": "Approved"
        },
        {
            "actionDate": "2024-05-24",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-27",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-27",
            "actionStatus": "Open"
        },
        {
            "actionDate": "2024-05-27",
            "actionStatus": "InProgress"
        },
        {
            "actionDate": "2024-05-27",
            "actionStatus": "Approved"
        }
    ]
}

JSON
Step 5. Button click JSON response

{
    "status": "Successful",
    "data": [
        {
            "activityStatus": "Open",
            "activiTyName": "Promotion Activities",
            "regionName": "Manchester",
            "minesName": "
Manchester",
            "activityDate": "2024-05-23"
        },
        {
            "activityStatus": "Open",
            "activiTyName": "Promotion Activities",
            "regionName": "Leeds",
            "minesName": "
Leeds",
            "activityDate": "2024-05-23"
        },
        {
            "activityStatus": "Open",
            "activiTyName": "Content Creation",
            "regionName": "",
            "minesName": "",
            "activityDate": "2024-05-23"
        },
        {
            "activityStatus": "Open",
            "activiTyName": "Promotion Activities",
            "regionName": "London",
            "minesName": "
London",
            "activityDate": "2024-05-23"
        }
    ]
}


Conclusion
Using JavaScript to integrate FullCalendar into a.NET Core application provides a strong way to create dynamic and interactive calendar interfaces. You've successfully installed FullCalendar in your.NET Core project, setup the required dependencies, made a view to show the calendar, and put a controller action in place to serve events by following the instructions in this guide.You can now use FullCalendar's features to create powerful scheduling tools, event management systems, or any other application that needs calendar capability, once it has been integrated into your program. Additionally, you are able to alter the calendar's look, functionality, and event handling to meet your own needs.

As you continue to develop your .NET Core application, you can further enhance the integration with FullCalendar by exploring additional plugins, implementing features such as drag-and-drop event creation, integrating with external data sources, or incorporating advanced scheduling functionalities.

Overall, integrating FullCalendar with .NET Core empowers you to create seamless and intuitive user experiences, enhancing the functionality and usability of your web applications.

HostForLIFE ASP.NET Core 8.0.4 Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in