Category Archives: Programming & Development

Custom URLRewriting with XML and Global.asax

utilizes my custom DocParser class here https://ronniediaz.com/2013/08/23/parse-xml-to-dynamic-expandoobject-c-net-4-0/

 void Application_BeginRequest(object sender, EventArgs e)
    {
        //string path = Request.Url.ToString();
        string path = Request.Path;

        if (Regex.IsMatch(path.ToLower(), ".*[.](jpg|png|gif|css|js|pdf|ico|woff|svg|eot|ttf)$"))
        {
            //var h = Regex.Replace(path.ToLower(), ".*/(.*)/(.*)$", "~/$1/$2", RegexOptions.Singleline);
            //Context.RewritePath(path);
            return;
        }
        
        //TODO: authorize user/request
 DocParser dp = new DocParser(Server.MapPath("~/rewrite.xml"));
        var rules = dp.GetElements("*/rule");
        
        foreach (var r in rules)
        {
            if (string.IsNullOrEmpty(r.match_url)) {
                Shared.HandleError("Global.asax::null or empty match_url encountered");
            }

            if (string.IsNullOrEmpty(r.action_url))
            {
                Shared.HandleError("Global.asax::null or empty action_url encountered");
            }
            
            if (Regex.IsMatch(path, r.match_url,RegexOptions.IgnoreCase))
            {
                List<object> qsvars = new List<object>();

                foreach (Match m in Regex.Matches(path, r.match_url, RegexOptions.IgnoreCase))
                {
                    for (int i=1;i<m.Groups.Count;i++)
                    {
                        qsvars.Add(m.Groups[i].Value);
                    }
                }
                //Context.RewritePath(string.Format(r.action_url,qsvars.ToArray()) + "&rewrite=1");
                Context.RewritePath(string.Format(r.action_url, qsvars.ToArray()));
            }
        }
}

rewrite.xml examples

<?xml version="1.0" encoding="utf-8" ?>
<rules>
  <rule match_url="^/home" action_url="~/home.aspx" />
  <rule match_url="^/login" action_url="~/default.aspx" />
  <rule match_url="^/register" action_url="~/welcome/register.aspx" />
  <rule match_url="^/logout" action_url="~/logout.aspx" />
  <rule match_url="^/default/(.*)" action_url="~/default.aspx?q={0}" />
  <rule match_url="^/test/(.*)/(.*)" action_url="~/test.aspx?q={0}&amp;r={1}" />
</rules>
Advertisements

Common functions asp .net static shared library

references custom encryption class here https://ronniediaz.com/2011/01/13/quick-net-encryption-reference/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.Security;
using System.Text;
using System.Net;
using System.IO;

namespace AIS.Common
{
    public static class Shared
    {
        //TODO: add local, dev, prd
        public static string basehref { get { return HttpContext.Current.Request.ApplicationPath; } }

        //TODO: change to json serialized object reference to prevent manipulation of pipe delimeters
        public static string SetSecureQueryString(object o)
        {
            string ct = Crypto.Rijndael.Encrypt(o.ToString(), "static_or_dynamic_string");
            return HttpUtility.UrlEncode(ct);
        }

        //TODO: change to json (same as above)
        public static string SetSecureQueryString(object a, object b, object c, object d, object e, object f, object g, object h)
        {
            string ct = Crypto.Rijndael.Encrypt(a.ToString() + "|" + b.ToString() + "|" + c.ToString() + "|" + d.ToString() + "|" + e.ToString() + "|" + f.ToString() + "|" + g.ToString() + "|" + h.ToString(), "livestream");
            return HttpUtility.UrlEncode(ct);
        }

        public static string GetSecureQueryString(string q)
        {
            try
            {
                //automatically decodes querystring in request
                return Crypto.Rijndael.Decrypt(q, "static_or_dynamic_string");
            }
            catch (Exception ex)
            {
                return "";
            }
        }

//retrieves content from web url and returns as string
        public static string DownloadString(string url, NetworkCredential nc=null)
        {
            System.Net.WebClient wc = new WebClient();
            if (nc != null)
            {
                wc.UseDefaultCredentials = true;
                wc.Credentials = nc;
            }

            return wc.DownloadString(url);
        }

        //http://mayur.gondaliya.com/programming-languages/c-sharp/samples/fetching-url-contents-into-a-string-using-httpwebrequest-72.html
//same as above function, different approach with more detail
        public static string DownloadPage(string url)
        {

            const int bufSizeMax = 65536; // max read buffer size conserves memory
            const int bufSizeMin = 8192; // min size prevents numerous small reads
            StringBuilder sb;

            // A WebException is thrown if HTTP request fails
            try
            {

                // Create an HttpWebRequest using WebRequest.Create (see .NET docs)!
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

                request.Method = WebRequestMethods.Http.Get;

                // Execute the request and obtain the response stream
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();

                // Content-Length header is not trustable, but makes a good hint.
                // Responses longer than int size will throw an exception here!
                int length = (int)response.ContentLength;

                // Use Content-Length if between bufSizeMax and bufSizeMin
                int bufSize = bufSizeMin;
                if (length > bufSize)
                    bufSize = length > bufSizeMax ? bufSizeMax : length;

                // Allocate buffer and StringBuilder for reading response
                byte[] buf = new byte[bufSize];
                sb = new StringBuilder(bufSize);

                // Read response stream until end
                while ((length = responseStream.Read(buf, 0, buf.Length)) != 0)
                    sb.Append(Encoding.UTF8.GetString(buf, 0, length));

                return sb.ToString();

            }
            catch (Exception ex)
            {
                sb = new StringBuilder(ex.Message);
                return sb.ToString();
            }

        }

//one approach using filesystem. will only work depending on permissions otherwise url parsing is needed
        public static string GetCurrentPageName()
        {
            string spath = System.Web.HttpContext.Current.Request.Url.AbsolutePath;
            System.IO.FileInfo oInfo = new System.IO.FileInfo(spath);
            string spagename = oInfo.Name;
            return spagename;
        }

//get titlecase string
        public static string GetTitleCase(object str)
        {
            try
            {
                return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToString().ToLower());
            }
            catch (Exception ex)
            {
                Shared.HandleError(ex);
                return "Other";
            }
        }

        #region handleerror
        public static void HandleError(Exception ex)
        {
            HandleError(ex.ToString());
        }

        //TODO: send error to error handler
        public static void HandleError(string details)
        {
            SendEmail(details);
        }

        public static void HandleError(Page p, Exception ex)
        {
            HandleError(p, ex.ToString());
        }

        public static void HandleError(Page p, string details)
        {
            //MessageBox.Show(hwnd, details);
            SendEmail(details);
        }

        //TODO: replace with call to error manager or hook to event for compatibility
        public static void SendEmail(string details)  {
        //throw new HttpUnhandledException(details);
            if (Shared.GetCurrentPageName().Replace("/", "") != "error.aspx") //TODO: remove. temporary resolution for unhandled session timeouts. PROTOTYPE
            {
                //HttpContext.Current.Response.Redirect("~/error.aspx");
                //TODO: global error log and local
            }
        }
        #endregion
    }
}

Could not load type System.ServiceModel.Activation.HttpModule’ from assembly ‘System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=

If you already have .Net 4.0 installed and install a program that brings in an earlier version of .Net, or manually install an earlier version of .Net afterwards, you may get an exception page that matches the title of this article.

This is a simple fix, outlined in detail in MSDN article referenced at the bottom.

Navigate to:

%windir%\Microsoft.NET\Framework\v4.0.30319

%windir%\Microsoft.NET\Framework64\v4.0.30319 (on a 64-bit computer)

Run:

aspnet_regiis.exe /iru

That’s it!

http://support.microsoft.com/kb/2015129

Are we a Corporatocracy?

http://www.usatoday.com/story/tech/2013/12/09/google-microsoft-facebook-others-form-reform-government-surveillance-coalition/3914697/

Wiki, http://en.wikipedia.org/wiki/Corporatocracy

ubuntu lts 12 xrdp rdp setup on Amazon Cloud AWS(12.04.3 precise pangolin)

Consolidated from multiple sources to exclude erroneous steps.

Tested on Amazon Web Services fresh Ubuntu LTS 12.04.3 instance.

Decided upon ubuntu vs centOS simply to avoid having to compile xrdp and manage dependencies manually. Chose 3rd party linux over Amazon AMI in this case for benefit of included repos, use cases and support in their respective communities (ubuntuforums, etc), as well as not having to compile xrdp in Amazon AMI.

sudo useradd -m {name}
passwd {name}

#you may want to consider setting a root passwd in case you mess up sudoers. if you make a mistake with sudoers terminate your instance and relaunch 🙂 ... or you could mount the HD with another system if it's unencrypted and modify sudoers
passwd root

#edit /etc/sudoers.d and add your new user
{name} ALL=(ALL) ALL

#edit sshd /etc/ssh/sshd_config disable root login and allow password authentication (if you like)
service ssh restart

#http://www.liberiangeek.net/2012/05/connect-to-ubuntu-12-04-precise-pangolin-via-windows-remote-desktop/
sudo apt-get install xrdp

sudo apt-get install gnome-session-fallback

#two options, 2d unity no longer available, previously
echo "gnome-session --session=ubuntu-2d" > ~/.xsession
#http://askubuntu.com/questions/247501/i-get-failed-to-load-session-ubuntu-2d-when-using-xrdp
echo gnome-session --session=gnome-fallback > ~/.xsession

#make sure your user has permission to this file if you have to create it with sudo etc
chown {name}:{name} .xsession

#http://www.filiwiese.com/installing-gnome-on-ubuntu-12-04-precise-pangolin/
sudo add-apt-repository ppa:gnome3-team/gnome3
sudo apt-get update
sudo apt-get install gnome-shell

#http://askubuntu.com/questions/251041/how-to-install-lightdm-set-defaults
sudo apt-get install lightdm

#http://askubuntu.com/questions/71126/how-do-i-set-the-gnome-classic-login-to-be-the-default-with-autologin
sudo /usr/lib/lightdm/lightdm-set-defaults -s gnome-fallback

Don’t forget AWS Firewall:

22 (SSH)	your ip/32

MSSQL User Defined Functions vs Stored Procedures

I received this question earlier today, and thought it was a valid question often misunderstood, and deserving of a small write-up:
“Should a User Defined Function be your first choice instead of a Stored Procedure?”

While there are many pros and cons of each not covered in this write-up (review your versions on MSDN for details), including some features which may not be apparent until you have an issue to troubleshoot (such as sp_who filtering), you can generally ask yourself a single question up front that can help you determine which you should use.

Simply, if the db functionality you need to implement in the function/procedure requires
any DML (insert/update/delete), then go with a stored procedure. Advanced selects and/or filters are best left up to views/table valued functions.

Additionally, do not be afraid to use a combination of functions and procedures especially if there is a goal of re-usability, in accordance with the design considering the planned growth of your db as your software & db architecture permits. On that note, consider and test the performance differences of these implementations, as a compiled/cached function/procedure containing more logic internally may outperform one utilizing logic that is spread throughout.

References
SP_who filtering UDF vs SP, http://stackoverflow.com/questions/2567141/use-sql-to-filter-the-results-of-a-stored-procedure
Data Manipulation Language, http://en.wikipedia.org/wiki/Data_manipulation_language
(Some) Differences (about.com), http://databases.about.com/od/sqlserver/a/procs_vs_functs.htm
(Some) Differences (stackoverflow), http://stackoverflow.com/questions/2039936/difference-between-stored-procedures-and-user-defined-functions

Parse XML to Dynamic ExpandoObject C# .NET 4.0

The example below uses the LINQ to XML predecessor System.Xml.XmlDocument simply because I still prefer the regex parsing method. It can easily be adapted to use XDocument instead based on your preference. The end resulting output (IEnumerable) is the same.

code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Dynamic;
using System.Xml.Linq;

namespace AIS.Common
{
    public class DocParser : IDisposable
    {
        public enum DocTypes
        {
            Xml
        };

        private XmlDocument Document { get; set; }
        //private XDocument Document { get; set; }
        private DocTypes DocType { get; set; }

        //constructor
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt">type of document, currently only supports xml</param>
        /// <param name="f">filename and path</param>
        public DocParser(DocTypes dt, string fp)
        {
            try
            {
                switch (dt)
                {
                    case DocTypes.Xml:
                        DocType = DocTypes.Xml;

                        Document = new XmlDocument();
                        Document.Load(fp);

                        //Document = XDocument.Load(fp);
                        break;
                    default:
                        throw new Exception("Constructor::invalid or unknown doc type specified");
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Constructor::Error with document load or doc type.",ex);
            }
        }

        public IEnumerable<dynamic> GetElements(string regex)
        {
            return XmlToExpandoObject(regex);
        }

        private IEnumerable<dynamic> XmlToExpandoObject(string regex)
        {
            dynamic eo = new ExpandoObject();
            var dictionary = eo as IDictionary<string, object>;
            XmlNodeList xnl = Document.SelectNodes(regex);
            foreach (XmlNode xn in xnl)
            {
                foreach (XmlAttribute xa in xn.Attributes)
                {
                    dictionary[xa.Name.ToString()] = xa.Value.Trim();
                    //TrySetAttr(xn.LocalName, xn);
                }

                yield return eo;
            }
        }
}
}

sample xml:

<?xml version="1.0" encoding="utf-8" ?>
<robots>
  <robot id="1" age="5" />
  <robot id="2" age="3" />
</people>

usage:

DocParser dp = new DocParser(DocParser.DocTypes.Xml, Server.MapPath("~/xmlfilename.xml")); //can also retrieve xml from external service, etc
        var robots = dp.GetElements("*/robot");
foreach (var r in robots) {
Console.WriteLine("Robot id={0}, age={1}", r.id,r.age); //output. if this is web app you will likely do this differently
}

References
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

mssql aes function encrypt decrypt in microsoft sql

Simple symmetric encryption in MSSQL. Copied from MS references below:

USE AdventureWorks2012;
--If there is no master key, create one now. 
IF NOT EXISTS 
    (SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
    CREATE MASTER KEY ENCRYPTION BY 
    PASSWORD = '23987hxJKL95QYV4369#ghf0%lekjg5k3fd117r$$#1946kcj$n44ncjhdlj'
GO

CREATE CERTIFICATE Sales09
   WITH SUBJECT = 'Customer Credit Card Numbers';
GO

CREATE SYMMETRIC KEY CreditCards_Key11
    WITH ALGORITHM = AES_256
    ENCRYPTION BY CERTIFICATE Sales09;
GO

-- Create a column in which to store the encrypted data.
ALTER TABLE Sales.CreditCard 
    ADD CardNumber_Encrypted varbinary(128); 
GO

-- Open the symmetric key with which to encrypt the data.
OPEN SYMMETRIC KEY CreditCards_Key11
   DECRYPTION BY CERTIFICATE Sales09;

-- Encrypt the value in column CardNumber using the
-- symmetric key CreditCards_Key11.
-- Save the result in column CardNumber_Encrypted.  
UPDATE Sales.CreditCard
SET CardNumber_Encrypted = EncryptByKey(Key_GUID('CreditCards_Key11')
    , CardNumber, 1, HashBytes('SHA1', CONVERT( varbinary
    , CreditCardID)));
GO

-- Verify the encryption.
-- First, open the symmetric key with which to decrypt the data.

OPEN SYMMETRIC KEY CreditCards_Key11
   DECRYPTION BY CERTIFICATE Sales09;
GO

-- Now list the original card number, the encrypted card number,
-- and the decrypted ciphertext. If the decryption worked,
-- the original number will match the decrypted number.

SELECT CardNumber, CardNumber_Encrypted 
    AS 'Encrypted card number', CONVERT(nvarchar,
    DecryptByKey(CardNumber_Encrypted, 1 , 
    HashBytes('SHA1', CONVERT(varbinary, CreditCardID))))
    AS 'Decrypted card number' FROM Sales.CreditCard;
GO

References:

http://msdn.microsoft.com/en-us/library/bb669072.aspx

http://msdn.microsoft.com/en-us/library/ms179331.aspx

asp .net repeater itemcommand command name common repeater control item operations

This is only one small snippet illustrating some functionality. I will add to this blog from my previous usage with Repeater control over time or per request.

In many deployments, I prefer to use Repeater or ListView rather than Grids. The code pattern is the same, but the output is slightly different as well as some of the inherent features/functionality.

Notice the example below simulates table output similar to a Grid, or it may also be used for non-table type of output. Repeater is therefore IMO more adaptable to different needs, and allows more re-usability code patterns across projects.

page side:

<asp:Repeater ID="rptRobotsInFactories" runat="server" OnItemCommand="rptRobotsInFactories_ItemCommand">
        <HeaderTemplate>
<table>
<tr>
<td>factory name</td>
<td>robot name</td>
<td>factory location</td>
<td>manufacture date</td>
<td colspan="2">commands</td>
</tr>
   </HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# Eval("factoryname")%>
<asp:TextBox ID="tbRobotName" runat="server" Text='<%# Eval("robotname")%>'></asp:TextBox>
</td>
<td>
<%# Eval("factorylocation")%>
</td>
<td>
<%# Eval("manufacturedate")%>
</td>
<td>
<asp:LinkButton ID="lbtnRename" runat="server"> CommandName="rename" CommandArgument='<%# Eval("robotname")%>'>rename</asp:LinkButton>
</td>
<td>
<asp:LinkButton ID="lbtnDeelte" runat="server"> CommandName="delete" CommandArgument="">delete</asp:LinkButton>
</td>
</tr>
</ItemTemplate>
        </HeaderTemplate>
<FooterTemplate>
<!-- insert pager here if you like-->
        </table>
        </FooterTemplate>
		</asp:Repeater>

code behind:

//you can also intercept item databind as i've listed in another previous article on nested repeaters

 protected void rptRobotsInFactories_ItemCommand(object sender, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "rename")
        {
            string newname = ((TextBox)rptRobotsInFactories.Items[e.Item.ItemIndex].FindControl("tbFileName")).Text;
            //string newname = ((TextBox)e.Item.FindControl("tbFileName")).Text; //equal to the above
            //string index = (string)e.CommandArgument; //useful to pass in index values also. can split the values passed in or pass in class obj
            //var rif = ((List<robotinfactory>)rptRobotsInFactories.DataSource)[e.Item.ItemIndex];
//var rif = Session_RobotsInFactories().Select(r=>r.id==Convert.ToInt32(e.CommandArgument)); //compare to using viewstate/page repeater above
            string oldname = (string)e.CommandArgument;
            if ((newname.ToLower().Trim().Replace(" ","") != "") && (newname!=oldname))
            {
//dowork_rename(oldname,newname);
            }
        }
else if (e.CommandName=="delete") {
            robotinfactory rif = ((List<robotinfactory>)rptRobotsInFactories.DataSource)[e.Item.ItemIndex];
//dowork_delete(rif.id);
}
    }

//added below funcs for clarity
public class robotinfactory() {
public string factoryname {get;set;}
public string robotname {get;set;}
public string factorylocation {get;set;}
public string manufacturedate {get;set;}
}

protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
//these would normally load from your LINQ dbml SP, view, select statement, stored procedure etc
var rifs = new List<robotinfactory>();

rifs.Add(new rif {
factoryname="a",
robotname="bob",
factorylocation="florida",
manufacturedate="7/1/2013"
});

rifs.Add(new rif {
factoryname="b",
robotname="sam",
factorylocation="not florida",
manufacturedate="7/4/2013"
});

rptRobotsInFactories.DataSource = rifs;
rptRobotsInFactories.DataBind();
}
}

directory info get files show directories C# .Net

There is sometimes a misunderstanding between a “file” and a “folder” in filesystems. In C# .Net the following is often used to list all “files” in a folder.

DirectoryInfo di = new DirectoryInfo("yourpath");

foreach (FileInfo fi in di.GetFiles()) {
//do work
}

However, even though you can specify to search containing subdirectories, the above function will not inherently list folders. If you are looking for the equivalent to “dir” or “ls”, instead use “GetFileSystemInfos()”.

            DirectoryInfo di = new DirectoryInfo("yourpath");
		
//note the difference here with getfilesysteminfos
		foreach (dynamic d in di.GetFileSystemInfos()) {
}

Note the usage of dynamic in the above example compared to the first example. This avoids any potential issues with inheritance and choosing the right class for your temp iterator variable for unboxing etc.