Monday, 9 December 2013

Validate Email Address in C#

Description:

In this article, I am going to write C# code examples to Check or Validate Email Address/Email ID using Regular Expressions and C# code example to Test EMail Address is valid or not by sending Test mail.

Summary:


Validate Email Address in C# using Regular Expressions

Here, we are using Regex class to represents Regular Expressions
public static bool IsValidEmailAddressByRegex(string mailAddress)
{
    Regex mailIDPattern = new Regex(@"[\w-]+@([\w-]+\.)+[\w-]+");

    if (!string.IsNullOrEmpty(mailAddress) && mailIDPattern.IsMatch(mailAddress))
    {
        return true;
    }
    else
    {
        return false;
    }
}

Validate Email Address/Email ID in C# using Regular Expressions(2)

public static bool IsValidEmailAddressByRegex2(string mailAddress)
{
    Regex mailIDPattern = new Regex(@"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
    + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
    + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$", RegexOptions.IgnoreCase);

    if (!string.IsNullOrEmpty(mailAddress) && mailIDPattern.IsMatch(mailAddress))
    {
        return true;
    }
    else
    {
        return false;
    }
}

Validate Email Address in C# using Regular Expressions(3)

public static bool IsValidEmailAddressByRegex3(string mailAddress)
{
    Regex mailIDPattern = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);

    if (!string.IsNullOrEmpty(mailAddress) && mailIDPattern.IsMatch(mailAddress))
    {
        return true;
    }
    else
    {
        return false;
    }
}

Validate Email Address Pattern and Test Email ID is Valid or Not in C#

You can use this C# function to validate E Mail Address string pattern and to Test the given E Mail ID is Valid Address or not by sending the Test mail.
public static bool ValidateAndTestEmailAddress(string mailAddress)
{
    Regex mailIDPattern = new Regex(@"[\w-]+@([\w-]+\.)+[\w-]+");

    if (!string.IsNullOrEmpty(mailAddress) && mailIDPattern.IsMatch(mailAddress))
    {
        System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient();

        // your mail server address
        smtpClient.Host = "smtp.server1.net";

        // your mail server port address
        smtpClient.Port = 25;

        // Credentials to use mail server if required
        smtpClient.Credentials = new NetworkCredential("admin@morgantechspac.com", "yourpassword");

        try
        {
            // Send Test Mail to Check Email Address/E mail ID is Valid or Not ...

            smtpClient.Send("admin@morgantechspac.com", mailAddress, "Mail ID testing", "Validate Mail Address");

            //  Email Address was Verified!

            return true;
        }
        catch (Exception exp)
        {
            //Failed to send test mail...
            Console.WriteLine(exp.Message);
            return false;
        }
    }
    else
    {
        //Invalid email address pattern...
        return false;
    }
}

Validate Email Address Pattern and Check Is Valid EMail Domain

You can use this Regex pattern to validate Email Address string pattern and also to check whether the given EMail Address contains Valid Email Domain or Not.

From http://www.regular-expressions.info/email.html
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@
(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|
biz|info|mobi|name|aero|asia|jobs|museum)\b

Thanks,
Morgan
Software Developer

Thursday, 5 December 2013

Event ID 2004 Resource Exhaustion Diagnosis Events

Description:

In this article, I am going to explain about Event ID 2004 Resource Exhaustion Diagnosis Events and how to configure or enable alert mail for this event. The Event ID 2004 falls under the category of Resource Exhaustion Detector component of Windows Resource Exhaustion Detection and Resolution (RADAR), it identifies the top three memory consuming programs and warns you when the system commit charge reaches a critical level.

Summary:


Event ID 2004 Log Source:

Log Name:      System
Source:        Microsoft-Windows-Resource-Exhaustion-Detector
Date:          04/12/2013 3:17:33 PM
Event ID:      2004
Task Category: Resource Exhaustion Diagnosis Events
Level:         Warning
Keywords:      Events related to exhaustion of system commit limit (virtual memory).
User:          SYSTEM
Computer:      myPC.myDomain.local
Description:
Windows successfully diagnosed a low virtual memory condition. The following programs consumed the most virtual memory: sqlservr.exe (1956) consumed 729833472 bytes, devenv.exe (3896) consumed 404164608 bytes, and w3wp.exe (2516) consumed 240144384 bytes.

Steps to Configure Alert Notification mail for Event ID 2004:

1. Open the Event Viewer MMC by running the command eventvwr.msc.
2. Expand the node Windows Logs, and select System
3. Search and and select the Event 2004, right-click on the event entry and click Attach Task To This Event..

Event ID 2004 Resource Exhaustion Diagnosis Events


4. Type the description like 'This is a warning alert message for high memory usage on the following programs' and click Next

event id 2004 resource exhaustion detector

event id 2004 resource exhaustion detector windows 7


5. Select Send an e-mail option and click Next.

event id 2004 source microsoft-windows-resource-exhaustion-detector


6.Go to Action -> Send an e-mail section, type the From and To Address and SMTP Server address for your Mail Server and click Next.

event id 2004 source microsoft-windows-resource-exhaustion-detector


7. Now click the Finish button to complete Alert Mail Notification for the Event ID 2004

event id 2004 source microsoft-windows-resource-exhaustion-detector





Thanks,
Morgan
Software Developr

Wednesday, 4 December 2013

Union vs Union ALL in SQL Server

Description:

In this article, I am going write the difference between Union vs Union All in SQL Server in multiple rows insert statement.

Union vs Union All in SQL

UNION ALL - It will not remove duplicate rows when you insert multiple rows or values by using Union All, it just combine all the rows.

UNION - Removes duplicate rows when you insert multiple rows or records by using Union.

Union ALL in SQL to Insert multiple rows or records

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into SQL Server using UNION ALL
INSERT INTO #tempTable (ID, UserName) 
Select 1, 'User1'
UNION ALL
Select 2, 'User2'
UNION ALL
Select 2, 'User2'
UNION ALL
Select 3, 'User3'

--Select inserted values from temp table 
Select * From #tempTable

Union vs Union All in SQL Server

Union in SQL to Insert multiple records/rows

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into SQL Server using UNION
INSERT INTO #tempTable (ID, UserName) 
Select 1, 'User1'
UNION 
Select 2, 'User2'
UNION 
Select 2, 'User2'
UNION 
Select 3, 'User3'

--Select inserted values from temp table 
Select * From #tempTable

Union vs Union All in SQL Server

Note: If you have no problem with duplicate rows, you can use Union All instead of Union for better performance. since Union query will check all the rows to find duplicates, it will takes more execution time compared with Union ALL.

Thanks,
Morgan
Software Developer

Insert Multiple Rows into Table in SQL Server

Description:

In this article, I am going to write T SQL Script to Insert Multiple Rows into Table in single statement with different ways in SQL Server. You can choose best way as per your wish. But If you have 1000 of records I would suggest you to go with SqlBulkCopy in C#.

Summary:


Insert Multiple Rows into Table in SQL Server by Single Statement

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into SQL Server by Single Statement
INSERT INTO #tempTable (ID, UserName) VALUES (1, 'User1');
INSERT INTO #tempTable (ID, UserName) VALUES (2, 'User2');
INSERT INTO #tempTable (ID, UserName) VALUES (3, 'User3');

--Select inserted values from temp table 
Select * From #tempTable


Insert Multiple Rows into Table with Union ALL

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into SQL Server using UNION ALL
INSERT INTO #tempTable (ID, UserName) 
Select 1, 'User1'
UNION ALL
Select 2, 'User2'
UNION ALL
Select 2, 'User2'
UNION ALL
Select 3, 'User3'

--Select inserted values from temp table 
Select * From #tempTable

Insert Multiple Rows into Table with Union ALL


Note: When you insert multiple rows using UNION ALL, it just combines the all the rows. It will not remove duplicate rows. So if you want to remove duplicate rows from multiple insert you need to use just UNION instead of  UNION ALL

Insert Multiple Rows into Table in SQL Server using Union by Single Statement

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into SQL Server using UNION
INSERT INTO #tempTable (ID, UserName) 
Select 1, 'User1'
UNION 
Select 2, 'User2'
UNION 
Select 2, 'User2'
UNION 
Select 3, 'User3'

--Select inserted values from temp table 
Select * From #tempTable

Insert Multiple Rows into Table with Union


Note: When you insert multiple rows using UNION, it removes the duplicate rows. So if you don't want to remove duplicate rows from multiple insert you need to use UNION ALL instead of  UNION.

Insert Multiple Rows into Table by select Rows from another Table

-- Check and Drop Existing Temp Table
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable'))
          DROP TABLE #tempTable

--Create temp table
CREATE TABLE #tempTable (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into table in SQL Server using UNION
INSERT INTO #tempTable (ID, UserName) 
Select 1, 'User1'
UNION 
Select 2, 'User2'
UNION 
Select 3, 'User3'

IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tempTable2')) 
           DROP TABLE #tempTable2

--Create second temp table
CREATE TABLE #tempTable2 (ID INT, UserName NVARCHAR(50));

-- Insert Multiple Values into table by select rows from another table 
INSERT INTO #tempTable2 (ID, UserName) Select ID,UserName From #tempTable


--Select inserted values from second temp table 
Select * From #tempTable2



Insert Multiple Rows into Table using SqlBulkCopy in C# with DataTable

Create SQL Table
CREATE TABLE [dbo].[ProductSalesData](
 [SaleDate] [smalldatetime] NOT NULL,
 [ProductName] [nvarchar(1000)] NOT NULL,
 [TotalSales] [int] NOT NULL)

Bulk Insert into MS SQL Server using SqlBulkCopy in C# with DataTable
using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

            // Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

            // Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

            // Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

            // Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

            // Let's populate the datatable with our stats.
            // You can add as many rows as you want here!

            // Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

            // Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

            // Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}

The Output is

select * from dbo.ProductSalesData

SaleDate               ProductName  TotalSales
04/12/2013 00:00:00    Nike         10

Thanks,
Morgan
Software Developer

Monday, 2 December 2013

HTTP Error 503. The service is unavailable.

Description:

     I have hosted my Web Application in IIS 7.5. It was worked well for the past one or two months. But today, when I try connect my Web Application thorough URL I got the HTTP error page with the message HTTP Error 503. The service is unavailable.

HTTP Error 503. The service is unavailable.

Cause of HTTP Error 503. The service is unavailable:

    After I have analyzed some time, found the reason. The HTTP Error 503. The service is unavailable occurs if the Application Pool of the corresponding Wep Application is Stopped or Disabled or Paused.
Check the following two Fix/Solutions to resolve this issue.


Steps to fix HTTP Error 503. The service is unavailable: Solution 1

1. Open the Internet Information Services (IIS) by running the command inetmgr 

2. Expand the Root node, expand Sites, and right-click on your Application, click Manage Web Site ->Advanced Settings


HTTP Error 503. The service is unavailable.


3. Note down the Application Pool name under General settings and close the window

HTTP Error 503. The service is unavailable.

4. Now go to Application Pools section, here you can see the corresponding Application Pool is in Stopped state. right-click on the Application Pool and Start it, also restart your Web Application.

HTTP Error 503. The service is unavailable. Start Application Pool


5. Now your problem would be solved, if not solved then check the below solution.

Fix HTTP Error 503. The service is unavailable: Solution 2

      Issue may be solved for some of them after completed the above steps. But in my case, I have started Application Pool, then I restarted my Web Application. Then when I connect my webpage, once again I got the same problem, then I went to further analyze from the event log. I found three System Events, Event ID 5021, Event 5057, Event 5059.

 Event ID 5012 Source:
Source:        Microsoft-Windows-WAS
Event ID:      5021
Level:         Warning
Description:
The identity of application pool AuditAppPoolV4 is invalid. The user name or password that is specified for the identity may be incorrect, or the user may not have batch logon rights. If the identity is not corrected, the application pool will be disabled when the application pool receives its first request.  If batch logon rights are causing the problem, the identity in the IIS configuration store must be changed after rights have been granted before Windows Process Activation Service (WAS) can retry the logon. If the identity remains invalid after the first request for the application pool is processed, the application pool will be disabled. The data field contains the error number. 
Event 5017 Source:
 
Source:        Microsoft-Windows-WAS
Event ID:      5057
Level:         Warning
Description:
Application pool AuditAppPoolV4 has been disabled. Windows Process Activation Service (WAS) did not create a worker process to serve the application pool because the application pool identity is invalid.
Event 5019 Source:
Source:        Microsoft-Windows-WAS
Event ID:      5059
Level:         Error
Description:
Application pool AuditAppPoolV4 has been disabled. Windows Process Activation Service (WAS) encountered a failure when it started a worker process to serve the application pool.
 
From the above Event IDs, it clearly indicates the root cause of the problem is Identity of the Application Pool. The given user Identity may be invalid due to expired password or locked or some other reason. So now we need to change it to new user Identity

 1. Go to the Application Pools section, right-click on the Application Pool, click Advanced Settings.

HTTP Error 503. The service is unavailable. Set Identity

 2. You can see the Identity name under Process model section in the opened window. click Identity name to Edit.

HTTP Error 503. The service is unavailable. Set Identity

 3. Click the Set button, enter new user credentials, and click OK.

HTTP Error 503 The service is unavailable. Set Identity


 4. Now Restart the Application Pool and Restart your Web Application.

HTTP Error 503 The service is unavailable. Set Identity

Create Table in SQL Server Examples

Description:

In this article, I am going to write T-SQL query to Create Table in MS SQL Server in different methods.

Summary:


Sql Query to Create Table in SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL)

Create Table with Identity/Auto Increment column in MS SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int IDENTITY NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL)

Create Table with Primary Key in MS SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL)

T-Sql Query to Create Table with Primary Key and Identity Column in SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int IDENTITY PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL)

Create Table with Primary Key and Custom Primary Key Name in SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL,
CONSTRAINT [PK_ID_AATable] PRIMARY KEY CLUSTERED(ID))

Create Table with Date Time column in SQL Server

Use [MS_SQLServer_DB]
GO
CREATE TABLE [TestSQLTable](
ID int NOT NULL,
UserName nvarchar(100) NOT NULL,
LoginTime datetime NULL)

Create Table with Foreign Key in SQL Server

--Relative Table(Foreign Key Table)

CREATE TABLE [RTable](
CityID int PRIMARY KEY NOT NULL,
CityName nvarchar(1000) NOT NULL)

--Primary Key Table

CREATE TABLE [PTable](
ID int IDENTITY PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) NULL,
City int NULL,
FOREIGN KEY (City) REFERENCES [RTable] (CityID))



Create Table with Sparse Column in SQL Server

The Sparse column feature exists only from SQL Server 2008 and later versions.
Use [MS_SQLServer_DB]
GO

CREATE TABLE [TestSQLTable](
ID int IDENTITY PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
MailID nvarchar(100) SPARSE NULL,SpecialPurposeColumns XML COLUMN_SET FOR ALL_SPARSE_COLUMNS)

Create Table with NonClustered Index Column in SQL Server

Use [MS_SQLServer_DB]
GO

CREATE TABLE [TestSQLTable](
ID int IDENTITY PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
JoinDate datetime NOT NULL,
MailID nvarchar(100) NULL)

CREATE NonClustered  Index Index_JoinDate
ON [TestSQLTable] (JoinDate)


Create Table with Unique Index Column in SQL Server

Use [MS_SQLServer_DB]
GO

CREATE TABLE [TestSQLTable](
ID int IDENTITY PRIMARY KEY NOT NULL,
UserName nvarchar(100) NOT NULL,
JoinDate datetime NOT NULL,
MailID nvarchar(100) NULL)

CREATE Unique INDEX Index_JoinDate
ON [TestSQLTable] (JoinDate)




Thanks,
Morgan
Software Developer

Event ID 4098 - Group Policy Shortcut error

Description:

In this article, I am going to give the solution/fix/cause for error Event 4098. Event ID 4098 is an error event that related to the Group Policy Shortcuts.

Event ID 4098 Source:

I saw the Event ID 4098 with the following error.
The computer 'My Settings' preference item in the 'Default Domain Policy {31B2F340-016D-11D2-945F-00C04FB984F9}' Group Policy object did not apply because it failed with error code '0x80070002 The system cannot find the file specified.' This error was suppressed.

Event ID 4098:Fix/Solution

After I have analyzed for some time found the following things as root cause for the problem.
 1. Open the Group Policy Management Console by running the command GPMC.msc.

 2. Click the Edit option on Default Domain Policy (the above 4098 event source shows this policy as error, In your case, it may be different policy )

3. Go to the Computer Shortcuts node, Computer Configuration ->Preferences -> Windows Settings ->Shortcuts, in right side pane check the target path of the shortcut link that causes for the Event 4098.
In my case, the shortcut link is My Settings

Event ID 4098 - Group Policy Shortcut error -Fix/Solution

3. Now change file path in shortcut link settings which caused the Group Policy Shortcut error.



 Thanks,
 Morgan Software
 Developer