Author: seun4talk

Web API that returns data to different sets of client based on the agreement with the organization.

This issue arose when I got a requirement in office to build API for clients but a tricky one indeed as my philosophy is to always build systems that are highly configurable rather than a system that is subject to code changes every time a new requirement arises.

Hence I took my time to analyze and plan carefully how to come up with a system that can handle the scenario on the ground.

The problem statement is to build a web API that will be used by the various client but each of them requires a different level of data exposure.

Imagine a system to display customer information but the business team has decided that data expose to the client should be based on an agreement signed eg.
Client A can get [Name,Age,Sex] , Client B can get [Name,Age] only , Client C can get [Name] only.

Let us get into the raw action.

First, let us create a sample repository

public class DataRepository
    {
        public static IList<Data> GetData()
        {
            return new List<Data>()
            {
                new Data(){ Age = 45, Sex = "Male" , Name = "Adeyinka Oluwaseun", PhoneNumber = "1111"},
                new Data(){ Age = 23, Sex = "Female" , Name = "Doyin Solomon", PhoneNumber = "2222"},
                new Data(){ Age = 56, Sex = "Male" , Name = "John Doe", PhoneNumber = "3333"},
            };
        }
    }

    public class Data
    {
        public string Name { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
        public string PhoneNumber { get; set; }
    }

Next is to create our custom response class which is a dictionary with an indexer to store the retrieved information from our repository.

public class Response
    {
        private readonly Dictionary<string, string> _store;

        public Response()
        {
            _store = new Dictionary<string, string>();
        }

        public string this[string key]
        {
            get => _store[key];
            set => _store[key] = value;
        }

        public Dictionary<string, string> Get()
        {
            return _store;
        }
    }

Next is to configure the clients in the appsettings.json where will configure the clients and the data that will be available to them based on the business agreement signed.

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Clients": {
    "Banks": "CLIENTA:Name,Sex|CLIENTB:Name|CLIENTC:Name,Age,Sex"
  } 
}

Next is our controller class

[Route("api/[controller]")]
    public class InformationController : Controller
    {
        private static Clients _clients;

        public InformationController(IOptions<Clients> clients)
        {
            _clients = clients.Value;
        }

        [HttpGet()]
        public IActionResult Get([FromQuery]string number , [FromQuery]string clientName)
        {
            var response = new Response();

            foreach (var info in ClientData())
            {
                if (info.Key == clientName)
                {
                    var props = info.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    var result = DataRepository.GetData().FirstOrDefault(c => c.PhoneNumber == number);

                    foreach (var prop in props)
                    {
                        if (result != null)
                        {
                            response[prop] = GetPropertyValue(result, prop);
                        }
                    }
                }
            }

            
            return new ObjectResult(JsonConvert.SerializeObject(response.Get(), Formatting.Indented));
        }

        private static Dictionary<string, string> ClientData()
        {

            var clients = _clients.Banks.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            var clientInfo = new Dictionary<string, string>();

            foreach (var client in clients)
            {
                var split = client.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                clientInfo.Add(split.First(), split.Last());
            }

            return clientInfo;
        }

        private static string GetPropertyValue(Data.Data data, string property)
        {
            return data.GetType().GetProperty(property)?.GetValue(data, null).ToString() ?? string.Empty;
        }
    }

The model to bind to the appsettings.json

public class Clients
    {
        public string Banks { get; set; }
    }

Finally in the startup.cs where we bind the Clients in the appsettings.json to the Model class ie. Clients

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.Configure<Clients>(settings => Configuration.GetSection("Clients").Bind(settings));

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

Result screenshot from the test created out on different clients using POSTMAN.

CLIENT A

Client A

CLIENT C

Client C

CLIENT B

Cleint B

CLICK TO DOWNLOAD SOURCE CODE FROM GITHUB

Advertisements

Filter Table or List Result In VueJs

In Vuejs 1 , there was an inbuilt filter to filter table result using filterBy but in Vuejs 2 it was deprecated.

Hence you need to write your own custom query to achieve same result.

This tutorial will show you how to achieve same.

The application server is written in nodejs , express as the web framework and vash as the template engine.

I will be using a fake an API from https://jsonplaceholder.typicode.com/users

This is the nodejs server code

var express = require("express");
var app = express();

var port = process.env.PORT || 3000;

app.use("/assets", express.static(__dirname + "/public"));

app.set("view engine", "vash");

app.get("/", (req, res) => {
  res.render("index");
});

app.listen(port);

Next is the View i.e the html to display our data and provide search.

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" media="screen"
/>
<div class="container">
    <h1>Filter Todo Table By Search in VueJs
        <small>(
            <i class="glyphicon glyphicon-filter"></i>)</small>
    </h1>
    <div class="row">
        <div class="col-md-6" id="todo"> 
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">TODOS</h3> 
                   
                </div>
                <div class="panel-body">
                    <input type="text" class="form-control" placeholder="search" v-model="search"/>
                </div>
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>Name</th>
                            <th>UserName</th>
                            <th>Email</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(item,index) in computedData" :key="item.id">
                            <td>{{ ++index }}</td>
                            <td>{{ item.name }}</td>
                            <td>{{ item.username }}</td>
                            <td>{{ item.email }}</td>
                        </tr>

                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue"></script>  
<script src="/assets/data.js"></script>

Finally , the Vuejs code

var app = new Vue({
  el: "#todo",
  data: {
    todos: [],
    search:'',
    computedTodos:[]
  },
  mounted() {
    loadAll: {
      axios
        .get("https://jsonplaceholder.typicode.com/users") 
        .then(response => {
          this.todos = response.data;
        })
        .catch(function(error) {});
    }
  },
  computed: {
    computedData: function() { 
      this.computedTodos = this.todos;  
      if (this.search) {
        this.computedTodos = this.computedTodos.filter(item => item.name.toUpperCase().includes(this.search.toUpperCase()) || item.username.toUpperCase().includes(this.search.toUpperCase()) || item.email.toUpperCase().includes(this.search.toUpperCase()));   
        return this.computedTodos;
      }
      return this.computedTodos;
    }
  }  
});

Snapshot of the html table.

total

Search for BRET
search

Source on my github page

 

Post data from VueJs to ASP.NET CORE using Axios

As simple as this sounds , if you do not get it right then you can spend days trying to figure out why the data you post from Vuejs doesn’t get the ASPNET CORE controller action.

This was my scenario until i finally got it right.

First , what is Vuejs ?

According to wikipedia , Vue.js is a popular JavaScript front-end framework that was built to organize and simplify web development.

Secondly , what is Axios ?

Axios  is a javascript library for Promise based HTTP client for the browser and node.js

I spents hours trying to figure out why data i post from Vuejs doesn’t get to my Controller action in asp.net core until i figured out that for this to work then i need to set [FromBody] attribute on my action.

Let us see sample scenario

This is my View : Index.cshtml

@{
    ViewData["Title"] = "Home Page";
}

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Vue To .NET CORE</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>

<body>

<div id="app">
   
    <input name="firstName" v-model="firstName" placeholder="First Name"/>
    <br/>
    <input name="lastName" v-model="lastName" placeholder="Last Name"/>
    <br/>
    <button v-on:click="sendToServer">Submit</button>

</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="/app/app.js"></script>

I added the Vuejs and Axios library via CDN.

Next is my Vuejs code

new Vue({

    el: "#app",
    data: {
        firstName: "",
        lastName: ""
    },
    methods: {
        sendToServer: function () {

            axios({
                    method: 'post',
                    url: '/home/index',
                    data: {
                        "firstName": this.firstName,
                        "lastName": this.lastName
                    }
                })
                .then(function (response) {
                    console.log(response);
                })
                .catch(function (error) {
                    console.log(error);
                });

        }
    }

});

The ViewModel 

namespace VueJsToNetCore.ViewModel
{
    public class User
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
    }
}

And lastly is my AspNet Core Controller.

using Microsoft.AspNetCore.Mvc;
using VueJsToNetCore.ViewModel;

namespace VueJsToNetCore.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Index([FromBody]User user)
        {
            return View();
        }
    }
}

NOTE : If you post without the [FromBody] attribute on the Controller Action then the posted parameters will not get to the action.

Page

pagecode

 

Source code available on my github page.

 

Make WebService Calls in ASP.NET CORE

Moving to ASP.NET Core is fun and interesting but then you begin to fall into problems trying to do some stuffs you use to do easily in ASP.NET MVC.

One of such is trying to make a call to a webservice but then where is the WEB.CONFIG xml file that keeps webservices configurations ? It is no more in ASP.NET CORE what we have now is the APPSETTINGS which is a json file. Hmmmmm……………..

In this post i will show how you can make webservice calls easily.

In order to use a webservice , i went online to get a free webservice from http://www.dneonline.com/calculator.asmx , this service has 4 simple operations which are Add , Divide , Multiply , Substract.

In this demo i will use the ADD method/operation which basically adds 2 numbers together. With this sample in this tutorial you can basically call any webservice after going through this tutorial.

The first thing we are going to do is a generate a proxy class for the webservice in our code using the in-built SVCUTIL.EXE command in the Visual Studio Command Prompt

Svc

This will automatically generate a proxy class and output.xml file but in this case we don’t need the output.xml in our code.

Svc Generated

Simply copy this generated .cs file into your code. For this service this is the generated .cs code. Note this is auto-generated by the VS Command Prompt using command above.

//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="CalculatorSoap")]
public interface CalculatorSoap
{
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Add", ReplyAction="*")]
    int Add(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Add", ReplyAction="*")]
    System.Threading.Tasks.Task<int> AddAsync(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Subtract", ReplyAction="*")]
    int Subtract(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Subtract", ReplyAction="*")]
    System.Threading.Tasks.Task<int> SubtractAsync(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Multiply", ReplyAction="*")]
    int Multiply(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Multiply", ReplyAction="*")]
    System.Threading.Tasks.Task<int> MultiplyAsync(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Divide", ReplyAction="*")]
    int Divide(int intA, int intB);
    
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/Divide", ReplyAction="*")]
    System.Threading.Tasks.Task<int> DivideAsync(int intA, int intB);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface CalculatorSoapChannel : CalculatorSoap, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class CalculatorSoapClient : System.ServiceModel.ClientBase<CalculatorSoap>, CalculatorSoap
{
    
    public CalculatorSoapClient()
    {
    }
    
    public CalculatorSoapClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
    {
    }
    
    public CalculatorSoapClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public CalculatorSoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public CalculatorSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
    {
    }
    
    public int Add(int intA, int intB)
    {
        return base.Channel.Add(intA, intB);
    }
    
    public System.Threading.Tasks.Task<int> AddAsync(int intA, int intB)
    {
        return base.Channel.AddAsync(intA, intB);
    }
    
    public int Subtract(int intA, int intB)
    {
        return base.Channel.Subtract(intA, intB);
    }
    
    public System.Threading.Tasks.Task<int> SubtractAsync(int intA, int intB)
    {
        return base.Channel.SubtractAsync(intA, intB);
    }
    
    public int Multiply(int intA, int intB)
    {
        return base.Channel.Multiply(intA, intB);
    }
    
    public System.Threading.Tasks.Task<int> MultiplyAsync(int intA, int intB)
    {
        return base.Channel.MultiplyAsync(intA, intB);
    }
    
    public int Divide(int intA, int intB)
    {
        return base.Channel.Divide(intA, intB);
    }
    
    public System.Threading.Tasks.Task<int> DivideAsync(int intA, int intB)
    {
        return base.Channel.DivideAsync(intA, intB);
    }
}

 

Next , is to add this class file which i call my GenericProxy class that i use to make calls to any webservice class in my codes.  It is a generic class so it is highly re-usable.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading.Tasks;

namespace CallWebService.Core
{
    internal sealed class GenericProxy<TContract> : IDisposable where TContract : class
    {
        private readonly ChannelFactory<TContract> _channelFactory;
        private TContract _channel;

        public GenericProxy(Binding binding, EndpointAddress remoteAddress)
        {
            _channelFactory = new ChannelFactory<TContract>(binding, remoteAddress);
        }

        public void Execute(Action<TContract> action)
        {
            action.Invoke(Channel);
        }

        public TResult Execute<TResult>(Func<TContract, TResult> function)
        {
            return function.Invoke(Channel);
        }

        private TContract Channel
        {
            get
            {
                if (_channel == null)
                {
                    _channel = _channelFactory.CreateChannel();
                }

                return _channel;
            }
        }

        public void Dispose()
        {
            try
            {
                if (_channel != null)
                {
                    var currentChannel = _channel as IClientChannel;
                    if (currentChannel != null && currentChannel.State == CommunicationState.Faulted)
                    {
                        currentChannel.Abort();
                    }
                    else
                    {
                        currentChannel?.Close();
                    }
                }
            }
            finally
            {
                _channel = null;
                GC.SuppressFinalize(this);
            }
        }
    }
}

 

Now all setup is ready , we are now ready to write our codes.

Add an interface for our calculator which i call ICALCULATOR service.

namespace CallWebService.Core
{
    public interface ICalculatorService
    {
        int Sum(int a, int b);
    }
}


Next is the CalculatorService which implements the ICalculator interface above and also call the ADD method/operation in the webservice , we need to pass the interface of the webservice to the GenericProxy class with the Binding settings and the EndPoint of the service.

The EndPoint of the webservice is stored in our appsettings.json which i will call with a class i call Configurations

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using Serilog;

namespace CallWebService.Core
{
    public class CalculatorService : ICalculatorService
    {
        private static readonly EndpointAddress Endpoint = new EndpointAddress(Configurations.CalculatorServiceEndPoint);
        private static readonly BasicHttpBinding Binding = new BasicHttpBinding
        {
            MaxReceivedMessageSize = 2147483647,
            MaxBufferSize = 2147483647
        };

        public int Sum(int a, int b)
        {
            int result = 0;
            using (var proxy = new GenericProxy<CalculatorSoap>(Binding, Endpoint))
            {
                try
                {
                    result = proxy.Execute(c => c.Add(a, b));
                }
                catch (FaultException ex)
                {
                    Log.Logger.Error(ex, "error while adding numbers.");

                }
                catch (Exception ex)
                {
                    Log.Logger.Error(ex, "error while adding numbers.");
                }

                return result;
            }

        }

    }
}

Configurations Class

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.IO;

namespace CallWebService.Core
{
    public static class Configurations
    {
        private static readonly IConfigurationRoot Configuration = new BootStrap().Setup();

        public static readonly string CalculatorServiceEndPoint = Configuration["WebService:CalculatorEndPoint"];

        private class BootStrap
        {
            public IConfigurationRoot Setup()
            {
                IHostingEnvironment environment = new HostingEnvironment();

                // Enable to app to read json setting files
                var builder = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true)
                    .AddEnvironmentVariables();

                if (environment.IsDevelopment())
                {
                    // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
                    builder.AddApplicationInsightsSettings(developerMode: true);
                }

                return builder.Build();
            }
        }
    }
}

 

AppSettings.json

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "WebService": {
    "CalculatorEndPoint": "http://www.dneonline.com/calculator.asmx?wsdl"
  } 
}

At this stage we are done with all we need  to do to call our webservice in our library project above , next is to move to the ASP.NET CORE project , in the Startup.cs we need to register our ICalculatorService dependency as below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using CallWebService.Core;

namespace CallWebService
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            services.AddTransient<ICalculatorService, CalculatorService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

 

For testing purpose we will be calling the webservice in our HomeController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CallWebService.Core;
using Microsoft.AspNetCore.Mvc;

namespace CallWebService.Controllers
{
    public class HomeController : Controller
    {
        private readonly ICalculatorService _calculatorService;

        public HomeController(ICalculatorService calculatorService)
        {
            _calculatorService = calculatorService;
        }

        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Index(int firstNumber , int secondNumber)
        {
            var result = _calculatorService.Add(firstNumber, secondNumber);
            ViewBag.Result = $"{firstNumber} + {secondNumber} = {result}";
            return View();
        }
    }
}

Index.cshtml for the Index view in the HomeController

@{
    ViewData["Title"] = "Home Page";
}

<form asp-controller="Home" asp-action="Index" method="post">
    <div class="row">
        <div class="col-md-6">
            <input type="text" name="firstNumber" />
        </div>
        <br />
        <div class="col-md-6">
            <input type="text" name="secondNumber" />
        </div>
        <br />
        <input type="submit" value="Add Numbers" />
        <br/>
        @ViewBag.Result 
    </div>
</form>

sunm

ans


Finally , we have our result from the webservice.

The complete source code is available on my my github repo for download.

NOTE : You can only run it with VISUAL STUDIO 2017.

SweetAlert Notification in ASP.NET MVC & ASP.NET CORE

I got a requirement in an application to display notification messages as beautiful pop-ups instead of plain text on the web page.

Note , this is not a toastr kind of notification , it is the normal javascript alert notification.

A quick search and i got hold of this beautiful alert project by Tristan Edwards called SweetAlert

I thought well about this and also how i need to implement it to make it re-usable and available in all my Controller without doing too much frontend implementation of it.

Hence , i had to come up with a BaseController which all other controllers will simply inherit  from.

BASECONTROLLER DESIGN

    public abstract class BaseController : Controller
    {
       
        public void Alert(string message , NotificationType notificationType)
        {
           var msg = "swal('" + notificationType.ToString().ToUpper() + "', '"+ message +"','"+ notificationType+"')" + "";
           TempData["notification"] = msg;
        }
    }

Then a sample controller that inherit from the BASECONTROLLER above.

public class TestController : BaseController
 {
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }
    }
}

Since this TESTCONTROLLER inherits from the BASECONTROLLER , i therefore have access to the Alert method in the BASECONTROLLER.

The alert has icons that depict the kind of alert i want to use i.e error notification , success notification , warning notification and info notification

Hence the need for an enum , so i create the enum class below , which already appeared in the BASECONTROLLER above.

   public class Enum
    {
        public enum NotificationType
        {
            error,
            success,
            warning,
            info
        }

    }

With completely re-usability in mind , let us create a partial view that will display the alert notification passed into TempData[“notification”] = msg; in the BASECONTROLLER  above.

So let us create a partial view called _NotificationPanel.cshtml file which we will call in the _Layout.cshtml file in the Views/Shared folder

@if (TempData["notification"] != null)
{
    @Html.Raw(TempData["notification"])
}

Then in the _Layout.cshtml we make the _NotifcationPanel.cshtml available like this

@Html.Partial(“_NotificationPanel”)

@RenderBody()

Also , we need to add the css and javascript we got from SweetAlert to the  HEAD section of the _Layout.cshtml file

<link href=”/sweetAlert/sweetalert.css” rel=”stylesheet” />
/sweetAlert/sweetalert.min.js

Finally note that the view of our TESTCONTROLLER above need to use the _Layout as it’s Layout , so our TESTCONTROLLER view page needs to look like this

@{
    ViewBag.Title = "title";
    Layout = "_Layout";
}

Now we are set for use. So let us create sample for all the SWEETALERT notification types.

For Success Messages :

Our TESTCONTROLLER will be :

For Success Messages :

   public class TestController : BaseController
    {
        [HttpGet]
        public IActionResult Index()
        {          
            Alert("This is success message",NotificationType.success);
            return View();
        }
    }

With the help of our enum class we can choose any kind of message we want.

Source code available on my github repo.

Thanks…please do leave your comments below.