Fransiscus Setiawan | EV Charging & Azure Solution Architect | Sydney

Technical Insights: Azure, .NET, Dynamics 365 & EV Charging Architecture

Enums with description in c#

Sometime when we have Enum , we want to use it /bind it on the list as well with a better description/ word. With this method you can bind enum to a list which display its description but store its value as well.This is very useful function.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;
using System.ComponentModel;

public class Enums
    {
        #region helpers
        public static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes =
              (DescriptionAttribute[])fi.GetCustomAttributes
              (typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
        }

        public static T Parse(string input)
        {
            return (T)Enum.Parse(typeof(T), input);
        }
        #endregion

        #region enums
        public enum ResultsType
        {
            [Description("Featured Products")]
            FeaturedProducts,
            [Description("New Products")]
            NewStock,
            CategoryResults,
            [Description("Specials")]
            Specials,
            Brand,
            Row1,
            Row2,
            Row3,
            [Description("This Weeks Specials")]
            ThisWeeksSpecials,
            [Description("Top 10 Best Sellers")]
            Top10BestSellers,
            [Description("Special Offers")]
            SpecialOffers,
            [Description("Buy 1 Get 1 Free")]
            Buy1Get1Free,
            [Description("Half Price Bargains")]
            HalfPriceBargains,
            [Description("Top Sellers")]
            TopSellers,
            [Description("Summer Specials")]
            SummerSpecials,
            [Description("CUSTOMERS WHO BOUGHT THIS ALSO BOUGHT")]
            AlsoBought,
            [Description("Related Products")]
            Upsell
        }

          public enum ReportType
         {
            [Description("Monthly Sales Report")]
            MonthySalesReport = 1,
            [Description("Dispatched Orders Report")]
            DispatchedOrdersReport = 2,
            [Description("Order Report")]
            OrderReport = 3
         }

#endregion

}

This is how you bind it

Private Sub PopulateReportType()

        ddlReportType.Items.Clear()
        ddlReportType.Items.Add(New ListItem(Enums.GetEnumDescription(Enums.ReportType.MonthySalesReport), Convert.ToInt32(Enums.ReportType.MonthySalesReport)))
        ddlReportType.Items.Add(New ListItem(Enums.GetEnumDescription(Enums.ReportType.DispatchedOrdersReport), Convert.ToInt32(Enums.ReportType.DispatchedOrdersReport)))
        ddlReportType.Items.Add(New ListItem(Enums.GetEnumDescription(Enums.ReportType.OrderReport), Convert.ToInt32(Enums.ReportType.OrderReport)))

    End Sub

Raise Event in User Control

I need to create a payment gateway user control that will be used accross all of the modules. This user control should be as simple as doing the transaction ONLY. So what I need to do is to let the host/page container knows whether the transaction is succeeded or not, if it is succeeded then the rest of the logic will be handled on ASPX page.

In order to do so I need to create an event on the user control that will be bubbled up to the page container/host. This sample might not be the best solution but it works perfectly for my needs and only requires several lines of code.

Write this in your user control including declaration(signature) of parameter that you want to pass

Partial Class usercontrols_MyPaymentGateway
    Inherits System.Web.UI.UserControl

#Region "Property"

    ''' 
    ''' this is an event for process status
    ''' 
    ''' 
    Public Event getProcessStatus(ByVal isPaid As Boolean)

Write this in your user control where you want to raise the event and pass the parameter

     RaiseEvent getProcessStatus(True)

Write this in your page container(Create an Event handler to handle your user control events) (NOTE: paymentGateway is the name of your user control)

 ''' 
    ''' event handler to the payment gateway controls
    ''' 
    ''' 
    ''' 
    Private Sub paymentProcessed(ByVal isPaid as boolean) Handles paymentGateway.getProcessStatus

        If (paymentGateway.IsPaid) Then
            ltMessage.Text = "Payment Successful " + paymentGateway.ResponseMessage

            'if it is paid then we need to clear the remaining text boxes
            paymentGateway.ClearFields()
        Else
            ltMessage.Text = "Payment Failed " + paymentGateway.ResponseMessage
        End If

    End Sub

Reference to user control in web.config

I’ve seen that most of people put their user control declaration in individual aspx page, and they declare it on the top of that page. What will happen if you are going to use it on multiple number of pages and i believe most of you would like to have a kind of tag that you can simply use on your web page to add your user control. In here, we declare all the user controls in web.config which I believe is more clean and manageable.

Web.Config


      
        
		
	  
    
	  
		  
		  
		  
		  
		  
		  
    

How to use it in ASPX Page






    Untitled Page


    
        
    


Optimizing Nested Query in SQL Server

My friend has been asked to optimize the SQL query for a forum application. Basically the Query is used to list the thread as well as the last person who posted on the forum. He and me tried to optimize that and we can fasten up the query up to only 13 secs which is not really well 🙁 . then the sql guru is coming to help him and show him the better way in writing the query and it performs only 1 sec. I thought it’s gonna be a good lesson to be shared it on my blog. There you go:

--Non Optimized Version
SELECT
	ForumTopic.ForumTopicID, ForumTopic.Title, Members.Username AS MemberName,
	ForumTopic.Views, ForumTopic.Replies,
	(
		SELECT TOP 1
			ForumPost.EnteredDate
		FROM
			ForumPost
		WHERE
			ForumPost.ForumTopicID = ForumTopic.ForumTopicID
		ORDER BY
			ForumPost.ForumPostID DESC
	) AS LastPostEnteredDate,
	(
		SELECT TOP 1
			Members.Username
		FROM
			ForumPost
		INNER JOIN
			Members
		ON
			ForumPost.EnteredBy = Members.MemberID
		WHERE
			ForumPost.ForumTopicID = ForumTopic.ForumTopicID
		ORDER BY
			ForumPost.ForumPostID DESC
	) AS LastPostMemberName
FROM
	ForumTopic
INNER JOIN
	Members
ON
	ForumTopic.EnteredBy = Members.MemberID
WHERE
	ForumID = @ForumID
AND
	ForumTopic.Valid = 1
ORDER BY
	LastPostEnteredDate DESC
--optimized version
SELECT
	ForumTopic.ForumTopicID,
	ForumTopic.Title,
	Members.UserName as MemberName,
	ForumTopic.Views,
	ForumTopic.Replies,
	ForumPost.EnteredDate as LastPostEnteredDate,
	Members1.Username as LastPostMemberName
FROM
	(
		SELECT
			ForumTopicID, MAX(ForumPostID) AS ForumPostID
		FROM
			ForumPost
		WHERE
			ForumTopicID IN (
				SELECT
					ForumTopicID
				FROM
					ForumTopic
				WHERE
					ForumTopic.ForumID = @ForumID
				AND
					ForumTopic.Valid = 1)
		GROUP BY
			ForumTopicID
	) RecentPost
INNER JOIN
	ForumPost
ON
	ForumPost.ForumPostID = RecentPost.ForumPostID
INNER JOIN
	ForumTopic
ON
	ForumTopic.ForumTopicID = RecentPost.ForumTopicID
INNER JOIN
	Members
ON
	ForumTopic.EnteredBy = Members.MemberID
INNER JOIN
	Members Members1
ON
	ForumPost.EnteredBy = Members1.MemberID
ORDER BY
	ForumPost.EnteredDate DESC

Recursive SQL using CTE in SQL Server 2005

How to do a recursive query in SQL Server 2005, Recursive in the terms of you got a table where it has foreign key to the other record on the same table. Assume a table employee where a record on that table can be an employee or a manager which is an employee as well, or let’s call it when you have nested structure within one table, call it as a tree structure. I’ve googled and found the way in doing it so I believe it’s worthy for me to share with everyone

Table Schema

How to get the whole structure by using one SQL query, we can utilize CTE(Common table expression) and using UNION ALL to do the recursive and do the INNER JOIN with the CTE it self

--get all contentPageID for the page and its children
WITH dynamicPages(contentPage_id, parentContent_id, contentPageName) AS
	(
		SELECT
			c.contentPage_id, c.parentContent_id, c.ContentPageName
		FROM
			tblContentPage c
		WHERE
			c.contentPage_id = @contentPage_id
		UNION ALL
		SELECT
			c.contentPage_id, c.parentContent_id, c.contentPageName
		FROM
			tblContentPage c
		INNER JOIN
			dynamicPages b
		ON
			c.parentContent_id = b.contentPage_id
	)
SELECT * FROM dynamicPages

Paging in Order BY using LINQ

This is a simple way of doing the paging in LINQ. If I do the paging before the ORDER BY then it will give me different result set. The paging is should be after the ORDER BY Statement. So you sort first then you paging it.

        /// 
        /// to get all the have your say using paging based on optional parameter
        /// of isapproved and sorted descending based on the posted date
        /// 
        /// 
        /// 
        /// 
        /// 
        public IQueryable HaveYourSaySelectApproved(bool? IsApproved, int startPage, int pageSize)
        {
            var haveyoursay = from h in HaveYourSayContext.HaveYourSays
                                      orderby h.DatePosted descending
			select h;

            if (IsApproved.HasValue)
            {
                haveyoursay = from h in HaveYourSayContext.HaveYourSays
                              where (h.IsApproved == IsApproved.Value)
                              orderby h.DatePosted descending
                              select h;
            }

	return haveyoursay.Skip(startPage * pageSize).Take(pageSize);
        }

Inserted Table and Deleted Table On SQL Server

this is only a simple trigger and table to monitor the activity on an update activity to “members” table. it tracks the date when the update query is being executed and who execute it, it will be quite useful for a database that has many applications accessing it with different SQL User

Holding table :

CREATE TABLE [dbo].[MemberUpdateTracking](
	[MemberTrackingID] [int] IDENTITY(1,1) NOT NULL,
	[MemberID] [int] NULL,
	[BeforeMemberCode] [varchar](50) NULL,
	[BeforeFirstName] [varchar](255) NULL,
	[BeforeSurname] [varchar](255) NULL,
	[BeforeUserName] [varchar](255) NULL,
	[BeforePassword] [varchar](255) NULL,
	[BeforeEmailAddress] [varchar](255) NULL,
	[AfterMemberCode] [varchar](50) NULL,
	[AfterFirstName] [varchar](255) NULL,
	[AfterSurname] [varchar](255) NULL,
	[AfterUserName] [varchar](255) NULL,
	[AfterPassword] [varchar](255) NULL,
	[AfterEmailAddress] [varchar](255) NULL,
	[ModifiedDate] [datetime] NOT NULL,
	[SQLUser] [varchar](255) NOT NULL,
 CONSTRAINT [PK_MemberUpdateTracking] PRIMARY KEY CLUSTERED
(
	[MemberTrackingID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

Triggers:

CREATE TRIGGER [dbo].[tr_Member_UPDATE]
	ON [dbo].[Members]
	FOR UPDATE
AS
BEGIN
	SET	NOCOUNT ON

	DECLARE @MemberID			int
	DECLARE @AfterFirstName		varchar(255)
	DECLARE @AfterSurname		varchar(255)
	DECLARE @AfterMemberCode	varchar(50)
	DECLARE @AfterUserName		varchar(255)
	DECLARE @AfterPassword		varchar(255)
	DECLARE @AfterEmailAddress	varchar(255)

	DECLARE @BeforeFirstName	varchar(255)
	DECLARE @BeforeSurname		varchar(255)
	DECLARE @BeforeMemberCode	varchar(50)
	DECLARE @BeforeUserName		varchar(255)
	DECLARE @BeforePassword		varchar(255)
	DECLARE @BeforeEmailAddress	varchar(255)


	--get information what will been inserted
	SELECT @MemberID = MemberID,
		   @AfterFirstName = FirstName,
		   @AfterSurname = Surname,
		   @AfterUserName = Username,
		   @AfterPassword = [Password],
		   @AfterMemberCode = MemberCode,
		   @AfterEmailAddress = EmailAddress
	FROM
		Inserted

	--only need for strange behaviour issue that we had before otherwise not necessary
	IF (@AfterFirstName = '' OR @AfterSurname = '' OR @AfterFirstName IS NULL OR @AfterSurname IS NULL)
	BEGIN
		--get the original information
		SELECT  @BeforeFirstName = FirstName,
				@BeforeSurname = Surname,
				@BeforeUserName = Username,
				@BeforePassword = [Password],
				@BeforeMemberCode = MemberCode,
				@BeforeEmailAddress = EmailAddress
		FROM
			Deleted

		--track the changes
		INSERT INTO MemberUpdateTracking(MemberID, BeforeMemberCode, BeforeFirstName,
					BeforeSurname, BeforeUserName, BeforePassword, BeforeEmailAddress,
					AfterMemberCode, AfterFirstName, AfterSurname, AfterUserName, AfterPassword,
					AfterEmailAddress, ModifiedDate, SQLUser)
		VALUES
			(@MemberID, @BeforeMemberCode, @BeforeFirstName, @BeforeSurname,
					@BeforeUserName, @BeforePassword, @BeforeEmailAddress, @AfterMemberCode,
					@AfterFirstName, @AfterSurname,
					@AfterUserName, @AfterPassword, @AfterEmailAddress,
					GETDATE(), SYSTEM_USER)
	END
END

Undo compressing old files by windows

My computer was losing its graphic card driver and somehow losing sound as well and I realised that i’ve been compressing the old files via disk clean up.

I thought i want to do reformat my PC, I tried to google to undo the compressing old files by windows and I’ve found that you need to run this from the command prompt. It will uncompress all the old files that has been compressed through windows disk clean up.I wonder why they don’t create a functionality to undo this.

C:\>compact /u /s /a /q /i *.*

Find a control in ContentPlaceHolder

I have a user control and I would like to hide a control on the page container that host this user control. I try to use

Page.FindControl("litContent")

But It throws an error of object not found. The solution is you need to find the contentplaceholder first on the master page then you find the control that you want from that placeholder. It’s a bit tricky since i thought once you get a Page instance then you can get all control hosted on the Page instance itself.

1. Place this tag on your asp.net page where it hosts your control


2. go to the page behind of the user control/page where you want to place your logic to hide/show it

'hide the dynamic page from the parent page
Dim mainContent As ContentPlaceHolder = CType(Page.Master.FindControl("ContentPlaceHolder1"), ContentPlaceHolder)

If Not (mainContent Is Nothing) Then
   Dim contentPlaceHolder As Literal = CType(mainContent.FindControl("litContent"),Literal)
   If Not (contentPlaceHolder Is Nothing) Then
       contentPlaceHolder.Visible = False
   End If
End If

AJAX Update Panel Timeout Issue

I have an asp.net page where the page will query the report from the database. To query the report itself might cause timeout exception on the page itself before the report result is being returned from database.

You need to do it in two steps, first you need to override the script timeout only for the pageitself. put this code in your code behind

    Dim pageTimeOut As Integer
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        pageTimeOut = Server.ScriptTimeout

        'this is in seconds
        Server.ScriptTimeout = 2500
End Sub

Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload

Server.ScriptTimeout = pageTimeOut

End Sub

The next step is required only if you use AJAX Update panel. Put this script on the aspx page


   Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
        function (sender, args)
        {
             if (args.get_error() && args.get_error().name == 'Sys.WebForms.PageRequestManagerTimeoutException')
            {
                  // remember to set errorHandled = true to keep from getting a popup from the AJAX library itself
                 args.set_errorHandled(true);
             }
        });

Page 15 of 19

Powered by WordPress & Theme by Anders Norén