European ASP.NET MVC 4 and MVC 5 Hosting

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

ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Dapper ASP.NET Core MVC CRUD Application

clock October 25, 2023 07:48 by author Peter

ASP.NET Core MVC (Model-View-Controller) is a sophisticated web application framework. It offers an organized approach to developing web applications by splitting application logic into separate components. When it comes to data access, developers have several options. Dapper, a lightweight and efficient Object-Relational Mapping (ORM) library, is one of the more popular choices.


In this post, we'll look at how to build a comprehensive CRUD (Create, Read, Update, Delete) application with ASP.NET Core MVC and Dapper, combining the characteristics of both technologies to create a strong web application.

What exactly is Dapper?
Dapper is a.NET micro ORM library created by the Stack Overflow team. Dapper, in contrast to full-featured ORMs such as Entity Framework, keeps things simple and lightweight. It allows you to map database records to.NET objects without adding unnecessary complexity. Dapper is well-known for its speed and efficiency, making it an ideal candidate for high-performance applications.

Using ASP.NET Core MVC with Dapper to Create a CRUD Application

You'll need the following components to construct a comprehensive CRUD application with ASP.NET Core MVC and Dapper:

  • Visual Studio or any other code editor will suffice.
  • SQL Server or another database server may be used.
  • ASP.NET Core MVC application.

Let us now begin the process.

Make an ASP.NET Core MVC Project.
Begin by launching Visual Studio and creating a new ASP.NET Core MVC project. You can select the "Web Application" template and the "MVC" project type.

Step 1

Step 2


Step 3

Install Dapper
Install the Dapper library via NuGet Package Manager.

Database Interconnection
Connect to your SQL Server via a database connection. To connect to the database, use the connection string in your application.
Step 1. Launch SQL Server Management Studio (SSMS).
Step 2: Establish a connection to a SQL Server instance by entering the server name and authentication credentials.
Step 3: In the Object Explorer, right-click on the destination server's "Databases" folder and select "New Database."

Step 4: In a SQL Server database, follow these steps to build a table and CRUD (build, Read, Update, Delete) stored procedures for that table.
Make a Table
CREATE TABLE dbo.Person(
Id INT PRIMARY KEY IDENTITY,
FullName NVARCHAR (100) NOT NULL,
Email NVARCHAR (100) NOT NULL,
[Address] NVARCHAR (200) NOT NULL
);

Create CRUD Stored Procedures

/* CREATE OPERATION */
CREATE PROCEDURE sp_add_person(
    @name NVARCHAR(100),
    @emil NVARCHAR(100),
    @address NVARCHAR(200)
)
AS
BEGIN
    INSERT INTO dbo.Person (FullName, Email, [Address])
    VALUES (@name, @emil, @address)
END

/* READ OPERATION */
CREATE PROCEDURE sp_get_Allperson
AS
BEGIN
    SELECT * FROM dbo.Person
END

/* UPDATE OPERATION */
CREATE PROCEDURE sp_update_person(
    @id INT,
    @name NVARCHAR(100),
    @email NVARCHAR(100),
    @address NVARCHAR(200)
)
AS
BEGIN
    UPDATE dbo.Person
    SET FullName = @name, Email = @email, [Address] = @address
    WHERE Id = @id
END

/* DELETE OPERATION */
CREATE PROCEDURE sp_delete_person(@id INT)
AS
BEGIN
    DELETE FROM dbo.Person WHERE Id = @id
END

Create a Data Access Layer
Start by Adding a new Class Library project to your project.

Step 1

Step 2

Step 3. Define a model class to represent the data you want to manipulate.

public class Person
    {
        public int Id { get; set; }
        [Required]
        public string? FullName { get; set; }
        [Required]
        public string? Email { get; set; }
        public string? Address { get; set; }
    }

Step 4: Using Dapper, create a data access layer. This layer will include methods for carrying out CRUD tasks on your model objects.

using Microsoft.Extensions.Configuration;
using Dapper;
using Microsoft.Data.SqlClient;
using System.Data;

namespace DapperMVC.Data.DataAccess
{
    public class SqlDataAccess: ISqlDataAccess
    {
        private readonly IConfiguration _configuration;
        public SqlDataAccess(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public async Task<IEnumerable<T>> GetData<T, P>(string spName, P parameters, string connectionId = "conn")
        {
            try {
                string connectionString = _configuration.GetConnectionString(connectionId);
                using (IDbConnection dbConnection = new SqlConnection(connectionString))
                {
                    return await dbConnection.QueryAsync<T>(spName, parameters, commandType: CommandType.StoredProcedure);
                }
            }
            catch (Exception ex)
            {
                throw;
            }

        }
        public async Task<bool> SaveData<T>(string spName, T parameters, string connectionId = "conn")
        {
            try
            {
                using IDbConnection connection = new SqlConnection(_configuration.GetConnectionString(connectionId));
                await connection.ExecuteAsync(spName, parameters, commandType: CommandType.StoredProcedure);
                return true;
            }
            catch (Exception ex)
            {

                return false;
            }
        }
    }
}

using DapperMVC.Data.DataAccess;
using DapperMVC.Data.Models.DbModel;
using Microsoft.Extensions.Configuration;

namespace DapperMVC.Data.Repository
{
    public class PersonRepository : IPersonRepository
    {
        private readonly ISqlDataAccess _dataAccess;
        private readonly IConfiguration _configuration;
        public PersonRepository(ISqlDataAccess db, IConfiguration configuration)
        {
            _dataAccess = db;
            _configuration = configuration;
        }
        public async Task<bool> AddAsync(Person person)
        {
            try
            {
                await _dataAccess.SaveData("sp_add_person", new
                {
                    Name = person.FullName,
                    email = person.Email,
                    address = person.Address
                });
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public async Task<bool> UpdateAsync(Person person)
        {
            try
            {
                await _dataAccess.SaveData("sp_update_person", new
                {
                    id = person.Id,
                    Name = person.FullName,
                    email = person.Email,
                    address = person.Address
                });
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public async Task<bool> DeleteAsync(int id)
        {
            try
            {
                await _dataAccess.SaveData("sp_delete_person", new { Id = id });
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public async Task<Person?> GetByIdAsync(int id)
        {
            IEnumerable<Person> result = await _dataAccess.GetData<Person, dynamic>
                ("sp_get_person", new { Id = id });
            return result.FirstOrDefault();
        }
        public async Task<IEnumerable<Person>> GetAllPersonAsync()
        {
            string query = "sp_get_Allperson";
            return await _dataAccess.GetData<Person, dynamic>(query, new { });
        }
    }
}

Actions of the Controller
Make controller actions that communicate with your data access layer. These actions will process requests, call the appropriate data access methods, and return views.

public IActionResult Person()
{
    return View();
}

[HttpGet]
public async Task<IActionResult> Add()
{
    return View();
}

[HttpPost]
public async Task<IActionResult> Add(Person person)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return View(person);
        }
        bool addPerson = await _personRepo.AddAsync(person);
        if (addPerson)
        {
            TempData["msg"] = "Successfully Added";
        }
        else
        {
            TempData["msg"] = "Could Not Added";
        }
    }
    catch (Exception ex)
    {
        TempData["msg"] = "Could Not Added";
    }
    return RedirectToAction(nameof(Add));
}

[HttpGet]
public async Task<IActionResult> Edit(int id)
{
    var person = await _personRepo.GetByIdAsync(id);
    if (person == null)
    {
        throw new Exception();
    }
    return View("Edit", person);
}

[HttpPost]
public async Task<IActionResult> Edit(Person person)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return View(person);
        }
        var updateResult = await _personRepo.UpdateAsync(person);
        if (updateResult)
        {
            TempData["msg"] = "Edit Successfully.";
            return RedirectToAction(nameof(DisplayAllPerson));
        }
        else
        {
            TempData["msg"] = "Could Not Edit.";
            return View(person);
        }
    }
    catch (Exception ex)
    {
        TempData["msg"] = "Could Not Edit.";
        return View(person);
    }
}

[HttpGet]
public async Task<IActionResult> DisplayAllPerson()
{
    try
    {
        var personAll = await _personRepo.GetAllPersonAsync();
        return View(personAll);
    }
    catch (Exception ex)
    {
        return View("Error", ex);
    }
}

[HttpGet]
public async Task<IActionResult> Delete(int id)
{
    var deleteResult = await _personRepo.DeleteAsync(id);
    return RedirectToAction(nameof(DisplayAllPerson));
}

Views
Create views for your controller actions. You can use Razor views to generate HTML content and display data to users.

Implement the CRUD Operations
Create controller actions and views to handle Create, Update, and Delete operations. You'll need forms in your views for creating and editing data and buttons or links to delete records.

Test and Debug

Test your application thoroughly, making sure all CRUD operations work as expected. Debug any issues that arise.

Output



When paired with Dapper, ASP.NET Core MVC provides a robust and efficient framework for developing CRUD apps. Because of Dapper's lightweight and high-performance data access capabilities, it is an excellent solution for applications that require speed and simplicity. You can construct a powerful CRUD application that properly manages data and delivers a seamless user experience by following the steps indicated in this article. As you gain experience with Dapper and ASP.NET Core MVC, you can add more features and functionalities to your application.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Model Binders for ASP.NET MVC with Examples

clock September 15, 2023 06:57 by author Peter

ASP.NET MVC (Model-View-Controller) is a popular web development framework for creating strong and maintainable web applications. Model Binders are an important part of it. Model Binders play a critical role in mapping incoming HTTP requests to action method parameters, making it easier to work with client-side data. In this blog post, we will delve into the world of ASP.NET MVC Model Binders and present practical examples of how to use them.

What Exactly Are Model Binders?
Model Binders are ASP.NET MVC components that are responsible for mapping data from numerous sources, such as form fields, query strings, route parameters, and JSON payloads, to action method parameters. They are critical in easing the process of taking user input and transforming it into highly typed objects that your program may use.

Here's a detailed breakdown of how Model Binders work:

  • A user delivers an HTTP request to your ASP.NET MVC application, generally via a form submission or an API call.
  • Routing: The MVC framework uses routing rules to identify which controller and action method should handle the request.
  • Model Binders are useful in this situation. They collect data from the HTTP request and transfer it to the action method's arguments. The mapping is based on the names and types of parameters.
  • Execution of Action Methods: After the data is bound to the action method parameters, the method is executed using the provided data.
  • The action method processes the data and provides a response, which is returned to the client.

Now, let's look at some real-world examples of Model Binders.

Binding to Simple Types as an Example
Assume you have a simple HTML form with a single text input field named "username." You wish to capture the user's entered username.
public ActionResult Register(string username)
{
    // Process the username
    return View();
}

In this scenario, the Model Binder automatically binds the username parameter based on the name of the form input field.

Example 2: Complex Type Binding
Model Binders can also be used to tie complex types, such as custom classes, to action method parameters. Consider the following User class:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}


You can bind an instance of the User class from a form submission as follows:
public ActionResult CreateUser(User user)
{
    // Process the user object
    return View();
}

The Model Binder will automatically populate the User object's properties using the submitted form data.
Example 3. Custom Model Binders

In some cases, you might need to implement custom Model Binders to handle complex scenarios. For example, if you want to bind data from a non-standard source or perform custom data transformation, you can create a custom Model Binder.
public class CustomBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Custom logic to bind the model
        // Example: Read data from a cookie and populate the model
    }
}


To use the custom Model Binder, you can decorate your action method parameter with the [ModelBinder] attribute:

public ActionResult MyAction([ModelBinder(typeof(CustomBinder))] MyModel model)
{
    // Custom binding logic applied
    return View();
}

ASP.NET MVC Model Binders are critical components that let you manage user input data in your online applications. They make it simple to convert HTTP request data to action method parameters, making it easier to work with user-supplied data. Model Binders provide a strong technique for streamlining data binding in your ASP.NET MVC applications, whether you're dealing with simple types or complex objects.

You can design more efficient and maintainable web apps with ASP.NET MVC if you understand how Model Binders function and use them effectively.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Using Elastic Search With ASP.NET MVC

clock September 8, 2023 09:06 by author Peter

In this article, we are going to learn how to use elastic search with ASP.NET MVC in step by step way.We are already in the fifth part of this article. Till now, we have covered a lot in elastic search starting from how to configure elastic search to how to insert data into elastic search, further using Kibana for visualizing data, and at last, we have learned about Logstash and how to insert a bulk of data from MSSQL and MYSQL into elastic search. Now, it’s time to learn how we can query elastic search documents from ASP.NET MVC because at last, we need to show data to end-users in a fast way as possible.

 

If you are a beginner and you do not have an idea what is elastic search but you want to know it, then the below links will help you to kick start with elastic search.

Create ASP.NET MVC Application
Let’s create a simple ASP.NET MVC application with the name “WebElasticSearch”.

After entering the name, it will show another window for project selection. There, just choose “MVC” Template and change Authentication to “No Authentication” and click OK to create the project.

Project Structure

Next, we are going to install NuGet packages.            

Installing NuGet Packages

We are going to install 2 NuGet packages.

    Net
    Nest

After installing the NuGet package, next, we are going to add a new connection folder.
Creating Connector folder and adding ConnectionToEs class

After creating the folder, next, we are going to add ConnectionToEs class.
In this class, we are going to create a connection to elastic search instance. As you can see in the below code, we have provided elastic search URI http://localhost:9200/".

Code Snippet

    using Elasticsearch.Net;  
    using Nest;  
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Web;  
      
    namespace WebElasticSearch.Connector  
    {  
        public class ConnectionToEs  
        {  
            #region Connection string to connect with Elasticsearch  
      
            public ElasticClient EsClient()  
            {  
                var nodes = new Uri[]  
                {  
                    new Uri("http://localhost:9200/"),  
                };  
      
                var connectionPool = new StaticConnectionPool(nodes);  
                var connectionSettings = new ConnectionSettings(connectionPool).DisableDirectStreaming();  
                var elasticClient = new ElasticClient(connectionSettings);  
      
                return elasticClient;  
            }  
     
            #endregion Connection string to connect with Elasticsearch  
        }  
    }  

After creating the connection class, next, we are going to add a Controller and create View for search.

Add Controller “AllSearch”

Adding a controller with name “AllSearch”.

After adding the Controller, next, we are going to add an action method and in the constructor, we are going to instantiate the connection object.

Adding Action Method
In this part, we are going to add Action method “Search” and create an instance of the ConnectionToEs class.

Code Snippet
    using System.Web.Mvc;  
    using WebElasticSearch.Connector;  
      
    namespace WebElasticSearch.Controllers  
    {  
        public class AllSearchController : Controller  
        {  
            private readonly ConnectionToEs _connectionToEs;  
            public AllSearchController()  
            {  
                _connectionToEs = new ConnectionToEs();  
            }  
      
            [HttpGet]  
            public ActionResult Search()  
            {  
                return View("Search");  
            }  
        }  
    }  

After adding “Search” Action Method, we are going to add a View for that action method.

Now, we are going to design the View.

Designing View

In this part, we are going to design the View with 2 textboxes.

    jobtitle
    nationalidnumber

Below is document of “humanresource” index in which, first we are going to create a search on both these parameters.


After designing the search View, next, we are going to add a class “humanresource” and properties similar to “humanresource” index and type “doc”.

Adding Class similar to “Humanresource” Index and type “Doc”
    public class Humanresources  
    {  
     public string nationalidnumber { get; set; }  
     public string LoginID { get; set; }  
     public string OrganizationNode { get; set; }  
     public int? OrganizationLevel { get; set; }  
     public string jobtitle { get; set; }  
     public string BirthDate { get; set; }  
     public string MaritalStatus { get; set; }  
     public string Gender { get; set; }  
     public DateTime? HireDate { get; set; }  
     public bool? SalariedFlag { get; set; }  
     public int? VacationHours { get; set; }  
     public int? SickLeaveHours { get; set; }  
     public bool? CurrentFlag { get; set; }  
     public string rowguid { get; set; }  
     public DateTime? ModifiedDate { get; set; }  }

After adding humanresource class next we are going to add “DataSearch” Action Method which will take both this parameter as input and provide response in json.

Adding DataSearch Action Method
The request to elastic search we are going to send using “Nest” Client.

In this action Method the first thing we have done is to connect to elastic search using connectionEs class, then we have provided index “humanresources” and type “doc”, next we can provide size of document as output I have provided as 50, at last comes query in this we are using “match” query for that we are passing field jobtitle and in query we are going to pass value which we have searched.

Code Snippet
    public JsonResult DataSearch(string jobtitle, string nationalIDNumber)  
        {  
            var responsedata = _connectionToEs.EsClient().Search<Humanresources>(s => s  
                                    .Index("humanresources")  
                                    .Type("doc")  
                                    .Size(50)  
                                    .Query(q => q  
                                        .Match(m => m  
                                            .Field(f => f.jobtitle)  
                                            .Query(jobtitle)  
                                        )  
                                    )  
                                );  
      
            var datasend = (from hits in responsedata.Hits  
                            select hits.Source).ToList();  
      
            return Json(new { datasend, responsedata.Took }, behavior: JsonRequestBehavior.AllowGet);  
        }  

After creating Action Method and setting up search with Nest, next we are going to call this Action Method using AJAX and then display this result on View. Since we get the response as JSON, I am going to use a client-side grid from DevExpress.

Calling Datasearch Action Method using Ajax and Displaying Response in Grid

Code Snippet
    <script>  
        $(document).ready(function () {  
      
            $("#btnsubmit").on("click", function () {  
      
                if ($("#txtjobTitle").val() === "" && $("#txtnationalIDNumber").val() === "") {  
                    alert("Provide Details to Search !");  
                }  
                else {  
      
                    var obj = {};  
                    obj.jobTitle = $.trim($("#txtjobTitle").val());  
                    obj.nationalIDNumber = $.trim($("#txtnationalIDNumber").val());  
      
                    var apiUrl = "@Url.Action("DataSearch", "AllSearch")";  
      
                    $.ajax({  
                        type: "POST",  
                        contentType: 'application/json',  
                        url: apiUrl,  
                        dataType: "json",  
                        data: JSON.stringify(obj),  
                        crossDomain: true,  
                        success: function (data) {  
                            var response = data;  
      
                            if (data.datasend.length <= 0) {  
                                alert("No Data Found!!");  
                            } else {  
      
                                var timetook = data.Took;  
                                $('div.total-title').text(timetook + " millisecond");  
      
                                $("#gridContainer").dxDataGrid({  
                                    dataSource: data.datasend,  
                                    showColumnLines: false,  
                                    showRowLines: true,  
                                    rowAlternationEnabled: true,  
                                    showBorders: true,  
                                    paging: {  
                                        pageSize: 50  
                                    },  
                                    scrolling: {  
                                        mode: "infinite" // or "virtual" | "infinite"  
                                    },  
                                    pager: {  
                                        showPageSizeSelector: false,  
                                        allowedPageSizes: [5, 10, 20],  
                                        showInfo: true  
                                    },  
                                    columns: [  
                                        {  
                                            caption: "JobTitle",  
                                            width: 350,  
                                            fixed: true,  
                                            dataField: "jobtitle"  
                                        },  
                                        {  
                                            caption: "NationalIDNumber",  
                                            width: 300,  
                                            fixed: true,  
                                            dataField: "nationalidnumber"  
                                        },  
                                         "MaritalStatus",  
                                         "Gender",  
                                         "SalariedFlag",  
                                         "VacationHours",  
                                         "SickLeaveHours",  
                                         "CurrentFlag"  
                                    ]  
                                });  
      
                            }  
                        },  
                        error: function (xhr, err) {  
                            alert("readyState: " + xhr.readyState + "\nstatus: " + xhr.status);  
                            alert("responseText: " + xhr.responseText);  
                        }  
      
                    });  
      
                }  
      
            });  
      
        });  
      
    </script>  

Markup of Grid
    <div class="panel panel-default">  
        <div class="panel-heading">Output</div>  
        <div class="panel-body">  
            <div class="row">  
                <div class="col-lg-12">  
                    <div id="gridContainer"></div>  
                </div>  
            </div>  
        </div>  
    </div>   

We have set up everything. Let’s run the code and see the output.

Output

Let’s see in Debug Mode how it works.

Searching Values



Getting Response

Single Document View

Let us now make the search conditional, i.e., the user can use any combination to search.

If the user searches data by Jobtitle only, then he will get response according to jobtitle. If a user does search with nationalidnumber, then he will get response according to it. Finally, the combination of both (Jobtitle+ nationalidnumber) can also be used to search, then the user will get response according to it.

Code Snippet
    public JsonResult DataSearch(string jobtitle, string nationalIDNumber)  
          {  
      
              if (!string.IsNullOrEmpty(jobtitle) && !string.IsNullOrEmpty(nationalIDNumber))  
              {  
                  var responsedata = _connectionToEs.EsClient().Search<Humanresources>(s => s  
                                   .Index("humanresources")  
                                   .Type("doc")  
                                   .Size(50)  
                                   .Query(q => q  
                                       .Match(m => m  
                                           .Field(f => f.jobtitle)  
                                           .Query(jobtitle)  
                                       )  
                                       && q  
                                       .Match(m => m  
                                           .Field(f => f.nationalidnumber)  
                                           .Query(nationalIDNumber)  
                                   ))  
                               );  
      
                  var datasend = (from hits in responsedata.Hits  
                                  select hits.Source).ToList();  
      
                  return Json(new { datasend, responsedata.Took }, behavior: JsonRequestBehavior.AllowGet);  
      
              }  
              else if (!string.IsNullOrEmpty(jobtitle))  
              {  
                  var responsedata = _connectionToEs.EsClient().Search<Humanresources>(s => s  
                                  .Index("humanresources")  
                                  .Type("doc")  
                                  .Size(50)  
                                  .Query(q => q  
                                      .Match(m => m  
                                          .Field(f => f.jobtitle)  
                                          .Query(jobtitle)  
                                      )));  
      
                  var datasend = (from hits in responsedata.Hits  
                                  select hits.Source).ToList();  
      
                  return Json(new { datasend, responsedata.Took }, behavior: JsonRequestBehavior.AllowGet);  
              }  
              else if (!string.IsNullOrEmpty(nationalIDNumber))  
              {  
                  var responsedata = _connectionToEs.EsClient().Search<Humanresources>(s => s  
                                  .Index("humanresources")  
                                  .Type("doc")  
                                  .Size(50)  
                                  .Query(q => q  
                                      .Match(m => m  
                                          .Field(f => f.nationalidnumber)  
                                          .Query(nationalIDNumber)  
                                      )));  
                  var datasend = (from hits in responsedata.Hits  
                                  select hits.Source).ToList();  
      
                  return Json(new { datasend, responsedata.Took }, behavior: JsonRequestBehavior.AllowGet);  
              }  
              return Json(data: null, behavior: JsonRequestBehavior.AllowGet);  
      
          }  


Output


These are simple examples which will help you to start using elastic search with ASP.NET Application. There are lots of filters and ways to write query in Elastic using “Nest” in ASP.NET.

Finally, we have learned how to simply query elastic search using “Nest” Client and display data in grid.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Simple Login Application using Sessions in ASP.NET MVC

clock September 1, 2023 10:10 by author Peter

Step: Design your Database
Create the UserProfile table using the following script.
    Create Table UserProfile  
        (  
            UserId int primary key identity(1, 1),  
            UserName varchar(50),  
            Password varchar(50),  
            IsActive bit  
        ) 



Insert user records using the following script.
    Insert into UserProfile  
    Select 'peter', 'pete1234', 1 Union All  
    Select 'scott', 'scott1234', 1 Union All  
    Select 'laura', 'laura1234', 1


Step 1: Create Project
Go to FILE, New, then click on Project.

Select Visual C#, Web under Installed templates. After that select ASP.NET MVC Web Application, then mention the Application Name (MvcLoginAppDemo) and Solution Name as you wish, then click OK.

Under Project template select a template as Basic, then Click OK.

Step 2: Add Entity Data Model
Go to Solution Explorer, Right Click on Project, Add, then select ADO.NET Entity Data Model.

Give it a meaningful model name and then click on Add.

Select Generate from database and then click on Next.


Click on New Connection,

After clicking on New Connection, we have to provide the following Connection Properties in the following wizard.
    Provide the Server name.
    Select the "Use SQL Server Authentication" radio button.
    Enter the User name and Password in the password text box.
    Check the "Save my password" checkbox.
    Select the "Select or enter a database name:" radio button.
    Select the database to which you want to set the connection.
    Click on the "Test Connection" button to ensure the connection can be established.
    Then click OK.

Select radio button: Yes include the sensitive data in the connection string. Choose your database objects, as in the following image. Click on Finish. At this point UserProfie entity will be created.

Step 3: Add a Controller
Go to Solution Explorer, Right click on Controller folder, Add and then click on Controller.
( Or ) Simply use shortcut key Ctrl + M, Ctrl + C,

Provide the Controller Name, and Scaffolding template as Empty MVC Controller. Then click on Add.

Write the following code in HomeController.
    using System.Linq;  
    using System.Web.Mvc;  
      
    namespace MvcLoginAppDemo.Controllers  
    {  
        public class HomeController: Controller  
        {  
            public ActionResult Login()  
            {  
                return View();  
            }  
      
            [HttpPost]  
            [ValidateAntiForgeryToken]  
            public ActionResult Login(UserProfile objUser)   
            {  
                if (ModelState.IsValid)   
                {  
                    using(DB_Entities db = new DB_Entities())  
                    {  
                        var obj = db.UserProfiles.Where(a => a.UserName.Equals(objUser.UserName) && a.Password.Equals(objUser.Password)).FirstOrDefault();  
                        if (obj != null)  
                        {  
                            Session["UserID"] = obj.UserId.ToString();  
                            Session["UserName"] = obj.UserName.ToString();  
                            return RedirectToAction("UserDashBoard");  
                        }  
                    }  
                }  
                return View(objUser);  
            }  
      
            public ActionResult UserDashBoard()  
            {  
                if (Session["UserID"] != null)  
                {  
                    return View();  
                } else  
                {  
                    return RedirectToAction("Login");  
                }  
            }  
        }  
    }  


Step 4: Create Views
Create View for Login Action Method
 
Right click on the Login Action method, then click on Add View as in the following picture.

Create Strongly Typed View
    View Name must be an action method name.
    Select view engine as Razor.
    Select Create a strongly typed view CheckBox .
    Select Model class as UserProfile (MvcLoginAppDemo)
    Select Scaffold template as Empty
    Click on Add

And write the following code in Login.cshtml (view).
    @model MvcLoginAppDemo.UserProfile  
      
    @{  
    ViewBag.Title = "Login";  
    }  
      
    @using (Html.BeginForm("Login", "Home", FormMethod.Post))  
    {  
    <fieldset>  
    <legend>Mvc Simple Login Application Demo</legend>  
      
    @Html.AntiForgeryToken()  
    @Html.ValidationSummary(true)  
    @if (@ViewBag.Message != null)  
    {  
    <div style="border: 1px solid red">  
    @ViewBag.Message  
    </div>  
    }  
    <table>  
    <tr>  
    <td>@Html.LabelFor(a => a.UserName)</td>  
    <td>@Html.TextBoxFor(a => a.UserName)</td>  
    <td>@Html.ValidationMessageFor(a => a.UserName)</td>  
    </tr>  
    <tr>  
    <td>  
    @Html.LabelFor(a => a.Password)  
    </td>  
    <td>  
    @Html.PasswordFor(a => a.Password)  
    </td>  
    <td>  
    @Html.ValidationMessageFor(a => a.Password)  
    </td>  
    </tr>  
    <tr>  
    <td></td>  
    <td>  
    <input type="submit" value="Login" />  
    </td>  
    <td></td>  
    </tr>  
    </table>  
    </fieldset>  
    }  


Create View for UserDashBoard Action method same as login view. And write the following code in UserDashBoard.cshtml (View).
    @ {  
        ViewBag.Title = "UserDashBoard";  
    }  
      
    < fieldset >  
        < legend > User DashBoard < /legend>  
      
    @if(Session["UserName"] != null) { < text >  
            Welcome @Session["UserName"].ToString() < /text>  
    } < /fieldset>  


Step 5: Set as StartUp Page
Go to Solution Explorer, Project, App_Start, then RouteConfig.cs  and change the action name from Index to Login (Login.cshtml as start up page).

Step 6: Run the Application
Provide the user credentials and click on OK. If you provide the valid user credentials then the user name will be displayed on your dashboard.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Using an ASP.NET MVC Application, Create a WEB API POST Method to Retrieve Data from a SQL Database

clock August 24, 2023 07:58 by author Peter

In this post, I'll show you how to use an ASP.NET MVC application to establish a WEBAPI POST function to extract data from a SQL database.

Open SQL Management Studio, then create a new table and write the table's stored procedure.
Table column names and datatypes are determined by your needs.

Create proc [dbo].[UserInfo]
(
@UserName nvarchar(100)
)
as
(
select UserId,UserName,Address,IsActive,UserTypeId from WebAPI
where
UserName=@UserName
)


Once you have successfully created the SQL store procedure then Create a new MVC WebAPI Application using visual studio.
provide the project name and project location.

Choose Empty project, then select the MVC and WEB API options from the essential references column on the right.

Now the project has been created successfully.

After you've created the project, right-click on the Models folder, select Add, and then New item. In the Models Folder, place the class file.

From the C# node then choose the class definition and provide the class file name UserEntity.cs. Once we added the class file to our project solution.

Use the below code in UsersEntity.cs file.
using Microsoft.SqlServer.Server;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.Office.SharePoint.Tools;
using static System.Net.Mime.MediaTypeNames;
using System.Data;

namespace SampleWebAPI.Models
{
    public class UsersEntity
    {

        public string UserId { get; set; }

        public string UserName { get; set; }

        public string Address { get; set; }

        public string UserTypeId { get; set; }

        public string IsActive { get; set; }

        public UsersEntity()
        {

        }
     }

}

Likewise create a new logger.cs and ErrorDetails.cs class file to capture the logs and error details in the Models folder.

Use the below code in Logger.cs file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleWebAPI.Models
{
    public class Logger
    {
         // To capture the log details
        #region "-- Class Level Variable / Object Declaration --"
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        #endregion
        #region "-- Public Functions --"
        public static void LogError(string msg, Exception ex)
        {
            logger.Error(msg, ex); //This for error msg
        }
        public static void LogDebug(string msg, Exception ex)
        {
            logger.Debug(msg, ex);
        }
        public static void LogFatal(string msg, Exception ex)
        {
            logger.Fatal(msg, ex);
        }
        public static void LogInfo(string msg)
        {
            logger.Info(msg);
        }
        public static void LogWarn(string msg, Exception ex)
        {
            logger.Warn(msg, ex);
        }
        public static void LogInfo(string msg, Exception ex)
        {
            logger.Info(msg, ex);
        }
    }
    #endregion
}


Use the below code in ErrorDetails.cs file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleWebAPI.Models
{
//This Class used for error msg
    public class ErrorDetails
    {
        public List<string> schemas { get; set; }
        public string details { get; set; }
        public int status { get; set; }
    }
}

Then add the controller to the Controller folder.
Right Click on the Controller folder, choose to add, and click Controller.
Click the MVC empty read and write controller file.

Then give the controller name based on your requirement.

Once the Controller has been created successfully, we can write the Controller methods in the controller.
Use the below code in the controller.
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using SampleWebAPI.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.UI.WebControls;
using Microsoft.Office.SharePoint.Tools;
using static System.Net.Mime.MediaTypeNames;

namespace SampleWebAPI.Controllers
{
    public class UserController : ApiController // To Initialize the Web API
    {
        [System.Web.Http.AcceptVerbs("GET", "POST")] // To check the result in browser
        [System.Web.Http.HttpPost] //To check the Post method
        [System.Web.Http.Route("users/info")] //This the route url
        public JObject info(string UserName)
        {
            ErrorDetails objErrorDetail = new ErrorDetails();
            string jsonResponse = string.Empty;
            JObject jsonObject = null;


            try
            {
                Logger.LogInfo("info: starting to get user list info");
                DataSet ds = new DataSet();
                UsersEntity objUserDetail = new UsersEntity();
                SqlConnection conn = new SqlConnection();
                conn.ConnectionString ="Data Source=Test;" +"Initial Catalog=Test;" +"User id=Test;" + "Password=Test;";

                {
                  //Sql connection from the database
                    using (SqlCommand cmd = new SqlCommand("UserInfo", conn))
                    {
                        conn.Open();
                        Logger.LogInfo("info: Sql Connection established.");
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@UserName",UserName);
                        SqlDataAdapter da = new SqlDataAdapter(cmd);
                        da.Fill(ds);
                        conn.Close();
                        Logger.LogInfo("info: Sql Connection closed.");

                    }
                }

                if (ds.Tables[0].Rows.Count >= 1)
                {
                    Logger.LogInfo("info: starting to format the json.");
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        // Display the column in the output page using object dataset.
                        List<string> lst = new List<string>();
                        objUserDetail.UserName = dr["UserName"].ToString();
                        objUserDetail.UserId = dr["UserId"].ToString();
                        objUserDetail.Address = dr["Address"].ToString();
                        objUserDetail.UserTypeId = dr["UserTypeId"].ToString();
                        objUserDetail.IsActive = dr["IsActive"].ToString();
                        jsonResponse = JsonConvert.SerializeObject(objUserDetail);
                        // Deserialize the JSON API response into a JObject
                        jsonObject = JsonConvert.DeserializeObject<JObject>(jsonResponse);
                        // Serialize the updated object back to JSON
                        string updatedJsonResponse = jsonObject.ToString();

                    }
                    Logger.LogInfo("info: data formatted in json successfuly.");
                    return jsonObject;
                }
                else
                {
                    Logger.LogInfo("info: User not found returned null data.");
                    List<string> lst = new List<string>();
                    lst.Add("urn:ietf:params:scim:api:messages:2.0:Error");
                    objErrorDetail.schemas = lst;
                    objErrorDetail.status = (int)HttpStatusCode.NotFound;
                    objErrorDetail.details = "User Not Found";
                    return JsonConvert.DeserializeObject<JObject>(JsonConvert.SerializeObject(objErrorDetail));
                }
            }
            catch (Exception ex)
            {
                Logger.LogInfo("info: Error occured.");
                Logger.LogError("info: Error - " + ex.Message, ex);
                jsonObject = null;
                List<string> lst = new List<string>();
                lst.Add("urn:ietf:params:scim:api:messages:2.0:Error");
                objErrorDetail.schemas = lst;
                objErrorDetail.status = (int)HttpStatusCode.InternalServerError;
                objErrorDetail.details = ex.Message.ToString();
                return JsonConvert.DeserializeObject<JObject>(JsonConvert.SerializeObject(objErrorDetail));
            }

        }

    }
}



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Creating Dynamic Dropdown Lists in ASP.NET MVC Using AJAX

clock August 14, 2023 09:43 by author Peter

Introduction: In this article, we will explore how to implement dynamic dropdown lists in an ASP.NET MVC application. We'll use jQuery AJAX to fetch data from the server and populate dependent dropdown lists based on user selections. The provided code includes examples of how to create cascading dropdowns for countries, states, and cities, allowing users to select specific locations for student data.


Prerequisites: To follow this tutorial, you should have a basic understanding of ASP.NET MVC, C#, jQuery, and Entity Framework.

Building the Dropdown Form
Building the Dropdown Form: In the "Index.chtml" file, we have designed a form to collect student data, including cascading dropdowns for countries, states, and cities.
<!-- Index.chtml -->
<!-- ... (existing code) ... -->
<div class="text-light text-center my-3 d-flex justify-content-center gap-3">
    <div>
        @if (ViewBag.Country != null)
        {
            @Html.DropDownListFor(x => x.Country, ViewBag.Country as SelectList, "Select Country", new { @class = "form-control" })
        }
    </div>
    <div class="stateSection">
        <span id="states-loading-progress" style="display: none;">Please wait for State..</span>
        @Html.DropDownListFor(x => x.State, ViewBag.State as SelectList, "Select State", new { @class = "form-control" })
        @Html.ValidationMessageFor(x => x.State)
    </div>
    <div class="citySection">
        <span id="states-loading-progress" style="display: none;">Please wait for City..</span>
        @Html.DropDownListFor(x => x.City, ViewBag.City as SelectList, "Select City", new { @class = "form-control" })
        @Html.ValidationMessageFor(x => x.City)
    </div>
</div>
<!-- ... (existing code) ... -->


Implementing AJAX for Dropdowns
Implementing AJAX for Dropdowns: In the JavaScript section, we've added AJAX functions to handle the country and state dropdowns dynamically.
/*------ Country Function -------*/
$("#Country").change(function () {
    var stateID = $(this).val();
    $('#State').empty();
    $('#City').addClass('d-none');

    console.log(stateID);

    var statesProgress = $("#states-loading-progress");
    statesProgress.show();

    if (stateID > 0) {
        $(".stateSection").addClass('active');

        $.ajax({
            type: "GET",
            url: "/Home/GetStateById/" + stateID,
            success: function (data) {
                $("#State").html('');

                var defaultOption = "<option value>Select State</option>";
                $("#State").append(defaultOption);

                $.each(data, function (id, option) {
                    var optionHtml = "<option value=" + option.StateID + ">" + option.StateName + "</option>";
                    $("#State").append(optionHtml);
                });

                statesProgress.hide();
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('State function failed');
                statesProgress.hide();
            }
        });
    } else {
        $(".stateSection").removeClass('active');
        $(".citySection").removeClass('active');
        $.notify("Please select a Country", "error");
    }
});


/*------ State Function -------*/
$("#State").change(function () {
    $('#City').removeClass('d-none');
    var cityID = $(this).val();
    var statesProgress = $("#states-loading-progress");
    statesProgress.show();

    if (cityID > 0) {
        $(".citySection").addClass('active');

        $.ajax({
            type: "GET",
            url: "/Home/GetCityById/" + cityID,
            success: function (data) {
                $("#City").html('');

                var defaultOption = "<option value>Select City</option>";
                $("#City").append(defaultOption);

                $.each(data, function (id, option) {
                    var optionHtml = "<option value=" + option.Id + ">" + option.CItyName + "</option>";
                    $("#City").append(optionHtml);
                });

                statesProgress.hide();
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('City function failed');
                statesProgress.hide();
            }
        });
    } else {
        $(".citySection").removeClass('active');
        $.notify("Please select a State", "error");
    }
});


Handling Dropdown Requests in the Controller
Handling Dropdown Requests in the Controller: In the "HomeController," we've added action methods to retrieve country, state, and city data from the database and return them as JSON results for the AJAX requests.
// Home Controller Method
public class HomeController : Controller
{
    public ActionResult Index()
        {
            List<CountryTable> CountryList = db.CountryTable.ToList();
            ViewBag.Country = new SelectList(CountryList, "Id", "countryName");

            List<StateTable> StateList = db.StateTable.ToList();
            ViewBag.State = new SelectList(StateList, "StateID", "StateName");

            List<CityTable> CityList = db.CityTable.ToList();
            ViewBag.City = new SelectList(CityList, "Id", "CItyName");

            return View();
        }

        public JsonResult GetStateById(int ID)
        {
            db.Configuration.ProxyCreationEnabled = false;
            var stateList = db.StateTable.Where(x => x.CountryID == ID).ToList();
            return Json(stateList, JsonRequestBehavior.AllowGet);
        }

        public JsonResult GetCityById(int ID)
        {
            db.Configuration.ProxyCreationEnabled = false;
            var CityList = db.CityTable.Where(x => x.StateID == ID).ToList();
            return Json(CityList, JsonRequestBehavior.AllowGet);
        }

        public ActionResult EditStudent(int ID)
        {
            var result = repo.EditFunction(ID);
            // Set selected values for the dropdown lists
            List <CountryTable> CountryList = db.CountryTable.ToList();
            ViewBag.CountryList = new SelectList(CountryList, "Id", "countryName", result.Country);

            List<StateTable> StateList = db.StateTable.ToList();
            ViewBag.StateList = new SelectList(StateList, "StateID", "StateName", result.State);

            List<CityTable> CityList = db.CityTable.ToList();
            ViewBag.CityList = new SelectList(CityList, "Id", "CItyName", result.City);

            return View(result);
        }
    }
}


Conclusion: In this article, we have learned how to create dynamic dropdown lists with cascading behavior in an ASP.NET MVC application using AJAX. The JavaScript AJAX functions communicate with the server to fetch data based on user selections, and the ASP.NET MVC controller methods handle the requests and return JSON results. By following this guide, you can enhance your web application with more interactive features and improve the user experience with dynamic dropdowns. Happy coding!



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Understanding Routing Precedence In ASP.NET MVC And Web API

clock August 3, 2023 09:40 by author Peter

Routing can be a very tricky issue within ASP.NET MVC and Web API applications. This can be especially true if you have a variety of different routes with varying parameters, defined in such a way that a single request could satisfy multiple routes.


This blog post will cover some of the precedence rules that are applied to routing in ASP.NET MVC and Web API and how to leverage these to ensure that the route you want to use gets used.

What are Routes? How do they work?
A Route in ASP.NET simply consists of a pattern that is going to be mapped to a handler. The handlers themselves can be a variety of different mechanisms (e.g. a physical file, a Web Forms page, or an MVC Controller class). In simplest terms, Routes define how requests are handled within your application.

Routes consist of the following three components,

    A name to identify the Route itself.
    A pattern to match URLs to match a request with its appropriate handler.
    A handler to tell requests that match the pattern where to go.

You can see an example of a route declaration in ASP.NET MVC below, which contains all three of these criteria.
    routes.MapRoute(   
    "Default", // Name  
    "{controller}/{action}/{id}", // Pattern  
    new { controller = "Home", action = "Index", id = "" } // Handler  
    );  


Routes can also be defined by using the [Route] attribute and decorating a particular Controller Action with it.
    [Route("widgets/{brand}", Order = 1)]  
    public IEnumerable<Widget> GetWidgetsByBrand(string brand) { ... }   

Since the focus of this post isn't really about routing itself and more of routing precedence, I won't go into too many more details about declaring them.

ASP.NET will store all of the defined Routes within a Routes Table and when a request comes to it, it will look through these Routes to determine the one best suited in order to serve the request. To know how this works, we need to know how Routes are prioritized and that's why this blog post exists at all.

Routes match requests using a pattern and tell them where to go.

Routing Precedence

Routing can be a blessing and a curse within an application. It can provide you with the freedom to define all sorts of very creative and easily understandable approaches to accessing the data, but when overused, things can get hairy. The primary reason that routing can make you want to pull your hair out is that a single request can match multiple routes.

The routing order can be broken down into the following steps.
    Check the Order property (if available).
    Order all Routes without an explicit Order attribute, as follows.

        Literal segments.
        Route parameters with constraints.
        Route parameters without constraints.
        Wildcard parameter segments with constraints.
        Wildcard parameter segments without constraints.

    As a tie-breaker, order the Routes via a case-insensitive string comparison.

Confused yet? That's okay
Let's talk about defining Route Order and the different types of routes for a moment, to clear things up.

Route Order

You can use the [Route] attribute to explicitly set when a particular route is going to be checked against the order property. By default, all defined routes have an order value of 0 and routes are processed from lowest to highest. This is the primary reason that it is so important for establishing the route precedence, as it's a single attribute that will govern the order in which routes are processed.

Let's look at the following three routes.
    [Route("Alpha", Order = 1)]  
    public void Fizz() { ... }   
    [Route("Beta")]  
    public void Buzz() { ... }   
    [Route("Gamma")]  
    public void FizzBuzz() { ... }   


Since the Alpha Route has an order property of 1, it will always be evaluated last. The only scenario where that would not be true would be if another route had a higher order value or an equal one (and it received priority via the other criteria).

Literal Segments
A Literal Segment Route can be thought of as a "hard-coded" route. It contains no types of parameters and no constraints. A few examples of these types of routes might look like.
    /widgets/broken  
    /employees  

Route Parameters
Route Parameters are going to have a bit more information that literals, but not by much. The only major difference is that they will have a "placeholder" that can be used to define parameters, similar to the String.Format() method.
    /widgets/{widgetId}  
    /reports/{year}/{month}  


Route Parameters with Constraints
Route Parameters can also be constrained to a specific type. This is important as they will be evaluated prior to unconstrained ones.
    /widgets/{widgetId:int}  
    /reports/{year:int}/{month:int}  

Wildcard Parameters
Wildcard Parameters are the last type of parameters to review, and you generally won't see these as much as the aforementioned types. These function as "catch-all" parameters and may contain more than a single segment.

Consider the following route,
    /query/widgets/{*queryvalues}  

Notice the {*queryvalues} segment. The leading asterisk indicates that this is a wildcard parameter and thus, it can accept all sorts of additional segments in it.
    /query/widgets/broken  
    /query/widgets/byyear/2015  

Wildcard Parameters with Constraints
Wildcard parameters can also feature type constraints just like normal route parameters as well if you are expecting a certain type,
    /query/widgets/{*byyear:int}  

Applying Precedence in Action
Now, to break this down, let's define several actions that meet the criteria of at least one of each of these routes. We will look at each phase as we order the routes.
    [RoutePrefix("widgets")]  
    public class WidgetsController: ApiController {  
            [Route("{widgetId:int}")] // Constrained Route Parameter  
            public HttpResponseMessage Get(int widgetId) {...  
                }  
                [Route("new")] // Literal Segment  
            public HttpResponseMessage GetNew() {...  
                }  
                [Route("{*features})] // Unconstrained Wildcard Parameter  
                        public HttpResponseMessage GetByFeatures(string features) {...  
                        }  
                        [Route("broken", RouteOrder = 1)] // Literal Segment (with Route Order)  
                        public HttpResponseMessage GetBroken() {...  
                        }  
                        [Route("{brand}")] // Unconstrained Route Parameter  
                        public HttpResponseMessage GetByBrand(string brand) {...  
                        }  
                        [Route("{*date:datetime}")] // Constrained Wildcard Parameter  
                        public HttpResponseMessage GetByManufacturedDate(DateTime date) {...  
                        }  
                    }  

So, with all of these routes defined, let's output all of them as they appear in the Controller and update them as we apply each rule.
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetNew() // widgets/new   
    GetByFeatures(string features) // widgets/{*features}   
    GetBroken() // widgets/broken   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   


Firstly, check the routes for the Order attribute. Now, since the GetBroken()action has an Order of 1, we know that this will be the last route to be evaluated (since the default is 0 and routes are processed in ascending order).
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetNew() // widgets/new   
    GetByFeatures(string features) // widgets/{*features}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetBroken() // widgets/broken   


Next up, we will check for any literal routes and ensure that they will be the first to be processed. In this case, the GetNew() action meets that requirement, so move it to the beginning,
    GetNew() // widgets/new   
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetByFeatures(string features) // widgets/{*features}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetBroken() // widgets/broken   


After literals, the next routes to be processed are constrained route parameters. The Get(int) action meets this requirement as it accepts an integer for its widgetId parameter, so it will fall next in line,
    GetNew() // widgets/new   
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetByFeatures(string features) // widgets/{*features}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetBroken() // widgets/broken   


Next, unconstrained route parameters are processed. The GetByBrand(string)action meets this requirement as it contains a parameter, but it doesn't specify a type for it,
    GetNew() // widgets/new   
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByFeatures(string features) // widgets/{*features}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetBroken() // widgets/broken   


After all of the literals and route parameters have been routed, the next to be evaluated are the wildcard parameters. More specifically, the constrained wildcard parameters, which the GetbyManufacturedDate(DateTime) route matches,
    GetNew() // widgets/new   
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetByFeatures(string features) // widgets/{*features}   
    GetBroken() // widgets/broken   

And finally, the last route type to evaluate is unconstrained wildcard parameters (or "catch-all" routes). The GetByFeatures(string) route fits under that category so it will be placed prior to the GetBroken() route, which had a higher Order property,
    GetNew() // widgets/new   
    Get(int widgetId) { ... } // widgets/{widgetId:int}   
    GetByBrand(string brand) // widgets/{brand}   
    GetByManufacturedDate(DateTime date) // widgets/{*date:datetime}   
    GetByFeatures(string features) // widgets/{*features}   
    GetBroken() // widgets/broken   


And that's it as we don't have any ties to break. But, if a tie between two routes did exist, then a case-insensitive comparison of the route template names would resolve it.

Any requests that come through will be evaluated in that order (i.e. the first pattern to match against the URL will be action that handles the request).

Your Mileage May Vary
One important thing to point out in a post like this is that generally, you shouldn't have to deal with routing precedence too often. If you are responsible for building and designing your API, then try to keep your API as simple as possible.

Don't try to create this sprawling, verbose API of endless routes unless you absolutely have to. Complicated APIs can lead to complicated problems, and in most cases, if your API is too difficult to interact with, others won't likely want to use it (especially, if you are building a public-facing API).



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How To Add Identity-Based Authentication To An ASP.NET Core 6 MVC Project?

clock July 12, 2023 07:04 by author Peter

Integrating security into your application is a crucial step. So that only authenticated users are permitted access to the application. ASP.NET Core Identity is a robust system that facilitates the authentication of users in ASP.NET Core applications. User registration, login, password administration, role-based authorization, and integration with external authentication providers are among its many features.


You will learn how to add identity service to your ASP.NET 6 MVC project in this article. Before beginning, let's examine the fundamentals.

What is ASP.NET MVC Core?

Microsoft ASP.NET Core MVC is a robust and adaptable web application development framework for the ASP.NET Core platform. The model, the view, and the controller are the three distinct application components that are separated by MVC. The model represents the data and business logic of the application. It contains the necessary data structures, logic, and algorithms for manipulating and processing the data. The view is accountable for displaying the user interface to the end user. The view receives data from the model and displays it in an approachable manner. The controller mediates between the model and view. The controller manages the application's flow by receiving and processing requests and returning the appropriate response.


What is the difference between authentication and authorization?
Authentication and authorization are essential application development components. Authentication is the process of confirming a user's identity, assuring that they are who they claim to be. Authorization, on the other hand, is the process of granting or denying access to specific resources or functionalities based on the permissions and roles of the authenticated user.

It is essential to employ a secure authentication and authorization mechanism in today's digital environment, where sensitive user data and confidential information are involved. It protects user accounts, restricts unauthorised access to sensitive data, and ensures that only authorised users are able to perform specific actions within the application. By effectively incorporating authentication and authorization, developers can increase the overall security and credibility of web applications.

What is ASP.NET Identity Core?

ASP.NET Core Identity is a membership system for ASP.NET Core applications that provides support for user authentication and authorization. It simplifies the management of user accounts, passwords, and roles, allowing developers to concentrate on the essential functionality of applications.

In other words, ASP.NET provides the necessary functionality for adding features such as registering, logging in, logging out, managing users, passwords, profiles, authorization, roles, claims, tokens, and email confirmation.

ASP.NET Core Identity provides a comprehensive set of features, including user registration, login, password management, role-based authorization, and integration with external authentication providers. It integrates seamlessly with ASP.NET Core MVC, making it simple to add authentication and authorization features to your web application.

Using ASP.NET Core Identity, developers can employ secure authentication mechanisms, such as cookies and JSON Web Tokens (JWT). In addition, it features a flexible and extensible architecture that permits customization and integration with existing user repositories and providers. Whether you are developing a small-scale application or a large enterprise-level system, ASP.NET Core Identity provides the tools and APIs required to implement secure and scalable authentication and authorization solutions.

How Do I Configure ASP.NET Core Identity In My Project?
To perform authentication using Identity, I will create a brand-new project. Let us now establish the project.

1. Establishing the undertaking
Open Visual Studio 2022. Select "Create a new project" and then select "Next". Click "Next" after selecting the "ASP.NET Core Web App (Model-View-Controller)" template.


Click "Next" after customising the project and solution names and selecting the location where you desire to save the project. The name of our initiative is CRMApp.

Click "Create" after selecting "NET 6" as the framework.

Now, the project has been effectively created.

Step 2: Configuring the database
Launch SSMS (SQL Server Management Server) and use it to create and manage databases.

create database SalesCRM;
use SalesCRM;


Step 3. Open appsetting.js and set the connection string.
"ConnectionStrings":
{
  "SalesCRMcnn": "Server=***;Database=SalesCRM;User Id=**;Password=****;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
}

Step 4. Creating Models
Click on Models and add a new class named SalesleadEntity.cs. In this class, add the required properties for the model as shown below.
namespace CRMApp.Models
{
    public class SalesLeadEntity
    {
        public int Id { get; set; }
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public string? Mobile { get; set; }
        public string? Email { get; set; }
        public string? Source { get; set; }
    }
}

Step 5. Adding Required Packages
Now, Right click on the project and select "Manage NuGet Packages". In the browse section, search the following packages and install them.
    Microsoft.EntityFrameworkCore
    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore.Tools
    Microsoft.AspNetCore.Identity.EntityFrameworkCore


Now, Create a new folder named "Data" in the project and add a new class named "ApplicationDbContext.cs".
using CRMApp.Models;
using Microsoft.EntityFrameworkCore;
namespace CRMApp.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions options) : base(options)
        {
        }
        public DbSet<SalesLeadEntity> SalesLead { get; set; }
    }
}

Now, open program.cs, and add the following service in the file.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SalesCRMcnn")));

Step 6. Adding the migration to the database
To add migration to the database, Go to "Tools" -> "NuGet Package Manager" -> "Package Manager Console", and the package manager console will open.

In the console, run the following commands.
add-migration "Initial migration"
Update-database


After running the above commands, a migration file will be added to your project, having folder name Migrations, and the database will be updated.

Step 7. Adding Controller
Click on Controller and add a new Scaffolded Item and select "MVC Controller with views, using Entity Framework," and click on "Add". A popup will open like this.

Choose "SalesLeadEntity" as the model class and "ApplicationDbContext" as DbContext class. Also, name the controller "LeadsController". Click on "Add", and a new controller will get created with action methods in it.

Now, go to "_Layout.cshtml" and add the following lines to make a new menu for the Sales Lead.
<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Leads" asp-action="Index">Sales Lead</a>
</li>


Now, if you will run the project and open the index page, you will have an empty page like this.

Here, click "Create New" to create a new record.

Once you add the records on the index page, you will have that records.

Step 8. Securing the project using Identity


Before adding Identity to the project, update the "ApplicationDbContext.cs" with the below code, as now we will be inheriting IdentityDbContext instead of DbContext.
using CRMApp.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace CRMApp.Data
{
    public class ApplicationDbContext : IdentityDbContext
    {
        ...
    }
}

Now, Right Click on the project and click on "Add new Scaffolded Item". Click on "Identity" and then click "Add".

Here, I have selected all options, but you can select according to your need and project requirements. Choose DbContextClass as "ApplicationDbContext" and Click on "Add".
Now, you will have Identity added to your project using scaffolding. Now, you will see a folder named Areas which has a sub-folder named Identity which contains a sub-folder names Account which has endpoints for login register, logout, etc in the form of razor pages.

Step 9.  Adding necessary code and updating the database

Open "_Layout.cs", and add the following code in the <nav> section before the </nav>
<partial name="_LoginPartial"/>

Now, you should be able to see Login and Register options in the right-side menu when running the project.

Add the following line in the Program.cs.
app.MapRazorPages();

Now, you will have to add migration to the database; go to "Tools", click on "NuGet Package Manager" and then on "Package Manager Console", the package manager console will open.

In the console, run the following commands.
add-migration "Identity tables migration"
Update-database

Here, a new migration file will be added to the Migration folder, and necessary tables are added to the database.

Step 10. Create a new account

Run the project and click on register to register users. A Register page will open like the one below.

Here, you can register users by filling in the fields given.

But, if you click on Sales Lead, you will see you can still access the sales lead page without logging. So, to prevent this, follow the next step.

Step 11. Adding security

Go to "LeadsController.cs"  and add attribute [Authorize] at the controller level.
namespace CRMApp.Controllers
{
    [Authorize]
    public class LeadsController : Controller
    {
       ...
    }
}


Now, if you will open the application and click on Sales Lead, you will see that you cannot access the page without logging in yourself. A page for login will open for you, as shown below.

Once you log in yourself using the email and password. You will be able to access the Index page with Sales Lead Details. Also, you will have options to edit, get details and delete the records.

Here, you can see the details.


As you have seen, we have successfully added authentication to our ASP. NET 6 projects using the Identity Service.

Conclusion

ASP.NET Core Identity is a powerful tool for implementing user authentication and authorization in ASP.NET Core applications. By leveraging its features, developers can easily incorporate secure and scalable authentication mechanisms into their web applications, enhancing overall security and user trust. ASP.NET Core Identity simplifies the process of managing user accounts, passwords, and roles, allowing developers to focus on the core functionality of their applications. With its seamless integration with ASP.NET Core MVC, developers can create robust user management functionality and ensure that only authorized users can access specific resources or functionalities within the application.

By following the steps outlined in this article, developers can successfully set up ASP.NET Core Identity in their projects and enjoy the benefits of a secure and efficient authentication system.



ASP.NET MVC 6 Hosting - HostForLIFE :: How to Redirect the Desired Web Page in ASP.Net Core MVC?

clock July 3, 2023 10:10 by author Peter

ASP.NET Core MVC is a framework used to develop web applications, also used for building modern and dynamic web applications. It is developed to run on multiple environments like Windows, Linux, and macOS. These operating systems provide a rich set of features that make it easy to build and deploy web applications. Some of the key features of ASP.NET Core MVC include dependency injection, routing, model binding, validation, and Razor views for building UI. It also provides support for building RESTful APIs, where developers can create scalable and flexible web applications.

The main problem arises when we want to redirect to the page which we want to occur when we perform any specific event or action like submitting the form or login into the application but by default, it reloads and shows the same page again, and if we want to redirect into the desired page where it is showing the actual updated record, then we can use redirectToAction("page name")method.

How to use the redirectToAction() method?
The redirectToAction() method is used in frameworks like ASP.NET and ASP.NET Core. This method is used to redirect from one web page to the desired page. The RedirectToAction() method is part of the Controller class, which is used to handle incoming HTTP requests. The method takes one or more parameters to specify the action and controller to redirect to.

Here's an example to demonstrate the usage of the RedirectToAction() method in ASP.NET MVC.

Let's say you have a controller named HomeController with two action methods: Index() and About(). The Index() action method displays the home page, and the About() action method displays information about the website.
using System.Web.Mvc;

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    public ActionResult About()
    {
        return View();
    }
}


Let's assume that you want to redirect the user from the Index() action method to the About() action method when a certain condition is met. You can achieve this using the RedirectToAction() method.
public class HomeController : Controller
{
    public ActionResult Index()
    {
        if (/* check condition */) // Replace this with your condition
        {
            return RedirectToAction("About");
        }
        return View();
    }
    public ActionResult About()
    {
        return View();
    }
}

In the example above, if the condition inside the Index() action method evaluates to true, the RedirectToAction() method is called with the parameter "About". This redirects the user to the About() action method, and the associated view is rendered.

The RedirectToAction()  method can also accept additional parameters to pass data between actions. For example

return RedirectToAction("About", new { id = 123 });

In this case, the About() action method can receive the id parameter to perform further processing.

The RedirectToAction() method in ASP.NET is used to redirect users from one action method to another within the same or different controller. It is commonly used in MVC applications for navigation and routing purposes. Using this method, you can control the flow of your application and redirect users based on specific conditions or events.
FAQ'S

Q1. What's the difference between RedirectToAction() and Redirect() methods?
A. The RedirectToAction() method is used to redirect users to another action method within the application, while the Redirect() method is used to redirect users to a different URL or external website.

Q2. Can I redirect to an action method in a different controller?
A. Yes, you can use the RedirectToAction() method to redirect to an action method in a different controller by specifying the controller name as a parameter.

Q3. Is it possible to redirect to an external URL using RedirectToAction()
A. No, the RedirectToAction() method is specifically designed for redirecting within the application. If you need to redirect to an external URL, you should use the Redirect() method and provide the URL as a parameter.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Consuming Services in ASP.NET Core MVC Controller

clock June 23, 2023 12:21 by author Peter

Another interesting feature of ASP.NET Core is service consumption using Dependency Injection. I already provided the overview of Dependency Injection in my earlier articles. Moving further, in this article we will see how one can inject and consume services to controller using dependency injection.

In ASP.NET, you can access services at any stage of your HTTP pipeline through dependency injection. By default, it provides Constructor injection, but it can easily be replaced by any other container of your choice. Before moving ahead, one point is very important to understand and that is lifetime of services.
ASP.NET  Core allows you to configure four different lifetimes for your services.

  • Transient - Created on every request.
  • Scoped - Created once per request.
  • Singleton - Created first time when they are requested.
  • Instance - Created in ConfigureServices method and behaves like a Singleton.

To understand the service consumption inan easier way, we will create a sample application going step-by-step. My example service will provide GUID to the respective controller. So, let's start quickly.

Create a new project - Create a new project using ASP.NET Web Application template as shown below:



Add Service Interface - Create an interface named IGUIDService under Services folder as shown below:
public interface IGUIDService
{
    string GenerateGUID();
}

Add Service Implementation - Create a class named GUIDServiceunder Services folder and provide the implementation of IGUIDService interface as shown below:
public class GUIDService : IGUIDService
{
    public string GenerateGUID()
    {
        return ("Generated GUID is: " + Guid.NewGuid()).ToString();
    }
}

Add a Controller - Next task is to add a Controller namedGUIDController by right clicking on Controllers folder as shown below:

Add a View - Before adding a View, create a folder named under Views folder. Now add a View by right clicking on GUID folder as shown:

Update the code inside View as shown below:

Use Service in Controller - Now instantiate the service and set the data for View as shown below:
public class GUIDController : Controller
{
    private IGUIDService _guidService;

    public GUIDController(IGUIDService guidService)
    {
        _guidService = guidService;
    }
    public IActionResult Index()
    {
        ViewData["GeneratedGUID"] = _guidService.GenerateGUID();
        return View();
    }
}


Register Service - Last step is to register the service in the ConfigureServices method of Startup class as shown below:
public void ConfigureServices(IServiceCollection services)
{
    ...
    ...
    services.AddMvc();
    services.AddInstance<IGUIDService>(new GUIDService());
}

Everything is set. Now run your application and you would be able to see GUID on browser as:

Hope you got an idea on how to inject services in ASP.NET Core 1.0.



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