RSS

Category Archives: ASP.Net

Why You Would Ever Use SOAP Over REST (Why I Never Learned REST Web Services)

Most of my career I have dealt with Banking, High Integrity, HIPPA, PCI, and Financial data. When dealing with these kinds of data the main things you need to be worried about are:

  1. Ability to perform distributed transactional functions
  2. Verification of identity through intermediary (not just point to point IE. SSL)
  3. Standard implementation of data integrity and data privacy.

For the above data types the three things above aren’t a option you must implement them and SOAP does all three with WS-Security, WS-AtomicTransaction, and WS-ReliableMessaging.

REST is limited by the HTTP protocol itself and the stateless nature of the web for things like transactions and expects you to handle errors in communication. SOAP on the other hand provides two-phase commit across distributed transactional resources, has successful/retry logic built in, non-repudiation through signed messages, and support for signature formats: SAML Certificates- Kerberos tickets-x.509 certificates. SOAP also has the ability to encrypt the messages itself and a few other nice features such as attaching security tokens built in natively. This combination of things along with proper use of ciphers, formats, and algorithms leads to what is called end to end security which is a requirement for the above mentioned data tpyes to be compliant with industry standards and in some cases federal law. For anyone who does not need these things REST is great but for secure data, strong typing, and support for numerous security mechanisms to ensure safe use and reliable data you use SOAP.

Advertisements
 
 

Tags: , , , , , ,

Problems With IE 10 and X-UA-Compatible meta tag

So as a lot of you prob know Microsoft has pushed IE 10 in a KB release on Apr 9th. For some of us this has caused a headache because there is a issue with how the

<meta http-equiv="X-UA-Compatible" content="IE=8" />

tag is interpreted and we use this as developers sometimes for SharePoint, Dynamics CRM, and using some older libs in web apps for certain pages. Now the answer for us was removing this tag as it was for code I rewrote long ago. But lets get to the underlying cause. so if you make a demo page and place this tag in the meta, then put two text boxes and attach js validate 1.1 to the boxes and make one required and one not. When you submit the page you will see both will show up as required. So lets hit F12 and see whats up with the rendering.

OMGS what is this (credit to Corey Peters his image looked better than mine so I stole it.)

So as you see in the screen cap above IE 10 is getting the Doc Mode correct but not the Browser Mode. This is great for those who have been pushing Microsoft for proper web standards but man they could have put out some warning instead of putting IE 10 in a KB so it would have been more apparent when skimming over upcoming WSUS that IE 10 was coming. This causes issues in rendering as the doc type clashes with the browser mode in how the page is processed/handled by IE breaking quite a few JS libs.

If you are experiencing these issues you can either remove the tag if it is not needed, detect the browser and display a warning, or look at your code and fix the issues that are holding it back from IE 10. In the short term you also can do the following.

1. Use a loose instead of strict doctype
2. Validate your markup and make sure it is correct
3. Add a site to compatibility mode view settings
4. change tag to

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" >

If that does not work you may have a long road ahead. Stay strong my friends and till next Microsoft update don’t let your code have a meltdown.

 
Leave a comment

Posted by on April 15, 2013 in ASP.Net, C#, HTML

 

Tags: , , , , , ,

Payment Systems, Tokens, and You

So as some of you may know I work for a medium size third party payments solutions provider. What is that you may ask? Well what we do as a company is we take your billing and communiqué data transform it into mail able information in the form of pdf’s, print, stuff, mail, and in some cases handle the payments from mail for the customers. After that we allow you to view, pay, and manage your bills online that you receive from us.  This entails some very detailed processes and the ability to be mindful of any security implications anything you write may cause (we have to be HIPPA, PCI, and HITRUST compliant). This is no small task and is much larger than the scope of this article but we will get into more of that later. I am in my essence a Secure Web Applications Architect it is what I derived my skills from… reverse engineering and though I love the latter I enjoy more making sure that people are safe and secure as I possibly can make them when using items I design/architect it makes me feel good knowing that I do everything I can to build a good secure yet agile application.

                So to the meat this article is about tokens and why they are a positive thing for you to use in your systems as you implement them and some key things to do when your building any application that takes payment information over the internet and/or public communication lines.

So first let’s start off with some key principles of things you should do with any web application you design:

  1. Approach everything from the standpoint that someone is trying to steal your information. Just because they aren’t right now doesn’t mean they  aren’t going to be trying in the future.
  2. SSL encryption is your best friend WHEN IMPLEMENTED CORRECTLY. The key to using ssl to simplify your over the wire transmissions is making sure you    do not use weak ciphers or transmission protocols. You should not use any CBC based cipher nor any SSL below version 3.  Use strong encryption meaning 128 bits or more.  Also avoid using TLS 1.1 and 1.0 if you can. Also do not use deflate compression. There are many reasons for what I just said but to name 2 very good reason’s they one  violate PCI standards and two make you susceptible to BEAST/CRIME attacks.
  3. Transmit as little sensitive information as possible. If you don’t need to collect it and/or transmit it then don’t it’s that simple take a little overhead on your server side and look up information that you already have if possible after properly verifying the provided information from the user.
  4. Log the IP address and the time stamp of the transmission of any users submitting a payment to your web site the reason for this is so you have at least one way to identify the location/point of initiation so that you can ban/monitor/provide the source of the offending transaction.
  5. NEVER store credit card data in your database NEVER meaning the credit card number, cvv2, and/or stripe data again this is in keeping with PCI standards and even without those is still good practice even if those industry standards did not exist . It is ok to keep the last 4 and star out the rest of the main card number, to keep the expiration date, and card type in the case of creating a wallet but more on that later.

This will be continued in part 2 which will come tomorrow where I will continue to go through best practices and after that I will go through creating a API for tokenization with paymentsgateway.com and the code of how to do it :).  Till then don’t let your code have a meltdown.

 
Leave a comment

Posted by on January 2, 2013 in ASP.Net, C#, PCI

 

Tags: , , , , ,

Convert ExcelML (Excel 2007/2010 xml file) to DataSet

Alright so I love Telerik and you guys who have worked with me know it but there is a issue with Telerik that is a deep dark secret I hide… lol its not that serious. So as we all know you can import regular xls files using the ace and jet OleDB libraries. Problem is that even with the new BIFF(Excel Binary) RadGrid export format Telerik put out this recent release it is still somewhat limited in its function. So the easiest way to keep formatting and make exports look pretty is to use the export type ExcelML which is a standardized xml format from excel. But there a catch. Guess what? There is no standardized way from Microsoft or anyone for that matter to process this file type back into your system!!!!!! Now you could always call the inter-op and COM libraries open the file and save it out as a binary xls but it requires you to have Excel installed on the computer that the program runs on. In my case that is going to be a web server and that is a BIG NO NO! So I wrote a way to custom parse the info back into the system as a DataSet dynamically (WITH NO REFLECTION!!!!!) and here follows the code in vb.net and c#. Make sure to include System.Data and System.XML.

    Public Shared Function ImportExcelXML(inputFileStream As Stream, hasHeaders As Boolean, autoDetectColumnType As Boolean) As DataSet
        Dim doc As New XmlDocument()
        doc.Load(New XmlTextReader(inputFileStream))
        Dim nsmgr As New XmlNamespaceManager(doc.NameTable)

        nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office")
        nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel")
        nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet")

        Dim ds As New DataSet()

        For Each node As XmlNode In doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)
            Dim dt As New DataTable(node.Attributes("ss:Name").Value)
            ds.Tables.Add(dt)
            Dim rows As XmlNodeList = node.SelectNodes("ss:Table/ss:Row", nsmgr)
            If rows.Count > 0 Then
                Dim columns As New List(Of ColumnType)()
                Dim startIndex As Integer = 0

                If hasHeaders Then
                    For Each data As XmlNode In rows(0).SelectNodes("ss:Cell/ss:Data", nsmgr)
                        columns.Add(New ColumnType(GetType(String)))
                        'default to text
                        dt.Columns.Add(data.InnerText, GetType(String))
                    Next
                    startIndex += 1
                End If

                If autoDetectColumnType AndAlso rows.Count > 0 Then
                    Dim cells As XmlNodeList = rows(startIndex).SelectNodes("ss:Cell", nsmgr)
                    Dim actualCellIndex As Integer = 0
                    For cellIndex As Integer = 0 To cells.Count - 1
                        Dim cell As XmlNode = cells(cellIndex)
                        If cell.Attributes("ss:Index") IsNot Nothing Then
                            actualCellIndex = Integer.Parse(cell.Attributes("ss:Index").Value) - 1
                        End If

                        Dim autoDetectType As ColumnType = [getType](cell.SelectSingleNode("ss:Data", nsmgr))

                        If actualCellIndex >= dt.Columns.Count Then
                            dt.Columns.Add("Column" + actualCellIndex.ToString(), autoDetectType.type)
                            columns.Add(autoDetectType)
                        Else
                            dt.Columns(actualCellIndex).DataType = autoDetectType.type
                            columns(actualCellIndex) = autoDetectType
                        End If

                        actualCellIndex += 1
                    Next
                End If

                For i As Integer = startIndex To rows.Count - 1
                    Dim row As DataRow = dt.NewRow()
                    Dim cells As XmlNodeList = rows(i).SelectNodes("ss:Cell", nsmgr)
                    Dim actualCellIndex As Integer = 0
                    For cellIndex As Integer = 0 To cells.Count - 1
                        Dim cell As XmlNode = cells(cellIndex)
                        If cell.Attributes("ss:Index") IsNot Nothing Then
                            actualCellIndex = Integer.Parse(cell.Attributes("ss:Index").Value) - 1
                        End If

                        Dim data As XmlNode = cell.SelectSingleNode("ss:Data", nsmgr)

                        If actualCellIndex >= dt.Columns.Count Then
                            For a As Integer = dt.Columns.Count To actualCellIndex - 1
                                dt.Columns.Add("Column" + actualCellIndex.ToString(), GetType(String))
                                columns.Add(getDefaultType())
                            Next
                            Dim autoDetectType As ColumnType = [getType](cell.SelectSingleNode("ss:Data", nsmgr))
                            dt.Columns.Add("Column" + actualCellIndex.ToString(), GetType(String))
                            columns.Add(autoDetectType)
                        End If

                        If data IsNot Nothing Then
                            row(actualCellIndex) = data.InnerText.Trim()
                        End If
                        actualCellIndex += 1
                    Next

                    dt.Rows.Add(row)
                Next
            End If
        Next
        Return ds

        '<?xml version="1.0"?>
        '<?mso-application progid="Excel.Sheet"?>
        '<Workbook>
        ' <Worksheet ss:Name="Sheet1">
        '  <Table>
        '   <Row>
        '    <Cell><Data ss:Type="String">Item Number</Data></Cell>
        '    <Cell><Data ss:Type="String">Description</Data></Cell>
        '    <Cell ss:StyleID="s21"><Data ss:Type="String">Item Barcode</Data></Cell>
        '   </Row>
        ' </Worksheet>
        '</Workbook>
    End Function

    Structure ColumnType
        Public type As Type
        Private name As String
        Public Sub New(type As Type)
            Me.type = type
            Me.name = type.ToString().ToLower()
        End Sub
        Public Function ParseString(input As String) As Object
            If [String].IsNullOrEmpty(input) Then
                Return DBNull.Value
            End If
            Select Case type.ToString().ToLower()
                Case "system.datetime"
                    Return DateTime.Parse(input)
                Case "system.decimal"
                    Return Decimal.Parse(input)
                Case "system.boolean"
                    Return Boolean.Parse(input)
                Case Else
                    Return input
            End Select
        End Function
    End Structure

    Private Shared Function getDefaultType() As ColumnType
        Return New ColumnType(GetType([String]))
    End Function

    Private Shared Function [getType](data As XmlNode) As ColumnType
        Dim type As String = Nothing
        If data.Attributes("ss:Type") Is Nothing OrElse data.Attributes("ss:Type").Value Is Nothing Then
            type = ""
        Else
            type = data.Attributes("ss:Type").Value
        End If

        Select Case type
            Case "DateTime"
                Return New ColumnType(GetType(DateTime))
            Case "Boolean"
                Return New ColumnType(GetType([Boolean]))
            Case "Number"
                Return New ColumnType(GetType([Decimal]))
            Case ""
                Dim test2 As Decimal
                If data Is Nothing OrElse [String].IsNullOrEmpty(data.InnerText) OrElse Decimal.TryParse(data.InnerText, test2) Then
                    Return New ColumnType(GetType([Decimal]))
                Else
                    Return New ColumnType(GetType([String]))
                End If
            Case Else
                '"String"
                Return New ColumnType(GetType([String]))
        End Select
    End Function  
public static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders, bool autoDetectColumnType)
{
	XmlDocument doc = new XmlDocument();
	doc.Load(new XmlTextReader(inputFileStream));
	XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

	nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
	nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
	nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");

	DataSet ds = new DataSet();

	foreach (XmlNode node in doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr)) {
		DataTable dt = new DataTable(node.Attributes("ss:Name").Value);
		ds.Tables.Add(dt);
		XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr);
		if (rows.Count > 0) {
			List<ColumnType> columns = new List<ColumnType>();
			int startIndex = 0;

			if (hasHeaders) {
				foreach (XmlNode data in rows(0).SelectNodes("ss:Cell/ss:Data", nsmgr)) {
					columns.Add(new ColumnType(typeof(string)));
					//default to text
					dt.Columns.Add(data.InnerText, typeof(string));
				}
				startIndex += 1;
			}

			if (autoDetectColumnType && rows.Count > 0) {
				XmlNodeList cells = rows(startIndex).SelectNodes("ss:Cell", nsmgr);
				int actualCellIndex = 0;
				for (int cellIndex = 0; cellIndex <= cells.Count - 1; cellIndex++) {
					XmlNode cell = cells(cellIndex);
					if (cell.Attributes("ss:Index") != null) {
						actualCellIndex = int.Parse(cell.Attributes("ss:Index").Value) - 1;
					}

					ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr));

					if (actualCellIndex >= dt.Columns.Count) {
						dt.Columns.Add("Column" + actualCellIndex.ToString(), autoDetectType.type);
						columns.Add(autoDetectType);
					} else {
						dt.Columns(actualCellIndex).DataType = autoDetectType.type;
						columns(actualCellIndex) = autoDetectType;
					}

					actualCellIndex += 1;
				}
			}

			for (int i = startIndex; i <= rows.Count - 1; i++) {
				DataRow row = dt.NewRow();
				XmlNodeList cells = rows(i).SelectNodes("ss:Cell", nsmgr);
				int actualCellIndex = 0;
				for (int cellIndex = 0; cellIndex <= cells.Count - 1; cellIndex++) {
					XmlNode cell = cells(cellIndex);
					if (cell.Attributes("ss:Index") != null) {
						actualCellIndex = int.Parse(cell.Attributes("ss:Index").Value) - 1;
					}

					XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr);

					if (actualCellIndex >= dt.Columns.Count) {
						for (int a = dt.Columns.Count; a <= actualCellIndex - 1; a++) {
							dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string));
							columns.Add(getDefaultType());
						}
						ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr));
						dt.Columns.Add("Column" + actualCellIndex.ToString(), typeof(string));
						columns.Add(autoDetectType);
					}

					if (data != null) {
						row(actualCellIndex) = data.InnerText.Trim();
					}
					actualCellIndex += 1;
				}

				dt.Rows.Add(row);
			}
		}
	}
	return ds;

	//<?xml version="1.0"?>
	//<?mso-application progid="Excel.Sheet"?>
	//<Workbook>
	// <Worksheet ss:Name="Sheet1">
	//  <Table>
	//   <Row>
	//    <Cell><Data ss:Type="String">Item Number</Data></Cell>
	//    <Cell><Data ss:Type="String">Description</Data></Cell>
	//    <Cell ss:StyleID="s21"><Data ss:Type="String">Item Barcode</Data></Cell>
	//   </Row>
	// </Worksheet>
	//</Workbook>
}

struct ColumnType
{
	public Type type;
	private string name;
	public ColumnType(Type type)
	{
		this.type = type;
		this.name = type.ToString().ToLower();
	}
	public object ParseString(string input)
	{
		if (String.IsNullOrEmpty(input)) {
			return DBNull.Value;
		}
		switch (type.ToString().ToLower()) {
			case "system.datetime":
				return DateTime.Parse(input);
			case "system.decimal":
				return decimal.Parse(input);
			case "system.boolean":
				return bool.Parse(input);
			default:
				return input;
		}
	}
}

private static ColumnType getDefaultType()
{
	return new ColumnType(typeof(String));
}

private static ColumnType getType(XmlNode data)
{
	string type = null;
	if (data.Attributes("ss:Type") == null || data.Attributes("ss:Type").Value == null) {
		type = "";
	} else {
		type = data.Attributes("ss:Type").Value;
	}

	switch (type) {
		case "DateTime":
			return new ColumnType(typeof(DateTime));
		case "Boolean":
			return new ColumnType(typeof(Boolean));
		case "Number":
			return new ColumnType(typeof(Decimal));
		case "":
			decimal test2 = default(decimal);
			if (data == null || String.IsNullOrEmpty(data.InnerText) || decimal.TryParse(data.InnerText, test2)) {
				return new ColumnType(typeof(Decimal));
			} else {
				return new ColumnType(typeof(String));
			}
			break;
		default:
			//"String"
			return new ColumnType(typeof(String));
	}
}
 
Leave a comment

Posted by on July 6, 2012 in ASP.Net, C#, Excel, ExcelML, XLS, XML

 

Tags: , , , ,

Convert LINQ to Entity ObjectQuery to DataTable

It has been a while, I know and I have been meaning to blog but have been uber busy so here is a new one for you.
So for anyone who has used LINQ to DataSet you know there is a method for CopyToDataTable(). For LINQ to Entity there is no such thing and though I will not go into why there are reasons and they make partial sense but I needed to do this to get better control of my data binding. So I went out and used reflection and came back with a simple way to convert the returned IEnumerable object list to a DataTable this treats each object in the returned entity as a DataRow and dynamically gets the properties and the column names. Below are the C# and VB.Net versions. Also make sure to include the System.Reflection Library in your class where you use this.

    Public Function ObjectQueryToDataTable(Of T)(objlist As IEnumerable(Of T)) As DataTable
        Dim dtReturn As New DataTable()

        Dim objProps As PropertyInfo() = Nothing

        If objlist Is Nothing Then
            Return dtReturn
        End If

        For Each objRec As T In objlist
            If objProps Is Nothing Then
                objProps = DirectCast(objRec.[GetType](), Type).GetProperties()
                For Each objpi As PropertyInfo In objProps
                    Dim colType As Type = objpi.PropertyType

                    If (colType.IsGenericType) AndAlso (colType.GetGenericTypeDefinition() = GetType(Nullable(Of ))) Then
                        colType = colType.GetGenericArguments()(0)
                    End If

                    dtReturn.Columns.Add(New DataColumn(objpi.Name, colType))
                Next
            End If

            Dim dr As DataRow = dtReturn.NewRow()

            For Each pi As PropertyInfo In objProps
                dr(pi.Name) = If(pi.GetValue(objRec, Nothing) Is Nothing, DBNull.Value, pi.GetValue(objRec, Nothing))
            Next

            dtReturn.Rows.Add(dr)
        Next
        Return dtReturn
    End Function
public DataTable ObjectQueryToDataTable<T>(IEnumerable<T> objlist)
{
	DataTable dtReturn = new DataTable();

	PropertyInfo[] objProps = null;

	if (objlist == null) {
		return dtReturn;
	}

	foreach (T objRec in objlist) {
		if (objProps == null) {
			objProps = ((Type)objRec.GetType()).GetProperties();
			foreach (PropertyInfo objpi in objProps) {
				Type colType = objpi.PropertyType;

				if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) {
					colType = colType.GetGenericArguments()(0);
				}

				dtReturn.Columns.Add(new DataColumn(objpi.Name, colType));
			}
		}

		DataRow dr = dtReturn.NewRow();

		foreach (PropertyInfo pi in objProps) {
			dr(pi.Name) = pi.GetValue(objRec, null) == null ? DBNull.Value : pi.GetValue(objRec, null);
		}

		dtReturn.Rows.Add(dr);
	}
	return dtReturn;
}

Hope this helps you out as always if you have a better way let me know :).

 
2 Comments

Posted by on July 6, 2012 in ASP.Net, C#, Entity Framework, SQL

 

Tags: , , ,

When You Should Initialize Variables Conditionally

Here is an example of a variable you can initalize conditionally.

<pre>        public virtual T QueryString<T>(string name)
        {
            string queryParam = null;
            if (HttpContext.Current != null && HttpContext.Current.Request.QueryString[name] != null)
                queryParam = HttpContext.Current.Request.QueryString[name];

            if (!String.IsNullOrEmpty(queryParam))
                return CommonHelper.To<T>(queryParam);

            return default(T);
        }

now the reason you would want to intialize this conditonally is that no matter what the string is null unless
the if statements are met therefore assigning a value in the begining instead of in the else adds a step to the method that doesn’t have to be there. So do something more like this…

        public virtual T QueryString<T>(string name)
        {
            string queryParam;

            if (HttpContext.Current != null && HttpContext.Current.Request.QueryString[name] != null)
                queryParam = HttpContext.Current.Request.QueryString[name];
            else
                queryParam = null;

            if (!String.IsNullOrEmpty(queryParam))
                return CommonHelper.To<T>(queryParam);

            return default(T);
        }
 
Leave a comment

Posted by on April 18, 2012 in ASP.Net, C#, C# for Beginners

 

Don’t Fear Lambda Expressions

example of a lambda expression

        /// <summary>
        ///     perform a check on the item being added before adding it.
        ///     Return true if it should be added, false if it should not be
        ///     added.
        /// </summary>
        public Func<ICollection<T>, T, bool> BeforeAdd
        {
            get { return _beforeAdd ?? (_beforeAdd = (l, x) => true); }
            set { _beforeAdd = value; }
        }
 
Leave a comment

Posted by on April 18, 2012 in ASP.Net, C#