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 8.0.1 Hosting - HostForLIFE :: C# &.NET: Experimental Attribute

clock April 16, 2024 08:45 by author Peter

You can add the Experimental property to your types, methods, or assemblies to designate that a feature is experimental using the new Experimental attribute in C# 12. When someone tries to use the method or the type after you've done this, the compiler will throw an error. I describe how to use this functionality in this article.


I used Visual Studio 2022 Preview to construct a console application with.NET 8 and run it for demonstration purposes. Use of the Preview version is required until the article's date. This feature will not function otherwise.

The System.Diagnostics.CodeAnalysis namespace is where the Experimental attribute originates. You can see an example of a class with this attribute in the code below:

using System.Diagnostics.CodeAnalysis;

namespace DotNet8Examples
{
    [Experimental(diagnosticId: "Test001")]
    public class ExperimentalAttributeDemo
    {
        public void Print()
        {
            Console.WriteLine("Hello Experimental Attribute");
        }
    }
}


On line 1, there is the namespace for the Experimental attribute.
On line 5, there is the Experimental attribute, with the diagnosticId. For the diagnosticId, you can specify an Id, which will be used by the compiler, to report a usage of the API the attribute applies to.
On line 8, there is a method for this class.

Now, if you try to create an instance of this class, the compiler will complain about it:
var experimentalAttributeDemo = new ExperimentalAttributeDemo();

It should be noted that the Experimental property can be used in both the method and the class. You can use the NoWarn property in the.csproj file to use this class and ignore this error; this will work on a global level, so each time you try to use the class or method, you won't have to suppress the error; alternatively, you can suppress it directly on the code, which will require you to do so each time you need to use the class or method.

I'm directly suppressing the error Test001 in the code in the example below. In order to do it, you must add your code in between the #pragma warning disable Test001 and the #pragma warning restore Test001:



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: Using Identity for NET API Login and Registration

clock April 2, 2024 08:18 by author Peter

Creating reliable and secure online apps requires careful consideration of authentication and authorization. Microsoft Identity offers a strong foundation for implementing authorization and authentication features with ease in the.NET ecosystem. In this post, we'll look at how to use Microsoft Identity in conjunction with controllers to efficiently handle user registration and login functions in a.NET API.

Required conditions

Make sure you have installed the following prerequisites before continuing:

  • The.NET SDK (at least version 5)
  • Visual Studio Code (optional) or Visual Studio


Establishing the Project
Let's start by making a new.NET Web API project:

dotnet new webapi -n YourProjectName
cd YourProjectName


Adding Identity to the Project
To add Identity to your project, run the following commands:
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer

This adds the necessary packages to your project for using Identity and Entity Framework Core with SQL Server.

Scaffold Identity

Next, scaffold Identity into your project:
dotnet aspnet-codegenerator identity -dc YourDbContext

Replace YourDbContext with the name of your application's DbContext.
Implementing Registration and Login Controllers:

Now, let's implement controllers for user registration and login.

1. Registration Controller

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using YourProjectName.Models;

namespace YourProjectName.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RegisterController : ControllerBase
    {
        private readonly UserManager<ApplicationUser> _userManager;

        public RegisterController(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        [HttpPost]
        public async Task<IActionResult> Register(RegisterModel model)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await _userManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                return Ok("Registration successful");
            }
            return BadRequest(result.Errors);
        }
    }
}

2. Login Controller
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using YourProjectName.Models;

namespace YourProjectName.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        private readonly SignInManager<ApplicationUser> _signInManager;

        public LoginController(SignInManager<ApplicationUser> signInManager)
        {
            _signInManager = signInManager;
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginModel model)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
            if (result.Succeeded)
            {
                return Ok("Login successful");
            }
            return Unauthorized("Invalid email or password");
        }
    }
}

Models
Ensure you have the necessary models for registration and login:
namespace YourProjectName.Models
{
    public class RegisterModel
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }

    public class LoginModel
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }
}


Configuring Startup
Finally, add Identity services to the ConfigureServices method in Startup.cs:
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<YourDbContext>()
    .AddDefaultTokenProviders();

Happy coding!



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: Razor Syntax in ASP.NET

clock March 25, 2024 10:23 by author Peter

ASP.NET is a reliable platform for web development, allowing developers to easily create dynamic and resilient web applications. At the heart of ASP.NET is Razor, a powerful templating engine that transforms the way developers create server-side code. Razor syntax provides a concise and easy way to combine server-side code and HTML, increasing productivity and maintainability. Let's go deeper into Razor syntax and see how it can improve your ASP.NET programming experience.

Understanding Razor syntax
Razor syntax seamlessly integrates server-side code into HTML markup, resulting in cleaner and more understandable code than typical ASP.NET Web Forms. Its lightweight and fluid design allows developers to seamlessly switch between HTML and server-side code, resulting in a more efficient development process.

Razor syntax uses a set of special characters (@) to represent server-side code blocks in HTML markup. These code blocks can include C# or VB.NET code, allowing developers to execute logic, get data from databases, modify objects, and conduct a variety of other operations right within the markup.

Benefits of Razor Syntax

  • Readable and Maintainable Code: Razor syntax promotes code readability by minimizing the clutter typically associated with embedding server-side logic within HTML. The clean and concise syntax enhances code maintainability, making it easier for developers to understand and modify code segments as needed.
  • Seamless Integration: Unlike traditional ASP.NET Web Forms, which often necessitate a clear demarcation between server-side and client-side code, Razor syntax seamlessly integrates server-side logic with HTML markup. This cohesive approach simplifies development and fosters a more fluid coding experience.
  • Enhanced Productivity: By streamlining the process of writing server-side code within HTML, Razor syntax boosts developer productivity significantly. Its intuitive nature reduces cognitive overhead, allowing developers to focus on implementing business logic rather than wrestling with cumbersome syntax.
  • Code Reusability: Razor syntax facilitates code reusability by enabling developers to encapsulate common functionality within reusable components known as partial views. These partial views can be invoked from multiple pages, promoting a modular and DRY (Don't Repeat Yourself) coding approach.
  • IntelliSense Support: Integrated development environments (IDEs) such as Visual Studio provide robust IntelliSense support for Razor syntax, offering real-time suggestions and auto-completion for server-side code blocks. This feature enhances code efficiency and reduces the likelihood of syntax errors.

Example of Razor Syntax

<!DOCTYPE html>
<html>
<head>
    <title>ASP.NET Razor Syntax</title>
</head>
<body>
    <div>
        <h1>Welcome, @Model.Name!</h1>
        <p>Your account balance is: [email protected]</p>
        @if (Model.IsPremium)
        {
            <p>Congratulations! You are a premium member.</p>
        }
        else
        {
            <p>Upgrade to premium for exclusive benefits.</p>
        }
    </div>
</body>
</html>

In this example, Razor syntax is used to embed server-side code within an HTML document. The @Model directive accesses properties of the model passed to the view, allowing dynamic content to be rendered based on the provided data.



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: How to Understanding Deadlocks in C# and .NET Core?

clock March 19, 2024 08:58 by author Peter

Deadlocks are a prevalent problem in concurrent programs, and they can be especially troublesome for programs written in C# and running on.NET Core. A deadlock arises when two or more threads are waiting for each other to release resources that are required to proceed. This can lead to all threads becoming stuck and unable to progress, causing the program to freeze. Many distinct conditions can result in deadlocks, and developers must be aware of them in order to avoid or reduce the danger of deadlocks.

For example, one common circumstance is that two threads each have a resource that the other thread requires. Another instance is when one thread is waiting for a lock to be released while another thread holds that lock and waits for the first thread to release a different lock. These circumstances can be difficult to identify and resolve, but with careful analysis and development techniques, deadlocks can be avoided or reduced.

What is a deadlock?

A deadlock occurs when two or more threads are stalled indefinitely, each waiting for the other to relinquish a resource that it requires to move forward. Deadlocks are characterized by a circular waiting pattern in which no thread can continue, resulting in a stalemate.

using System;
using System.Threading;

class Program
{
static object ResourceA = new object();
static object ResourceB = new object();

static void Thread1()
{
    lock (ResourceA)
    {
        Console.WriteLine("Thread1 acquired ResourceA");
        Thread.Sleep(100); // Simulating some work

        lock (ResourceB)
        {
            Console.WriteLine("Thread1 acquired ResourceB");
        }
    }
}

static void Thread2()
{
    lock (ResourceB)
    {
        Console.WriteLine("Thread2 acquired ResourceB");
        Thread.Sleep(100); // Simulating some work

        lock (ResourceA)
        {
            Console.WriteLine("Thread2 acquired ResourceA");
        }
    }
}

static void Main(string[] args)
{
    Thread t1 = new Thread(Thread1);
    Thread t2 = new Thread(Thread2);

    t1.Start();
    t2.Start();

    t1.Join();
    t2.Join();

    Console.WriteLine("Program completed successfully.");
}
}


Understanding The Deadlock
In this case, Thread1 locks ResourceA first and then attempts to lock ResourceB, whereas Thread2 locks ResourceB first and then attempts to lock ResourceA. If Thread1 obtains ResourceA while Thread2 obtains ResourceB, they will both be waiting for the other resource, resulting in a stalemate.

Preventing Deadlocks

To prevent deadlocks, you can employ various strategies:

  • Lock Ordering: Always acquire locks in a consistent order to prevent circular dependencies.
  • Lock Timeout: Use Monitor.TryEnter or Mutex.WaitOne with a timeout to avoid indefinite blocking.
  • Lock Hierarchy: Establish a lock hierarchy and always acquire locks in the same order within that hierarchy.
  • Avoid Nested Locks: Minimize the use of nested locks to reduce the risk of deadlocks.

Conclusion
Deadlocks can be challenging to debug and resolve, but understanding their causes and employing preventive measures can help mitigate their occurrence. In C# and .NET Core, careful design and coding practices, along with thorough testing, are essential for creating robust and reliable concurrent applications. By following best practices and being mindful of potential deadlock scenarios, developers can ensure the smooth execution of their multithreaded code.



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: Central Package Management (CPM) in.NET Core

clock March 15, 2024 09:18 by author Peter

Dependency management is a key feature of NuGet. It may be simple to manage dependencies for a single project. As multi-project solutions expand in size and complexity, maintaining dependencies can become difficult.


NuGet's central package management (CPM) features allow you to manage shared dependencies for multiple projects from a single, convenient location.

NuGet package dependencies
NuGet package dependencies have been managed in the following methods.

  • packages.config: An XML file used by earlier project types to keep track of the packages that were referenced.
  • <PackageReference />: NuGet package dependencies are described by an XML element used in MSBuild projects.

Enabling Central Package Management
You must create a Directory.Packages.props file at the root of your repository and set the MSBuild value ManagePackageVersionsCentrally to true in order to begin using central package management.

Then, using <PackageVersion /> elements that identify the package ID and version, you declare each of the corresponding package versions needed for your projects inside.
<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="{{package name}}" Version="{{version number}}" />
  </ItemGroup>
</Project>

For each of the projects, we need to define package references, and each of the projects belongs to the same version.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="{{package name}}" />
  </ItemGroup>
</Project>


You're controlling your versions centrally and utilizing central package management now!

Let’s check with the demo.
Create one application for whatever you want for the project. Here I have created the console application for demo purposes. In the above image, CPMDemo is the console application, and CPMDemo.Utility is the class library project.

We can create Directory.Packages.props is the root-level file in our console application.

Here is the content of the directory package file.
<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageVersion Include="Microsoft.EntityFrameworkCore" Version="6.0.27" />
  </ItemGroup>
</Project>


Here is the content of the CPMDemo.csproj changes.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" />
  </ItemGroup>
</Project>


Here is the content of the CPMDemo.Utility.csproj changes.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" />
  </ItemGroup>
</Project>


Once you have completed the above changes on your application side, you just need to build the solution, and then after expanding the dependencies and expanding the packages as well, you will see the packages have been added to your application with the mentioned package versions.

Below is a screenshot taken before building the solution, so at that time we hadn’t added any packages to our application.

Below is a screenshot after building the solution and being able to see the added packages in our application.

Central Package Management rules
There are several restrictions governing the location of the Directory.Packages.props file within a repository's directory as well as its context. For the sake of simplicity, each project is evaluated using a single Directory.Packages.props file.

This indicates that the file nearest to the directory of your project will be considered for it if you have several Directory.Packages.props files in your repository. This gives you additional authority over your repository at different levels.

Repository structure
As an illustration, look at the repository structure below:


Here is the explanation for better understanding.

  • ProjectName1 will assess the Directory.Packages.props file in the Repository Name\Solution1\ directory.
  • ProjectName2 will assess the Directory.Packages.props file in the Repository Name\ directory.

In this manner, we can concentrate the packages that we need on the application side. It will also be simple to maintain—we just need to change one location, and it will reflect everywhere.

Happy learning!!



European ASP.NET Core 8.0.1 Hosting - HostForLIFE :: Use ASP.NET to generate a QR code with text around it

clock March 8, 2024 08:07 by author Peter

To generate a QR code with text surrounding it in ASP.Net, use the nuget package listed below. We can use zxing.net or the QRCoder free nuget package. In this case, we'll use the QRCoder package.

Install the QRCoder package on our project. We are good to go now.

Generate QR Code Sample

In Below code snippet we are using QRCodeGenerator Class to generate QRCode, create an instance for QRCodeGenerator(),
QRCodeData qrCodeData = qrGenerator.CreateQrCode(text, QRCodeGenerator.ECCLevel.Q)

It will Create QRCode Data for the given text.

ECCLevel

Error Correction Level of the QR code. It represents the ability of the QR code to remain readable even if it's partially damaged or obscured.
  L (Low): About 7% of the codewords can be restored.
  M (Medium): About 15% of the codewords can be restored.
  Q (Quartile): About 25% of the codewords can be restored.
  H (High): About 30% of the codewords can be restored.

It will create QRCode for QR Code data,
QRCode qrCode = new QRCode(qrCodeData);

Converting QR Code into bitmap
GetGraphic(int x);


x: Pixel rate for that QR Code
And we have plenty of override methods for GetGraphic() for different use case scenarios.
Bitmap bitMap = qrCode.GetGraphic(20)

Converting bitmap to base64 string
In bitMap.Save() helps us to save the bitmap in image format.

System.Drawing.Imaging.ImageFormat: we can choose which format we would like to save our image, like (PNG, GIF, JPEG, Icons....etc).

And we are converting our memorystream to byte array then we can convert it into string with base64.
System.IO.MemoryStream ms = new System.IO.MemoryStream();
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
string base64String = Convert.ToBase64String(byteImage);


Generate Url for QR Code Image
We can define data while returning from API calls, or we can handle that on the UI side.
ImageUrl = "data:image/png;base64," + base64String;

If we just return base64String.
<img  [src]="'data:image/png;base64,'+ base64String" />

Sample for Generate QR Code with text around it.
In Below Sample GetGraphic(7, Color.Black, Color.White, null, 7, 3).

Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Bitmap icon = null, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true).
  7: pixelsPerModule
  Black: darkColor
  White: lightColor
  null: icon
  7: iconSizePercent
  3: iconBorderWidth

public string GenerateRecurringQRCode(string key){
string result = string.Empty;
QRCodeGenerator qrGenerator = new QRCodeGenerator()
QRCodeData qrCodeData = qrGenerator.CreateQrCode(key, QRCodeGenerator.ECCLevel.Q)
using (QRCode qrCode = new QRCode(qrCodeData))
{
    using (Bitmap bitMap = qrCode.GetGraphic(7, Color.Black, Color.White, null, 7, 3))
    {
        using (MemoryStream ms = new MemoryStream())
        {
            Bitmap qrCodeWithText = AddTextToQRCode(bitMap); // Adding Text to QR Code
            qrCodeWithText.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            byte[] byteImage = ms.ToArray();
            result = Convert.ToBase64String(byteImage);
        }
    }
}
return result;
}

In this code snippet below we have drawn a DO NOT SCREENSHOT QR CODE around qr code AddTextToQRCode();
static Bitmap AddTextToQRCode(Bitmap bitMap)
 {
     RectangleF rectf1 = new RectangleF(26, 8, 350, 100);
     RectangleF rectf2 = new RectangleF(26, 263, 350, 100);


     Graphics g = Graphics.FromImage(bitMap);

     g.SmoothingMode = SmoothingMode.AntiAlias;
     g.InterpolationMode = InterpolationMode.HighQualityBicubic;
     g.PixelOffsetMode = PixelOffsetMode.HighQuality;

     g.DrawString("DO NOT SCREENSHOT QR CODE", new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, rectf1);
     g.DrawString("DO NOT SCREENSHOT QR CODE", new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, rectf2);


     Rectangle recleft = new Rectangle();
     recleft.Height = 200;
     recleft.Width = 500;
     recleft.X = 0;
     recleft.Y = 0;
     SizeF s;
     String str = "DO NOT SCREENSHOT QR CODE";
     StringFormat strf = new StringFormat();
     strf.Alignment = StringAlignment.Center;
     recleft.X = 0;
     recleft.Y = 0;
     g.TranslateTransform(8, 393);
     g.RotateTransform(-90);
     g.DrawString(str, new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, recleft, strf);
     g.ResetTransform();

     Rectangle recright = new Rectangle();
     recright.Height = 200;
     recright.Width = 500;
     recright.X = 0;
     recright.Y = 0;
     SizeF sright;
     String strright = "DO NOT SCREENSHOT QR CODE";
     StringFormat strfright = new StringFormat();
     strf.Alignment = StringAlignment.Center;
     recright.X = 0;
     recright.Y = 0;
     g.TranslateTransform(280, -104);
     g.RotateTransform(90);
     g.DrawString(str, new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, recright, strf);
     g.ResetTransform();


     g.Flush();
     return bitMap;
 }

let Break down the above code snippet.

In this, we have created to rectangle to place our text top and bottom
RectangleF rectf1 = new RectangleF(x, y, width, height);
RectangleF rectf1 = new RectangleF(26, 8, 350, 100);

  The X-coordinate of the top-left corner of the rectangle is 26.
  The Y-coordinate of the top-left corner of the rectangle is 8.
  The width of the rectangle is 350.
  The height of the rectangle is 100.

RectangleF rectf1 = new RectangleF(26, 8, 350, 100);
RectangleF rectf2 = new RectangleF(26, 263, 350, 100);


Converting bitmap to graphics and setting quality

  • SmoothingMode: This mode helps to smooth the edges of rendered shapes, resulting in a higher quality appearance, especially when drawing lines or curves.
  • InterpolationMode: The object will interpolate (or estimate) colors and shapes when scaling or rotating images. HighQualityBicubic typically produces smoother results compared to other interpolation modes.
  • PixelOffSetMode: This mode determines how pixels are offset during rendering operations, which can affect the positioning and clarity of rendered objects.

Graphics g = Graphics.FromImage(bitMap);

g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;

Draw String in red color and a bold Arial Black font at the positions defined by rectf1 and rectf2 on the QR code image.
void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle)
  s: "DO NOT SCREENSHOT QR CODE"
  Font: new Font("Arial Black", 10, FontStyle.Bold) We are using Arial Black font and font size 10, fontstyle bold
  Brush: Color of the text we are about to paint (RED)
  layoutRectangle: position and size to a rectangle.

g.DrawString("DO NOT SCREENSHOT QR CODE", new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, rectf1);
g.DrawString("DO NOT SCREENSHOT QR CODE", new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, rectf2);


In this, we have created a rectangle to place our text left and right.

In the code snippet below, we have placed text on the left.
  Rectangle recleft = new Rectangle();: This line creates a new Rectangle object named recleft.
  recleft.Height = 200;: Sets the height of the rectangle to 200.
  recleft.Width = 500;: Sets the width of the rectangle to 500.
  String str = "DO NOT SCREENSHOT QR CODE";: Initializes a string variable str with the text "DO NOT SCREENSHOT QR CODE".
  StringFormat strf = new StringFormat();: Creates a new StringFormat object named strf.
  strf.Alignment = StringAlignment.Center;: Sets the alignment of the text to center.
  recleft.X = 0;: Resets the X-coordinate of the rectangle to 0 (this seems redundant as it was set earlier).
  recleft.Y = 0;: Resets the Y-coordinate of the rectangle to 0 (again, redundant).
  g.TranslateTransform(8, 393);: Translates the origin of the graphics object by (8, 393) pixels or moves the origin of the drawing surface to a specified point.
  g.RotateTransform(-90);: Rotates the graphics object counterclockwise by 90 degrees.
  g.DrawString(str, new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, recleft, strf);: Draws the string str using a specified font, brush, and rectangle. The text is drawn with the previously set rotation and translation.
  g.ResetTransform();: Resets the transformation matrix of the graphics object to its identity matrix, undoing the translation and rotation applied earlier.

Rectangle recleft = new Rectangle();
recleft.Height = 200;
recleft.Width = 500;
recleft.X = 0;
recleft.Y = 0;
String str = "DO NOT SCREENSHOT QR CODE";
StringFormat strf = new StringFormat();
strf.Alignment = StringAlignment.Center;
g.TranslateTransform(8, 393);
g.RotateTransform(-90);
g.DrawString(str, new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, recleft, strf);
g.ResetTransform();

let do the same for right side.
Rectangle recright = new Rectangle();
recright.Height = 200;
recright.Width = 500;
recright.X = 0;
recright.Y = 0;
String strright = "DO NOT SCREENSHOT QR CODE";
StringFormat strfright = new StringFormat();
strf.Alignment = StringAlignment.Center;
g.TranslateTransform(280, -104);
g.RotateTransform(90);
g.DrawString(str, new Font("Arial Black", 10, FontStyle.Bold), Brushes.Red, recright, strf);
g.ResetTransform();


Flushes any pending graphics operations to ensure that all drawing operations are completed and return bit map to GenerateQRCode() method.
g.Flush();
return bitMap;

Note. If you like to change text you need to alter rectangle and size.
Hope this will be helpful.



ASP.NET Core 8 Hosting - HostForLIFE.eu :: OKTA Authentication for.NET Core API

clock March 6, 2024 08:11 by author Peter

What is Authentication in the.NET Core API?
Authentication is one of the most fundamental aspects of software development. It secures our APIs and refuses API requests if an unauthorized user attempts to access secure endpoints.

Why do we need Authentication in .Net Core API?

  • Data Protection: APIs frequently expose access to data or services that could be abused if they fall into the wrong hands. Authentication ensures that only authorized people or systems can access this information or service.
  • Access Control: Not all users should have equal access rights. Some users may have complete access, while others may have limited permissions. Authentication is the initial step in building such an access control mechanism.
  • Non-repudiation: Using proper authentication, actions may be traced back to the user who conducted them. This ensures accountability for activities taken, which is necessary in many applications.
  • Compliance: Many sectors have standards and obligations in place to protect data and privacy. Authentication, together with other security procedures, helps to meet these regulatory compliance requirements.
  • User Experience: By authenticating users, APIs can also provide personalized experiences, as they know who is making the request and can tailor responses accordingly.

Let's Begin
Let's create a new project

Following the API construction, we will install the nuget package "Microsoft.AspNetCore.Authentication.JwtBearer".

For Authentication, we will be using Okta; Okta provides a way to manage and provide access to users and gives its developer platform to try out authentication stuff.

Sign up on the below link

https://developer.okta.com/signup/

Use authO options, and pick up the region of your choice.
After that, we will create a new API, and In the identifier, we usually give out the hosted app URL, but here for testing purposes. We will give our localhost url of our API.

Now click on the APIs on the left side and click on the Test section; you will get the curl command to generate the Okta auth token.

Now let's open our Program.cs, and we will add the following code.
builder.Services.AddAuthentication(options =>

  {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

  }).AddJwtBearer(options =>

  {
    options.Authority = "https://dev-7fjgp6661wzrvpqw.us.auth0.com/";
    options.Audience = "https://localhost:7294";

  });


From the values in Okta portal, we can use it in the Postman to get the token response.


Now we will add a new controller in our API called "AllowAllController".
[Route("api/[controller]")]
[ApiController]

public class AllowAllController: ControllerBase {
  [HttpGet]
  public string Get() {
    return "Working okay";
  }
}

Once we run the API and hit this endpoint, we will get the response.


Now to test authorization, we will add a [Authorize] keyboard at the top of the controller.

So now our modified controller looks like this.
[Route("api/[controller]")]
[ApiController]
[Authorize]

public class AllowAllController: ControllerBase
{
  [HttpGet]
  public string Get()
  {
    return "Working okay";
  }
}


Now when we hit our API, it will get the Unauthorized response.

Now we will pass the token we get from the token endpoint in the Authorization Header of the request.




ASP.NET Core 8 Hosting - HostForLIFE.eu :: Third-party API Integration in the ASP.NET Core Web API

clock February 28, 2024 07:16 by author Peter

ASP.NET Core is a sophisticated framework for developing online APIs that enables developers to build strong and scalable applications. One of the most important aspects of current web development is the use of third-party APIs, which give access to external services and data.

Create a Model

using System.Text.Json.Serialization;

namespace _1_3rdAPIIntegrationInAspNetCoreWebAPI.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public double DiscountPercentage { get; set; }
        public double Rating { get; set; }
        public int Stock { get; set; }
        public string Brand { get; set; }
        public string Category { get; set; }
        public string Thumbnail { get; set; }
        public List<string> Images { get; set; }
    }
}

Here's a breakdown of each property.

  • ID: An integer representing the unique identifier of the product.
  • Title: A string representing the title or name of the product.
  • Description: A string representing the description or details of the product.
  • Price: A decimal representing the price of the product.
  • DiscountPercentage: A double representing the discount percentage applied to the product.
  • Rating: A double representing the rating of the product (e.g., star rating).
  • Stock: An integer representing the available quantity of the product in stock.
  • Brand: A string representing the brand or manufacturer of the product.
  • Category: A string representing the category or type of the product.
  • Thumbnail: A string representing the URL or path to the thumbnail image of the product.
  • Images: A list of strings representing the URLs or paths to additional images of the product.


Create the Interface for the Product Service
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Models;

namespace _1_3rdAPIIntegrationInAspNetCoreWebAPI.Interfaces
{
public interface IProducts
{
    Task<List<ProductsResponse>> GetProductsAsync();
}
}


GetProductsAsync: This function returns a Task<List<ProductsResponse>>. It indicates that implementing classes will enable the asynchronous retrieval of a list of products. The List<ProductsResponse> contains product responses, including IDs, titles, descriptions, and pricing. The method is asynchronous, as shown by the Task return type, which means that it can be anticipated for asynchronous execution.

Create the service for the products
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Interfaces;
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Models;
using System.Net;
using System.Text.Json;

namespace _1_3rdAPIIntegrationInAspNetCoreWebAPI.Services
{
public class ProductService : IProducts
{
    private static readonly HttpClient httpClient;

    static ProductService()
    {
        httpClient = new HttpClient()
        {
            BaseAddress = new Uri("https://dummyjson.com/")
        };

    }

    public async Task<List<ProductsResponse>> GetProductsAsync()
    {
        try
        {
            var url = string.Format("products");
            var result = new List<ProductsResponse>();
            var response = await httpClient.GetAsync(url);

            if (response.IsSuccessStatusCode)
            {
                var stringResponse = await response.Content.ReadAsStringAsync();
                var productsResponse = JsonSerializer.Deserialize<ProductsResponse>(stringResponse, new JsonSerializerOptions()
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                });

                // Add the deserialized ProductsResponse to the result list
                result.Add(productsResponse);
            }
            else
            {
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new Exception("Products not found.");
                }
                else
                {
                    throw new Exception("Failed to fetch data from the server. Status code: " + response.StatusCode);
                }
            }

            return result;

        }
        catch (HttpRequestException ex)
        {
            throw new Exception("HTTP request failed: " + ex.Message);
        }
        catch (JsonException ex)
        {
            throw new Exception("JSON deserialization failed: " + ex.Message);
        }
        catch (Exception ex)
        {
            throw new Exception("An unexpected error occurred: " + ex.Message);
        }
    }
}
}

Create the Controller for the Products
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Interfaces;
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace _1_3rdAPIIntegrationInAspNetCoreWebAPI.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ProductsController : ControllerBase
{
    private readonly IProducts _productService;

    public ProductsController(IProducts productService)
    {
        _productService = productService;
    }

    [HttpGet]
    public async Task<IEnumerable<ProductsResponse>> GetProducts()
    {
        return await _productService.GetProductsAsync();
    }
}
}


Register the Services in IOC Container

using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Interfaces;
using _1_3rdAPIIntegrationInAspNetCoreWebAPI.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddSingleton<IProducts, ProductService>();

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Output



ASP.NET Core 8 Hosting - HostForLIFE.eu :: Hands-On Prompt Engineering with .NET Core

clock February 20, 2024 08:29 by author Peter

Prompt engineering

For conversational AI systems to be effective, prompt engineering is essential. We'll examine how to apply rapid engineering with.NET Core, a flexible framework for creating cross-platform apps, in this practical course. In order to demonstrate several prompt engineering strategies, such as contextual prompts, error management, and response variation, we'll develop a basic chatbot application.

Setting up your development environment
Before we begin, ensure you have the .NET Core SDK installed on your system. You can download it from the official .NET website

Once installed, open your terminal or command prompt and run the following command to verify the installation.
dotnet --version

If the installation was successful, you should see the version of .NET Core.

Creating a new .NET core console application

Let's start by creating a new .NET Core console application. Open your terminal or command prompt and navigate to the directory where you want to create the project. Then, run the following command.
dotnet new console -n ChatbotApp

This command creates a new console application named "ChatbotApp."
Building the Chatbot

Now that we have our project set up, let's build the chatbot functionality. Open the Program.cs file in your preferred code editor and replace the existing code with the following.
using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Welcome to the Chatbot!");
        Console.WriteLine("What's your name?");
        string userName = Console.ReadLine();
        Console.WriteLine($"Hello, {userName}! How can I assist you today?"); // Your prompt engineering logic goes here
    }
}


This code prompts the user for their name and greets them accordingly. Let's add some prompt engineering logic to provide a more interactive experience.

Implementing prompt engineering

  • Contextual Prompts: Based on the user's input, we can tailor the prompts to provide relevant responses. For example, if the user asks for help, we can provide assistance prompts.
  • Error Handling: Handle user input errors gracefully. If the user provides invalid input, prompt them to try again.
  • Response Variation: Introduce a variety of responses to make the conversation feel more natural and engaging.


Here's an example of how you can enhance the chatbot with these prompt engineering techniques.
using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Welcome to the Chatbot!");
        Console.WriteLine("What's your name?");
        string userName = Console.ReadLine();
        Console.WriteLine($"Hello, {userName}! How can I assist you today?");

        // Continuously prompt the user for input
        while (true)
        {
            string userInput = Console.ReadLine().ToLower();

            // Handle specific user inputs
            if (userInput.Contains("help"))
            {
                Console.WriteLine("Sure, I can help you with that!");
                continue;
            }
            else if (userInput.Contains("quit") || userInput.Contains("exit"))
            {
                Console.WriteLine("Goodbye! Have a great day!");
                break;
            }

            // Default response for other inputs
            Console.WriteLine("I'm sorry, I didn't understand. Can you please rephrase?");
        }
    }
}


Running the Chatbot


To run the chatbot, navigate to the project directory in your terminal or command prompt and execute the following command.
dotnet run

You'll see the chatbot welcome message and prompt for the user's name. Then, you can interact with the chatbot by entering different inputs and observing the prompt engineering logic in action.

In this hands-on tutorial, we explored prompt engineering using .NET Core by building a simple chatbot application. We implemented various prompt engineering techniques, including contextual prompts, error handling, and response variation, to create an engaging conversational experience. By mastering prompt engineering with .NET Core, you can develop conversational interfaces that provide seamless interactions and enhance user engagement.

Start experimenting with prompt engineering in your .NET Core projects today and unleash the full potential of conversational AI systems.



ASP.NET Core 8 Hosting - HostForLIFE.eu :: Describe the.NET 8 Keyed Services

clock February 13, 2024 07:19 by author Peter

Keyed services are a major improvement to the built-in dependency injection (DI) framework of.NET 8. This functionality, which has long been a part of third-party DI frameworks like Autofac and StructureMap, gives developers more freedom and control over how dependencies are delivered to their applications. Now let's explore keyed services in more detail: Understanding Keyed Services


In the past,.NET DI registered services exclusively on the basis of their kind. Although this worked well in most cases, it became less successful when there were several implementations of the same interface. This is mitigated by keyed services, which enable us to link a special "key" to every service registration. An enum, string, or any other item that specifically defines the intended implementation can be used as this key.

Advantages of Services with Keys

  • Flexibility: You can inject particular implementations according to runtime circumstances, configuration settings, or dynamic conditions.
  • Decoupling: Implement different versions of the same interface for distinct uses to keep concerns apart.
  • Maintainability: Clearly name and reference desired dependencies in your code to improve readability.
  • Configurability: Apply several implementations according to configuration files or environment variables.

Consider a scenario where an application requires data storage because of configuration settings or user preferences. We have two implementations of the IDataStore interface: LocalStorage and CloudStorage.

1. Explain interfaces
public interface IDataStore
{
    void SaveData(string data);
}

public class LocalStorage : IDataStore
{
    public void SaveData(string data)
    {
        // Implementation to save data locally
        Console.WriteLine($"Saving data locally: {data}");
    }
}

public class CloudStorage : IDataStore
{
    public void SaveData(string data)
    {
        // Implementation to save data in the cloud
        Console.WriteLine($"Saving data in the cloud: {data}");
    }
}

2. Register Services with Keys
// In Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDataStore, LocalStorage>(key: "local");
    services.AddSingleton<IDataStore, CloudStorage>(key: "cloud");
}


3. Inject and Use Keyed Service
public class MyService
{
    private readonly IKeyedServiceProvider _provider;
    private readonly IConfiguration _configuration;

    public MyService(IKeyedServiceProvider provider, IConfiguration configuration)
    {
        _provider = provider;
        _configuration = configuration;
    }

    public void DoSomething()
    {
        string storageType = _configuration["StorageType"]; // e.g., "local" or "cloud"

        IDataStore store = _provider.GetKeyedService<IDataStore>(storageType);
        store.SaveData("This data will be saved based on the configuration.");
    }
}


4. Run the Application
// Program.cs
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    // Configure services and app...

    var app = builder.Build();

    // Run the app...
}

With their more sophisticated and adaptable approach to dependency injection, keyed services are a great addition to the.NET 8 DI architecture. You can gain more authority and clarity over the design of your program by comprehending their advantages, usage trends, and sophisticated applications. Learn about, play with, and take use of keyed services to create more flexible, dynamic, and organized.NET applications!



About HostForLIFE.eu

HostForLIFE.eu 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 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in