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 :: Learn About Filters In ASP.NET MVC

clock December 30, 2020 12:17 by author Peter

As part of this article, we will learn about ASP.Net MVC filters, their different types and we will create a custom log Action Filter using Visual Studio. So without wasting any time let's start.

What are ASP.Net MVC filters
In an ASP.Net MVC Web application, we have action methods defined in controllers that call from different views. For example, when the user clicks on some button on the view, a request goes to the designated controller and then the corresponding action method. Within this flow, sometimes we want to perform logic either before an action method is called or after an action method runs.
 
To fulfill the above condition ASP.Net MVC provides us filters. Filters are the custom classes that provide us with an option to add pre-action and post-action behavior to controller action methods.
 
ASP.NET MVC framework supports four different types of filters:

  • Authorization filters
  • Action filters
  • Result filters
  • Exception filters

Note
They are executed in the order listed above.
 
Authorization filters
In ASP.NET MVC web application by default, all the action methods of all the controllers can be accessible for all the users (for both authenticated and anonymous users both). For this, if we want to restrict some action methods from anonymous users or we want to allow the action methods only to an authenticated user, then you need to use the Authorization Filter in MVC.
 
The Authorization Filter provides two built-in attributes such as Authorize and AllowAnonymous. We can decorate our action methods with the Authorize attribute which allows access to the only authenticated user and we can use AllowAnonymous attribute to allow some action method to all users.
 
We can also create custom Authorization filters for this we have to implement IAuthenticationFilter interface and have overrides its OnAuthentication() and OnAuthenticationChallenge(). We are going deep into it.
 
Action filters
In the ASP.NET MVC web application, action filters are used to perform some logic before and after action methods. The output cache is one of the built-in action filters which we can use in our action methods.
    [OutputCache(Duration=100)]
    public ActionResult Index()
    {
       return View();
    }

We can also create a custom action filter either by implementing IActionFilter interface and FilterAttribute class or by deriving the ActionFilterAttribute abstract class. As part of this article, I am covering creating a custom action filter using the ActionFilterAttribute abstract class.
 
ActionFilterAttribute includes the following method to override it:
    void OnActionExecuted(ActionExecutedContext filterContext)
    void OnActionExecuting(ActionExecutingContext filterContext)
    void OnResultExecuted(ResultExecutedContext filterContext)
    void OnResultExecuting(ResultExecutingContext filterContext)

We will see this in detail below.
 
Result filters
 
In an ASP.NET MVC web application, result filters are used to perform some logic before and after a view result is executed. For example, we might want to modify a view result right before the view is rendered.
 
Exception filters
 
In the ASP.NET MVC web application, we can use an exception filter to handle errors raised by either our controller actions or controller action results. We also can use exception filters to log errors.
 
Creating a Log Action Filter
Open Visual Studio and create a new ASP.NET Web Application

Choose Empty, select “MVC” and then click the OK button.

Add a ‘Filters’ folder and create a new class LogActionFilter.cs under it:
    using System.Diagnostics;  
    using System.Web.Mvc;  
    using System.Web.Routing;  
      
    namespace FiltersMVC.Filters  
    {  
        public class LogActionFilter : ActionFilterAttribute  
      
        {  
            public override void OnActionExecuting(ActionExecutingContext filterContext)  
            {  
                Log("OnActionExecuting", filterContext.RouteData);  
            }  
      
            public override void OnActionExecuted(ActionExecutedContext filterContext)  
            {  
                Log("OnActionExecuted", filterContext.RouteData);  
            }  
      
            public override void OnResultExecuting(ResultExecutingContext filterContext)  
            {  
                Log("OnResultExecuting", filterContext.RouteData);  
            }  
      
            public override void OnResultExecuted(ResultExecutedContext filterContext)  
            {  
                Log("OnResultExecuted", filterContext.RouteData);  
            }  
      
      
            private void Log(string methodName, RouteData routeData)  
            {  
                var controllerName = routeData.Values["controller"];  
                var actionName = routeData.Values["action"];  
                var message = $"{methodName} controller:{controllerName} action:{actionName}";  
                Debug.WriteLine(message, "Action Filter Log");  
            }  
        }  
    }  


We overrides OnActionExecuting(), OnActionExecuted(), OnResultExecuting(), and OnResultExecuted() methods all are calling the Log() method. The name of the method and the current route data is passed to the Log() method. The Log() method writes a message to the Visual Studio Output window.
 
Now, add HomeController.cs under the Controllers folder.
    using FiltersMVC.Filters;  
    using System.Web.Mvc;  
      
    namespace FiltersMVC.Controllers  
    {  
        [LogActionFilter]  
        public class HomeController : Controller  
        {  
            // GET: Home  
            public ActionResult Index()  
            {  
                return View();  
            }  
        }  
    }  

After adding the above files our folder structure will look like this:


Now run the application, we can see the results in the “Output” window.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Ajax.ActionLink and Html.ActionLink in MVC

clock December 16, 2020 08:26 by author Peter

In this article, you will learn the use of the Ajax.ActionLink helper and Html.ActionLink. I will compare both to show you how they differ. Okay, let's begin with Html.ActionLink.

Html.ActionLink
Html.ActionLink creates a hyperlink on a view page and the user clicks it to navigate to a new URL. It does not link to a view directly, rather it links to a controller's action. Here are some samples of Html.ActionLink.
 
If you want to navigate to the same controller's action method, use the one given below. Razor is smart enough to assume the first param is link text and the second param is the action method name, if it finds only two parameters.
    @Html.ActionLink("Click here", // <-- Link text  
                     "Index" // <-- Action Method Name  
                     )  

It's rendered HTML: <a href="/">Click here</a>
 
If you want to navigate to a different controller's action method, use the one given below. You can even avoid typing "null" for the route value and htmlArguments. Here also, razor will assume the first param as link text, the second param as the action method name and the third param as the controller name, if it finds three parameters.
    @Html.ActionLink("Click here", // <-- Link text  
                     "About", // <-- Action Method Name  
                     "Home", // <-- Controller Name  
                     null, // <-- Route value  
                     null // <-- htmlArguments  
                     )  


It's rendered HTML: <a href="/Home/About">Click here</a>
 
If you want to navigate to the same controller's action method then use the one given below. Here razor will assume the first param is link text, second param is an action method and the third param is the route value. We can avoid typing "null" for the htmlArgument; that works fine.
    @Html.ActionLink("Edit", // <-- Link text  
                     "Edit", // <-- Action Method Name  
                     new { id=item.CustomerID }, // <-- Route value  
                     null // <-- htmlArguments  
                    )  


It's rendered HTML: <a href="/Home/Edit/187">Edit</a>
 
If you want to navigate to the same controller's action method then use the one given below. Here razor will assume the first param is link text, second param is the action method and the third param is the route value. Instead of typing "null" or avoiding the htmlAttribute, I am using the "class" attribute with "ui-btn" as the name.
    @Html.ActionLink("Edit", // <-- Link text  
                     "Edit", // <-- Action Method Name  
                     new { id=item.CustomerID }, // <-- Route value  
                     new {@class="ui-btn"} // <-- htmlArguments  
                    )  

It's rendered HTML: <a class="ui-btn" href="/Home/Edit/187">Edit</a>
 
What if one wants rendered HTML to be as given below that is an application-specific anonymous attribute:
<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>
 
If you try to do it as given below, you will get the error:

The reason is that we can't use an anonymous property/attribute having a dash in the name. Use an underscore instead of a dash and MVC will automatically replace the underscore with a dash in the rendered HTML, here it is:
    @Html.ActionLink("Edit", // <-- Link text  
                     "Edit", // <-- Action Method Name  
                     new { id=item.CustomerID }, // <-- Route arguments  
                     new {@class="ui-btn", data_val="abc"} // <-- htmlArguments  
                    )  

That's how we work around in MVC for any anonymous property.
 
Note: You can notice that Html.ActionLink takes at least two parameters as Html.ActionLink(LinkText, ActionMethod).
 
Ajax.ActionLink

Ajax.ActionLink is much like the Html.ActionLink counterpart, it also creates the hyperlink <a href="">Click here</a> but when the user clicks it and has a JavaScript enabled browser, Ajax.ActionLink sends the asynchronous request instead of navigating to the new URL. With the Ajax.ActionLink we specify what controller's action method is to be invoked and also specify what to do with the response coming back from the action method.
 
Let's create an Ajax.ActionLink helper that will send an asynchronous request to the action method and will update the DOM with the result.
 
Step 1
At first we need an Ajax.ActionLink that will send the async request, so here we go:
    <h2>Customers</h2>  
    @Ajax.ActionLink("Customer from Germany", // <-- Text to display  
                     "Germany", // <-- Action Method Name  
                     new AjaxOptions  
                     {  
                         UpdateTargetId="CustomerList", // <-- DOM element ID to update  
                         InsertionMode = InsertionMode.Replace, // <-- Replace the content of DOM element  
                         HttpMethod = "GET" // <-- HTTP method  
                     })  
    @Ajax.ActionLink("Customer from Mexico", // <-- Text to display  
                     "Mexico", // <-- Action Method Name  
                     new AjaxOptions  
                     {  
                         UpdateTargetId="CustomerList", // <-- DOM element ID to update  
                         InsertionMode = InsertionMode.Replace, // <-- Replace the content of DOM element  
                         HttpMethod = "GET" // <-- HTTP method  
                     })  
    <div id="CustomerList"></div>  
    @section scripts{  
        @Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")  
    }  


In the code above, you can see that I have created two Ajax.ActionLinks, one to display the list of customers from Germany and another to display the list of customers from Mexico, all will be called asynchronously. We have not specified which controller to access, so by default it will look in the same controller. Here is the generated HTML by both Ajax.ActionLink.
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Germany">Customer from Germany</a>
 
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Mexico">Customer from Mexico</a>
 

The unobtrusive jQuery uses the data-ajax prefix for JavaScript to invoke action methods on the server rather than intrusively emitting inline client scripts.
 
When we will click the link it will make a GET HTTP method call and the returned result will be updated to a DOM element by Id "CustomerList".
 
Always remember to place a reference of the jquery.unobtrusive-ajax.js library file after jquery-{version}.js file references, we can use bundling also. If you don't include the jquery.unobtrusive-ajax.js or do it incorrectly, then when you click the link to the view list of countries, an async result will be opened on the new browser tab.
 
Also, ensure that the unobtrusive JavaScript is enabled in your web.config (it should be by default).
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />  

Step 2
Now, let's go ahead and implement the "Germany" and "Mexico" action methods that will return a PartialView.
    NorthwindEntities db = new NorthwindEntities();  
    public PartialViewResult Germany()  
    {  
        var result = from r in db.Customers  
                        where r.Country == "Germany"  
                        select r;  
        return PartialView("_Country", result);  
    }  
    public PartialViewResult Mexico()  
    {  
        var result = from r in db.Customers  
                        where r.Country == "Mexico"  
                        select r;  
        return PartialView("_Country", result);  
    }  


So, in both of the PartialViewResult methods I have used a LINQ query that will filter records on country and then pass the results to a partial view page "_Country.cshtml". I have placed this file in the "Shared" folder so that any view can access it. Let's move on to see the partial view page "_Country.cshtml".
 
Step 3
I made this view page strongly typed by using @model and then iterated through the model data to create a nice tabular format.
    @model IEnumerable<MvcActionLink.Models.Customer>  
    <table>  
        <tr>  
            <th>  
                @Html.DisplayNameFor(model => model.ContactName)  
            </th>  
            <th>  
                @Html.DisplayNameFor(model => model.Address)  
            </th>  
        </tr>  
    @foreach (var item in Model) {  
        <tr>  
            <td>  
                @Html.DisplayFor(modelItem => item.ContactName)  
            </td>  
            <td>  
                @Html.DisplayFor(modelItem => item.Address)  
            </td>  
        </tr>  
    }  
    </table>  


Now, you all set to run the application.



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: Simple Insert And Select Operation Using .NET Core MVC With ADO.NET And Entity Framework Core

clock December 2, 2020 08:53 by author Peter

In this article, I am going to show you guys how to use ADO.NET and Entity framework core in .NET Core MVC. This way you can use either both or on way to implement your application as per your requirements. I attached the project solution which you can refer to. Also, I have shown a repository pattern to complete this project.

Step 1
I have used MS SQLServer for the database.
    USE [CrudDB]  
    GO  
    /****** Object: Table [dbo].[Crud_Data] Script Date: 22-11-2020 09:33:14 ******/  
    SET ANSI_NULLS ON  
    GO  
    SET QUOTED_IDENTIFIER ON  
    GO  
    CREATE TABLE [dbo].[Crud_Data](  
    [id] [int] IDENTITY(1,1) NOT NULL,  
    [Name] [varchar](50) NULL,  
    [City] [varchar](50) NULL,  
    [InsertDate] [datetime] NULL,  
    [FatherName] [varchar](50) NULL,  
    CONSTRAINT [PK_Crud_Data] PRIMARY KEY CLUSTERED  
    (  
    [id] ASC  
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]  
    ) ON [PRIMARY]  
    GO  


Step-2
Change in the startup.cs file in the project root
    public void ConfigureServices(IServiceCollection services)  
         {  
             services.AddControllersWithViews();  
             //By changing the service reference we are switching to ado.net  to entity framwork core vice versa  
             //----Start  
             services.AddScoped<ICrudRepository, CrudRepository>();  
             //services.AddScoped<ICrudRepository, CrudContextRepository>();  
             //-----End  
             services.AddDbContext<DBAccessContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyKey")));  
         }  

Step 3
Connection string in appsettings.json:
    {  
      "Logging": {  
        "LogLevel": {  
          "Default": "Information",  
          "Microsoft": "Warning",  
          "Microsoft.Hosting.Lifetime": "Information"  
        }  
      },  
      "AllowedHosts": "*",  
      "ConnectionStrings": {  
        "MyKey": "Data Source=PRO-ACQER8AM;Initial Catalog=CrudDB;Integrated Security=True;"  
      }  
    }

Step 4
Made model to communicate with View and DB Layer.
    namespace TestDemo.Models  
    {  
        [Table("Crud_Data", Schema = "dbo")]  
        public class CrudModel  
        {  
            public int Id { get; set; }  
            [Required]  
            public string Name { get; set; }  
            [Required]  
            public string City { get; set; }  
      
            public DateTime? InsertDate { get; set; }  
               
            public string? FatherName { get; set; }  
        }  
    } 

Step 5
Controller class CrudController.cs with dependency injection use with helps to lose coupling while switching from ADO.NET to Entity framework and vice-versa.
    public class CrudController : Controller  
       {  
           private readonly ICrudRepository crudRepository;  
           public CrudController(ICrudRepository crudRepository)  
           {  
               this.crudRepository = crudRepository;  
           }  
           public IActionResult Index()  
           {  
               ViewBag.ModelList = crudRepository.GetData();  
               return View();  
           }  
           [HttpPost]  
           public IActionResult Index(CrudModel crudModel)  
           {  
               try  
               {  
                   if (ModelState.IsValid)  
                   {  
                       // ICrudRepository crudRepository = new CrudRepository();  
                       var result = crudRepository.insert(new string[] { crudModel.Name, crudModel.City, System.DateTime.Now.ToString(), crudModel.FatherName });  
                       ViewBag.ModelList = crudRepository.GetData();  
                       if (result)  
                       {  
                           ViewBag.Msg = "Succeed";  
                           ViewBag.alertType = "alert alert-success";  
                       }  
                       else  
                       {  
                           ViewBag.Msg = "Insertion failed";  
                           ViewBag.alertType = "alert alert-danger";  
                       }  
      
                   }  
               }  
               catch (Exception ex)  
               {  
                   ViewBag.Msg = "Insertion failed";  
                   ViewBag.alertType = "alert alert-danger";  
                   ModelState.AddModelError("Message", ex.Message);  
               }  
      
               return View();  
      
           }  
       }

 

Step 6
The project consists of class files for the DB layer and Repository folder and one partial view for showing the detail view.
    We have created an interface in the repository folder to make a service and use both the classes as a service.
    We have created the DBLayer folder and created 2 classes one consists of ado.net insert and select the method and another one for Entity framework Core DBContext.
    In Partial View, I have injected the service directly so that you no need to pass the model to communicate with a partial view. you can check the getdata() method by debugging and uncommenting the specific section over there.
    System.Data.sqlclient reference required to use ado.net, you can add this by using NuGet package manager.

DataAccessDB.cs
    public class DataAccessDB : IDataAccessDB  
       {  
           private readonly IConfiguration config;  
           string connsString = string.Empty;  
           public DataAccessDB(IConfiguration config)  
           {  
               this.config = config;  
               connsString = config.GetConnectionString("MyKey");  
           }  
           public List<CrudModel> GetData()  
           {  
               // string connsString = config.GetConnectionString("MyKey");// "Data Source=PRO-ACQER8AM;Initial Catalog=CrudDB;Integrated Security=True;";  
               List<TestDemo.Models.CrudModel> ModelList = new List<Models.CrudModel>();  
               using (SqlConnection conn = new SqlConnection(connsString))  
               {  
                   conn.Open();  
                   using (SqlCommand command = new SqlCommand($"select * from [dbo].[Crud_Data]", conn))  
                   {  
                       try  
                       {  
                           using (var result = command.ExecuteReader())  
                           {  
      
                               while (result.Read())  
                               {  
      
                                   ModelList.Add(  
                                       new Models.CrudModel { Id = (int)result.GetValue("Id"), Name = (string)result.GetValue("Name"), City = (string)result.GetValue("City"),  FatherName = (string)result.GetValue("FatherName").ToString() });  
                               }  
                           }  
                       }  
                       catch (Exception ex)  
                       {  
      
                       }  
                       finally  
                       {  
                           conn.Close();  
                       }  
      
                       return ModelList;  
                   }  
      
      
               }  
           }  
      
             
      
           public bool insert(string[] Param)  
           {  
      
               //   string connsString = config.GetConnectionString("MyKey");// "Data Source=PRO-ACQER8AM;Initial Catalog=CrudDB;Integrated Security=True;";  
      
               using (SqlConnection conn = new SqlConnection(connsString))  
               {  
                   conn.Open();  
                   using (SqlCommand command = new SqlCommand($"INSERT INTO [dbo].[Crud_Data] ([Name],[City],[InsertDate],FatherName) VALUES ('{Param[0]}','{Param[1]}',getdate(),'{Param[3]}')", conn))  
                   {  
                       try  
                       {  
                           var result = command.ExecuteNonQuery();  
      
                           if (result > 0)  
                           {  
                               return true;  
                           }  
                       }  
                       catch (Exception)  
                       {  
      
                       }  
                       finally  
                       {  
                           conn.Close();  
                       }  
                       return false;  
                   }  
      
      
               }  
      
           }  
       }  


 DBAccessContext.cs
    public class DBAccessContext:DbContext  
      {  
      
          public DBAccessContext(DbContextOptions<DBAccessContext> options):base(options)  
          {   
          }  
      
          public DbSet<CrudModel> Crud_Data { get; set; }  
      
      }  


CrudRepository.cs
    public class CrudRepository : ICrudRepository  
    {  
        private readonly IConfiguration configuration;  
        private readonly DataAccessDB DB;  
      
        public CrudRepository(IConfiguration configuration)  
        {  
            this.configuration = configuration;  
            this.DB = new DataAccessDB(configuration);   
        }  
        public List<CrudModel> GetData()  
        {  
            return DB.GetData();  
        }  
      
        public bool insert(string[] Param)  
        {  
      
            return DB.insert(Param);  
      
        }  
      
      
    }  

 CrudContextRepository.cs
    public class CrudContextRepository : ICrudRepository  
       {  
           private readonly DBAccessContext dBAccessContext;  
           private readonly IConfiguration configuration;  
      
           public CrudContextRepository(DBAccessContext dBAccessContext,IConfiguration configuration)  
           {  
               this.dBAccessContext = dBAccessContext;  
               this.configuration = configuration;  
           }  
           public  List<CrudModel> GetData()  
           {  
              return dBAccessContext.Crud_Data.ToList();  
           }  
      
           public bool insert(string[] Param)  
           {  
               var model = new CrudModel()  
               {  
                   Name = Param[0],  
                   City = Param[1],  
                   InsertDate = System.DateTime.Now,  
                   FatherName= Param[3]  
      
               };  
               
            dBAccessContext.Crud_Data.Add(model);  
              var result= dBAccessContext.SaveChanges();  
      
               if (result>0)  
               {  
                   return true;  
               }       
               return false;  
           }  
       }  

 ICrudRepository.cs
    public interface ICrudRepository  
      {  
          bool insert(string[] Param);  
          List<TestDemo.Models.CrudModel> GetData();  
      
      }  


 Index.cshtml under View/Crud/
    @model TestDemo.Models.CrudModel  
      
    <partial name="_ValidationScriptsPartial" />  
    <style>  
        .bg-secondary {  
            background-color: #f4f5f7 !important;  
        }  
    </style>  
      
    <h1>Welcome to Crud</h1>  
      
    <form id="Form1" method="post" asp-action="Index" asp-controller="Crud" >  
        @if (ViewBag.Msg != null)  
        {  
      
            <div class="@ViewBag.alertType" role="alert">  
                <div asp-validation-summary="All">@ViewBag.Msg</div>  
            </div>  
            @*<script>  
                    $(function () {  
      
                        $.notify({  
                            title: "<strong>Message:</strong> ",  
                            message: "@ViewBag.Msg"  
                        });  
                    });  
      
                </script>*@  
      
            ViewBag.Msg = null;  
        }  
      
        <div class="card">  
            <div class="card-body">  
                <div class="form-group">  
                    <label asp-for="Name">Name</label>  
                    <input asp-for="Name" class="form-control">  
                    <span asp-validation-for="Name" class="text-danger"></span>  
                </div>  
                <div class="form-group">  
                    <label asp-for="City">City</label>  
                    <input asp-for="City" class="form-control" />  
                    <span asp-validation-for="City" class="text-danger"></span>  
                </div>  
                <div class="form-group">  
                    <label asp-for="FatherName">Father Name</label>  
                    <input asp-for="FatherName" class="form-control" />  
                    <span asp-validation-for="FatherName" class="text-danger"></span>  
                </div>  
            </div>  
            <div class="card-footer">  
                <button type="submit" class="btn btn-primary">Submit</button>  
            </div>  
        </div>  
      
        @{ if (ViewBag.ModelList != null)  
            { <div class="card">  
                    <div class="card-body">  
                        <partial name="_ListPartial" model="@ViewBag.ModelList" />  
                    </div>  
                </div>  
            }}  
      
        @*@await Html.PartialAsync("_ListPartial", Model)*@  
      
        @*@(await Html.RenderComponentAsync<TestDemo.Components.Component>(RenderMode.ServerPrerendered,null))*@  
      
    </form> 



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