Monday, August 18, 2014

Accessing Network Users Email With LDAP

If your running an application on your personal or company network and it's using Windows Authentication, this snippet may be of some use.  This past weekend, I was at an event where I was given the task to create an application that allowed users in the network to register for a company event.  One of the many requirements was to send a confirmation email once the registration was complete.  Since this application would be used on our company network, I decided to use WindowsIdentity and DirectoryServices in the .Net framework.

In the snippet below, I will show you how to access the current users email address.  As you begin to explore the Active Directory, remember that "mail" is only one of many attributes that you can accessed through LDAP.  For more, go here.  Happy Coding!! :)



You'll need to reference DirectoryServices in your project.
using System.DirectoryServices;
using System.Security.Principal;
 
public static string DisplayEmail(IIdentity id)
 {
    string email = string.Empty;
    var winId = id as WindowsIdentity;
     if (id == null)
      {
        return "Identity is not a windows identity";
      }

    var userInQuestion = winId.Name.Split('\\')[1];
    var myDomain = winId.Name.Split('\\')[0];

    var entry = new DirectoryEntry("LDAP://" + myDomain);

    var adSearcher = new DirectorySearcher(entry)
      {
       SearchScope = SearchScope.Subtree,
       Filter = "(&(objectClass=user)(samaccountname=" + userInQuestion + "))"
      };

    var userObject = adSearcher.FindOne();

    if (userObject != null)
      {
       email = string.Format("{0}", userObject.Properties["mail"][0]);
      }
       
       return email;
 }

Typically, I put functions like this in my Utility class but you can put it where ever you see fit. Below is an example of how to execute this function.
 
var email = Utility.DisplayUser(WindowsIdentity.GetCurrent());



Retrieve OS version with Javascript

Recently, I was given a task to find out what OS version an end users machine was running on.  The reason I need this information was to check if the user should be running the application on IE9 32bit or IE9 64bit.  Now, this might not sound very useful but given the environment I was working in, the end user could be having an awkword experience.

 
 <script type="text/javascript">
      function checkOSVersion() {
        if (navigator.userAgent.indexOf("WOW64") != -1 || navigator.userAgent.indexOf("Win64") != -1) 
           {
             alert("This is a 64 bit OS");
           } 
        else 
            {
                alert("Not a 64 bit OS");
            }
           }
    </script>

Sunday, February 23, 2014

Using FileUpload with JQuery Mobile

One of the more irritating situations I've come across with JQuery Mobile is using ASP.FileUpload control. Whenever you hit submit to upload a file, the FileUpload control doesn't get the file. Basically, you end up with an empty string when it tries to save. I finally was able to figure it out after doing some digging around in the JQuery Mobile API. The below example shows what needs to be set to allow the FileUpload control to work.


In order to allow your FileUpload control work, you'll need to set data-ajax="false" where ever your form tag is located.

 
<form data-ajax="false" id="form1" runat="server">
</form>

Saturday, February 1, 2014

Binding returned data from an Ajax call to a Gridview

First, I have to say this was one of my most frustrating functions I've ever created. The biggest problem I faced was trying to get the data from the Ajax call to bind to the Gridview. As you'll see in this example, once the data returns, I loop through the xml and append a table row to the Gridview.


You'll need the JQuery reference in the head section.

 <script src ="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type ="text/javascript">

For this first function you'll need to change the url in the ajax call to either the page your creating the Ajax call or the page your getting the post from which can also be a web service or handler. Then don't forget to set the method name after the page or web service your calling.

 function Button1_onclick() {
    $.ajax({
            type: "POST",
            data: '{}',
            contentType: "application/json; charset=utf-8",
            url: "AjaxTest.aspx/GetTransactionData",
            dataType: "xml",
            success: OnSuccess,
            error: function (XMLHttpRequest, textStatus, errorThrown) {
              $("#errmsg").ajaxError(function (event, request, settings) {
              $(this).append("<li>Error requesting page " + settings.url + "</li>");
           });
         }
      });
           return false;
    }

The next function will loop through the returned xml and append a table row for each row found in the xml to the Gridview.

 function OnSuccess(xml) {
   debugger;
    try {
         $(xml).find('Table1').each(function () {
          var id_text = $(this).find('ID').text();
          var name_text = $(this).find('Description').text();

          $('#<%=GridView1.ClientID %>').append("<tr><td>" + id_text + "</td><td>" + id_text + "</td</tr>");
        });
        }
    catch (err) {
        var txt = "There was an error on this page.\n\n";
        txt += "Error description: " + err.description + "\n\n";
        txt += "Click OK to continue.\n\n";
        alert(txt);
       }
     }

Below is the form example used to initiate the ajax call.

 <input id="Button1" type="button" value="Get XML" onclick="return Button1_onclick()" />
            <asp:GridView ID="GridView1" runat="server"></asp:GridView>

Finally, this is where you'll fill the data that gets returned to the client side. You'll need to add a WebMethod to your ".CS" page then create your data table and fill it from either a direct database call or web service to return the xml. In the example below, I'm creating my initial data table columns in the Page_Load so that when the Ajax call returns, it knows what columns are mapped to the Gridview.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
protected void Page_Load(object sender, EventArgs e)
    {
        DataTable table = new DataTable();
        table.Columns.Add("ID");
        table.Columns.Add("Description");
        table.Rows.Add();
        GridView1.DataSource = table;
        GridView1.DataBind();
    }

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
    public static string GetTransactionData()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("ID");
        dt.Columns.Add("Description");

        dt.Rows.Add("1", "Description 1");
        dt.Rows.Add("2", "Description 2");
        dt.Rows.Add("3", "Description 3");
        dt.Rows.Add("4", "Description 4");
        dt.Rows.Add("5", "Description 5");

        DataSet m_dsDataSet = new DataSet("pageDataSet");

        m_dsDataSet.Tables.Add(dt);

        string strXml = m_dsDataSet.GetXml();
        return strXml;
    }

Monday, January 27, 2014

Binding Nested Detailsview in Gridview

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            GridViewRow row = e.Row;

            // Make sure we aren't in header/footer rows
            if (row.DataItem == null)
            {
                return;
            }

            DetailsView dv = (DetailsView)row.FindControl("DetailsView1");

            List<[object]> aList = List<[object]>();

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                aList[e.Row.RowIndex].Name = aList[e.Row.RowIndex].Name;

                dv.DataSource = aList.Where(u => u.ID == Convert.ToInt32(aList[e.Row.RowIndex].Address)).ToList();
                dv.DataBind();
            }
        }