Blog Archives

asp .net could not establish trust relationship for the SSL/TLS secure channel

A quick google search revealed multiple reported resolutions, however, after following the steps in the MSDN blog reference listed below, the issue was still unresolved in my situation.

Additional details in the stack trace will reveal another similar message: “The remote certificate is invalid according to the validation procedure.”

In this specific scenario, the site in question is either not configured with a wildcard certificate for a subdomain of the parent site or the operation system I am working on does not support SNI. In the meantime, a workaround is needed to continue testing and development.

Additional reading on google revealed another solution which was more suitable and utilized a code based approach, as opposed to a server configuration based solution.

To make it more dynamic, I added a key into the app/web config to control if SSL errors should be ignored. Please note that it is also possible to replace the code based approach solely with an app/web config entry listed in the west-wind blog referenced below, but I personally prefer to go with code whenever possible.

<?xml version="1.0"?>
<configuration>
  <configSections>
  </configSections>
  <connectionStrings>
    <add name="ConnectionString"
      connectionString="Data Source=servername;Initial Catalog=databasename;"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="ignoresslerrors" value="true"/>
  </appSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
 public class ConfigValues
    {
        public static string IgnoreSSLErrors { get { return getval("ignoresslerrors"); } }
}

public function main() {
connect("https://sitename.com",ConfigValues.IgnoreSSLErrors);
}

public function connect(string url, string ignoresslerrors) {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

try
            {
                if (Convert.ToBoolean(ignoresslerrors))
                {
                    System.Net.ServicePointManager.ServerCertificateValidationCallback +=
            delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
            {
                return true; //will always accept the cert and ignore errors. this is not good common practice unless you are sure of the destination you are connecting to. needed in this scenario to continue development until issue with cert is resolved.
            };
                }
            }
            catch (Exception ex)
            {
                Shared.HandleError(ex);
            }
}

References

http://www.west-wind.com/weblog/posts/2011/Feb/11/HttpWebRequest-and-Ignoring-SSL-Certificate-Errors

http://blogs.msdn.com/b/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is-invalid-according-to-the-validation-procedure.aspx

slideshowpro dynamic images xml file output with classic asp

outputxml() 

'--------------------------------
'generates xml file with some static info and some dynamic for use by slideshowpro
'in slideshowpro simply replace images.xml with the name of this file
'--------------------------------

sub outputxml()
Response.ContentType = "text/xml"

outputxmlheader()
outputxmlbody()
outputxmlfooter()
end sub

sub outputxmlheader()
Response.Write("<?xml version=""1.0"" encoding=""UTF-8""?>")
Response.Write("<gallery title=""My Photos"" description="""">")
end sub

sub outputxmlfooter()
Response.Write("</gallery>")
end sub

sub outputxmlbody()
call outputalbumandfiles(Server.MapPath("/myphotos/img/20121031event"),"a1","2012 Event A","Event A Description.","img/20121031event/","ico/eventa.jpg")

call outputalbumandfiles(Server.MapPath("/companyphotos/img/20121120event"),"a2","2012 Event B","Event B Description.","img/20121120event/","ico/eventb.jpg")
end sub

sub outputalbumandfiles(path,id,title,description,lgpath,tn)
Response.Write("<album id=""" & id & """ title=""" & title & """ description=""" & description & """ lgPath=""" & lgpath & """ tn=""" & tn & """>")

set fs = CreateObject("Scripting.FileSystemObject")
    set folder = fs.GetFolder(path)
	
	for each item in folder.Files
	 if FilterExtensions(item.Name) then
	 Response.Write("<img src=""" & item.Name & """ target=""_blank"" />")
		 end if
     next

	 'TODO: set objects = nothing
Response.Write("</album>")
end sub
   
'filter out .db files and any other files you do not want to slideshowpro to load
'alternative you can reverse the logic to allow only jpg, png etc
   function FilterExtensions(fn)
FilterExtensions=true
   a_ext = Array(".db",".db") 'place additional extensions here 
   for each ext in a_ext
      i = InStrRev(fn,ext)
   if i>0 then
   FilterExtensions=false
   next
   end function

References
http://support.microsoft.com/kb/301244

Classic ASP VB Filter File Name Extensions From String EndsWith

Came across a classic ASP VB site recently in my adventures. There was a feature request to filter out some file extensions from existing code logic, and I discovered quickly most of my .Net methods were unavailable, so I came up with this little snippet and had a great blast from the past. :)

   function FilterExtensions(fn)
   FilterExtensions=true
   a_ext = Array(".db",".db") 'place additional extensions here 
   for each ext in a_ext
      i = InStrRev(fn,ext)
   if i>0 then
   FilterExtensions=false
   end if
   next
   end function

If FilterExtensions returns true then there were no matches (extension of filename successfully passed all filters).

lastChild is null in FireFox works in IE invalid nodeType javascript c# asp .net

This issue alluded me at first as it works in IE but not in FF. See code below.

//pass in table, last cell number and style to apply to it. call this on hover and blur for cell highlight effects. alternatively you can determine last cell number as well and this function could be rewritten to work solely for the purpose of modifying specific cells rather than last cell
function ChangeTableCellStyle(tableid,cellnumber,mystyle) {
if (document.getElementById)
{
var selectedElement = document.getElementById(tableid);
selectedElement.className = style;
//change style on end cell by drilling into table. this will become deprecated by css3.
if (selectedElement.tagName.toLowerCase()=="table")
{

var tbody = selectedElement.lastChild;
if (tbody!=null)
{
var tr = tbody.lastChild;
if (tbody !=null)
{
var tr = tbody.lastChild; //BUGGED IN FF!

//nodetype should be 1 for element type. in FF it is 3. see reference link at bottom for list of types.
if (tr.nodeType!=1) {
tr.tbody.getElementsByTagName("td");
tr[cellnumber].className+= ' ' + mystyle;
} else {
tr.lastChild.className+=' ' + mystyle;
}

}
}

}
}

}

//example usage
ChangeTableCellStyle("table1",3,"cellend"); //will append the class cellend to the last cell in table1 if table1 only has 4 cells per row

In you’re interested in reviewing other approaches to styling your table cells, see my similar article here.

pass null to sql data source select

sds.CancelSelectOnNullParameter = false;

References
http://forums.asp.net/t/963932.aspx

Serialize C# object to JSON JavaScriptSerializer .Net

//declare data you want to send as an object type
public class MyType {
//may simply contain properties mapping to your database rows or be more complex objects
//use [Serializable] attributes to mark props or methods as non-serialized
}
public void Page_Load(object sender, EventArgs e) {
MyType o1 = new MyType {p1="",p2=""};


Response.Write(JSONSerialize(o1));

Response.Write("<br /><br />");

MyType o2 = new MyType {p1="",p2=""};
List<MyType> olist = new List<MyType> {o1, o2};

Response.Write(JSONSerialize(olist));
}

public string JSONSerialize(MyType o) {
System.Web.Script.Serialization.JavaScriptSerializer sz = 
         new System.Web.Script.Serialization.JavaScriptSerializer();
return sz.Serialize(o);
}

//additional signature to handle lists of object
public string JSONSerialize(List<MyType> o) {
System.Web.Script.Serialization.JavaScriptSerializer sz = 
         new System.Web.Script.Serialization.JavaScriptSerializer();
return sz.Serialize(o);
}

References
MS Blogs, http://blogs.microsoft.co.il/blogs/pini_dayan/archive/2009/03/12/convert-objects-to-json-in-c-using-javascriptserializer.aspx
JSON.org, http://www.json.org/js.html
C# Cross-Site Page Access, http://stackoverflow.com/questions/6290053/setting-access-control-allow-origin-in-asp-net-mvc-simplest-possible-method
PHP Cross-Site Page Access, http://rayfd.wordpress.com/2007/03/28/why-wont-eval-eval-my-json-or-json-object-object-literal/
JS Eval string to JSON Object, http://rayfd.wordpress.com/2007/03/28/why-wont-eval-eval-my-json-or-json-object-object-literal/

asp .net c# luhn algorithm validation mod10 with realtime clientside Javascript

Read the rest of this entry

C# ListBox Management Adding Removing Updating Databound Items ASP .Net

The lambda one-liner indicated in the snippet below essentially nests at least two “for/foreach” loops. See my related article for full source.

This code snippet is used to populate a drop down list of all factories containing unregistered robots where are not already marked in the list to be decommissioned.

Upon selecting a factory containing unregistered robots, another listbox is populated with the robots so they can be selected from which moves them into the decommissioned list.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;

public partial class DecommissionRobots : System.Web.UI.UserControl
{
public event EventHandler SendToDecommission;

    public void Update()
    {
        upnlContainer.Update();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            LoadRegions();
            txtExpDate_CalendarExtender.SelectedDate = DateTime.UtcNow.AddMonths(6);
        }
    }

    protected void LoadRegions()
    {
        using (AndroneticsDataContext db = new TigrentLearningDataContext(
        ConfigurationManager.ConnectionStrings["AndroneticsConnection1"].ConnectionString)) {
        ddlRegions.DataSource = db.UP_GET_REGIONS();
        ddlRegions.DataTextField = "REGION";
        ddlRegions.DataValueField = "REGION_ID";
        ddlRegions.DataBind();

        ListItem li = new ListItem("", "");
        ddlRegions.Items.Insert(0, li);
}
    }

    protected void ClearLists()
    {
        lstUnselectedRobots.Items.Clear();
//you may want to clear other lists in this manner in your app as well
    }

protected void LoadFactories()
    {
        ClearLists();

        if (ddlSegment.SelectedIndex > 0)
        {
            using (AndroneticsDataContext db = new AndroneticsDataContext(
        ConfigurationManager.ConnectionStrings["AndroneticsConnection1"].ConnectionString))
            {
                List<UP_GET_FactoriesResult> allFactories = db.UP_GET_Factories(Convert.ToInt32(ddlRegion.SelectedValue), null).ToList();

                ////this would be approximately how you would approach traditionally
                //foreach (UP_GET_FactoriesResult r in allFactories)
                //{
                //    if (GetUnregisteredRobots(r.FACTORY_ID).Count != 0)
                //    {
                //        //etc, would need another loop here
                //    }
                //}

                //now for the lambda way
                var Factories = allFactories.Where(
                    r => GetUnregisteredRobots(r.FACTORY_ID).Where(
                        ra => !lstDecommissionRobots.Items.Contains(new ListItem(ra.ROBOT_NAME,ra.ROBOT_ID.ToString()))).Count() != 0);

                ddlFactories.DataSource = Factories;
                ddlFactories.DataTextField = "FACOTRY_TITLE";
                ddlFactories.DataValueField = "FACTORY_ID";
                ddlFactories.DataBind();

                ListItem li = new ListItem("", "");
                ddlFactories.Items.Insert(0, li);
            }
        }
    }

    private List<UP_LOAD_COURSE_RobotsResult> GetUnregisteredRobots(int courseid)
    {
        using (AndroneticsDataContext db = new AndroneticsDataContext(
        ConfigurationManager.ConnectionStrings["AndroneticsConnection1"].ConnectionString))
        {
            List<UP_LOAD_COURSE_RobotsResult> allRobots = db.UP_LOAD_COURSE_Robots(courseid).ToList();

            int userID = int.Parse(Request.QueryString["ID"]);
            List<string> excregisteredRobots = (from m in db.UP_GET_REGISTERED_Robots(userID) select m.MODULE_NAME).ToList();

            return allRobots.Where(m => !excregisteredRobots.Contains(m.MODULE_NAME)).ToList();
        }
    }

protected void LoadUnregisteredRobots()
    {
        lstUnselectedRobots.Items.Clear();

        //we need to make sure a re=d-g.and FACTORY were selected.
        if (ddlFactories.SelectedIndex > 0 && ddlRegion.SelectedIndex > 0)
        {
//notice this reuses the same code as above any simple retrieves the results for value selected in the dropdown. this value is updated by autopostback true set on the aspx page side.
            lstUnselectedRobots.DataSource = GetUnregisteredRobots(Convert.ToInt32(ddlFactories.SelectedValue));
            lstUnselectedRobots.DataTextField = "Robot_NAME";
            lstUnselectedRobots.DataValueField = "Robot_ID";

            lstUnselectedRobots.DataBind();
        }
    }

protected void btnSelect_Click(object sender, ImageClickEventArgs e)
    {
        List<ListItem> selectedItems = new List<ListItem>();

        //add all the selected items to a list
        foreach (ListItem li in lstSelectItems.Items)
        {
            if (li.Selected)
            {
                selectedItems.Add(li);
            }
        }

        //add the selected items to the selected box
        lstSelectedItems.Items.AddRange(selectedItems.ToArray());

        //remove the selected items from the original list
        foreach (ListItem items in selectedItems)
        {
            lstUnselectedRobots.Items.Remove(items);
        }

        LoadFactories();
    }

    protected void btnRemove_Click(object sender, ImageClickEventArgs e)
    {
        List<ListItem> selectedItems = new List<ListItem>();

        //add all the selected items to a list
        foreach (ListItem li in lstSelectedItems.Items)
        {
            if (li.Selected)
            {
                lstDecommissionRobots.Add(li);
            }
        }

        //add the selected items back to the initial selection box
        lstUnselectedRobots.Items.AddRange(selectedItems.ToArray());

        //remove the selected items from the selected list
        foreach (ListItem items in selectedItems)
        {
            lstDecommissionRobots.Items.Remove(items);
        }

        LoadFactories();
    }

    protected void btnSend_Click(object sender, ImageClickEventArgs e)
    {
        List<USER_ACCESS> FactoryItems = new List<USER_ACCESS>();
        int userid= int.Parse(Session["userid"].ToString());

        try
        {
            if (lstDecommissionRobots.Items.Count > 0)
            {
                //for each Factory item that's selected, add it to the Factory list
                foreach (ListItem li in lstDecommissionRobots.Items)
                {
                    USER_ACCESS regFactory = new USER_ACCESS()
                    {
                        USER_ID = studentID,
                        Robot_ID = Convert.ToInt32(li.Value),
                        EXPIRATION_DATE = Convert.ToDateTime(txtExpDate.Text),
                        CREATED_BY = Users.CurrentUser.UserID.ToString()
                    };

                    FactoryItems.Add(regFactory);
                }

                //Make sure the list got filled and then insert the Factories into the db.
                if (FactoryItems.Count > 0)
                {
                    AndroneticsDAL dalInstance = new AndroneticsDAL();
                    dalInstance.EnrollStudent(FactoryItems);

                    //TODO: replace with update event handle
                    //PopulateFactories(userid);
                    ClearLists();
                    lstDecommissionRobots.Items.Clear();
                    ddlSegment.ClearSelection();
                    ddlFactories.ClearSelection();

                    if (SendToDecommission != null)
                    {
                        SendToDecommission(sender,e);
                    }
                }
            }
            else
            {
                //PopulateFactories(userid);
            }
        }
        catch (Exception ex)
        {
//Utility.HandleError(ex); //send to email, handle, etc or handle in global.asax
        }
    }

    protected void ddlRegion_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadFactories();
        ddlFactories.SelectedItem.Selected = false;
    }

    protected void ddlFactories_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadRobots();
    }
}

HTML/ASPX Side:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DecommissionRobots.ascx.cs" Inherits="DecommissionRobots" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:UpdatePanel ID="upnlContent" runat="server" ChildrenAsTriggers="false"
            UpdateMode="Conditional">
            <ContentTemplate>
                <asp:Panel runat="server" ID="pnlFactorieselection" GroupingText="Decommission Robots">
                    <div class="panelPadding paddingTop10 tableSize">
                        <div>
                            <div class="displayInlineLeftFloat labelSize">
                                <asp:Label runat="server" ID="lblRegion" AssociatedControlID="ddlRegion" Text="Region Name:"
                                    CssClass="labelSize"></asp:Label></div>
                            <div class="displayInlineLeftFloat FactoryDropDowns">
                                <asp:DropDownList runat="server" ID="ddlRegion" AutoPostBack="true" OnSelectedIndexChanged="ddlRegion_SelectedIndexChanged">
                                    <asp:ListItem Text="United States" Value="UnitedStats"></asp:ListItem>
                                    <asp:ListItem Text="United Kingdom" Value="UnitedKingdom"></asp:ListItem>
                                </asp:DropDownList>
                            </div>
                        </div>
                        <div class="clearFloat paddingTop10">
                            <div class="displayInlineLeftFloat labelSize">
                                <asp:Label runat="server" ID="lblFactories" AssociatedControlID="ddlFactories" Text="Factory Name:"
                                    CssClass="labelSize"></asp:Label></div>
                            <div class="displayInlineLeftFloat FactoryDropDowns">
                                <asp:DropDownList runat="server" ID="ddlFactories" AutoPostBack="true" OnSelectedIndexChanged="ddlFactories_SelectedIndexChanged">
                                </asp:DropDownList>
                            </div>
                        </div>
                        <div class="clearFloat paddingTop10">
                            <div class="displayInlineLeftFloat labelSize">
                                <asp:Label runat="server" ID="lblExpDate" AssociatedControlID="txtExpDate" Text="Expiration Date:"
                                    CssClass="labelSize"></asp:Label></div>
                            <div class="displayInlineLeftFloat">
                                <asp:TextBox runat="server" ID="txtExpDate"></asp:TextBox>
                                <asp:CalendarExtender ID="txtExpDate_CalendarExtender" runat="server" DefaultView="Months"
                                    Enabled="True" TargetControlID="txtExpDate">
                                </asp:CalendarExtender>
                            </div>
                        </div>
                        <div class="clearFloat">
                            <br />
                        </div>
                        <div>
                            <div>
                                <span class="listWidth displayInline CenterElement">Unregistered Robots</span><span
                                    id="selectedCaption" class="listWidth displayInline CenterElement">Selected
                                    Robots</span></div>
                            <div id="RegSection" class="displayInlineLeftFloat">
                                <asp:ListBox ID="lstUnregisteredRobots" runat="server" CssClass="FloatLeft listWidth" Rows="10"
                                    SelectionMode="Multiple"></asp:ListBox>
                                <div id="selectButtons" class="floatContainer">
                                    <div>
                                        <asp:ImageButton runat="server" ID="btnSelect" AlternateText="select" OnClick="btnSelect_Click"
                                            ImageUrl="~/Images/special_right.gif" /></div>
                                    <div class="buttonTopMargin5">
                                        <asp:ImageButton runat="server" ID="btnRemove" AlternateText="remove" ImageUrl="~/Images/special_left.gif"
                                            OnClick="btnRemove_Click" /></div>
                                </div>
                                <asp:ListBox runat="server" ID="lstDecommissionRobots" Rows="10" SelectionMode="Multiple"
                                    CssClass="listWidth"></asp:ListBox>
                            </div>
                            <div id="sendButton">
                                <asp:ImageButton runat="server" ID="btnSend" AlternateText="Enroll" ImageUrl="~/Images/btn_send.gif"
                                    OnClick="btnSend_Click" /></div>
                        </div>
                    </div>
                </asp:Panel>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="ddlRegion" EventName="SelectedIndexChanged" />
                <asp:AsyncPostBackTrigger ControlID="ddlFactories" EventName="SelectedIndexChanged" />
                <asp:AsyncPostBackTrigger ControlID="btnSelect" EventName="Click" />
                <asp:AsyncPostBackTrigger ControlID="btnRemove" EventName="Click" />
                <asp:AsyncPostBackTrigger ControlID="btnSend" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>

References
Fraction Of The Blogosphere, http://ronniediaz.com/2010/12/21/lambda_functions_in_-net/

C# Nested Repeaters ASP .Net

Nested repeaters are a very common topic in ASP .Net so I thought it would be a good subject to write on, especially considering the number of solutions that exist when you Google “nested repeaters” that offer plug-and-play answers, but don’t actually explain why one approach may be more optimal than another.

The Solution

XML/HTML for your repeaters:

<asp:Repeater runat="server" ID="rptRobotFactories" EnableViewState="false" OnItemDataBound="rptRobotFactories_ItemDataBound">
                        <ItemTemplate>
                            <div id="header">
                                <%# (((System.Data.DataRowView)Container.DataItem)["FACTORYNAME"]) %>
                            </div>
                            <asp:Repeater runat="server" ID="rptRobots" EnableViewState="false">
                                <HeaderTemplate>
                                    <ul>
                                </HeaderTemplate>
                                <ItemTemplate>
                                    <li>
                                        <%# Eval("ROBOTNAME") %>
                                    </li>
                                </ItemTemplate>
                                <FooterTemplate>
                                    </ul></FooterTemplate>
                            </asp:Repeater>
                        </ItemTemplate>
                    </asp:Repeater>

Code-behind to load data into rptRobotFactories:

//don't forget these guys. save the practice on your typing, finger joints will thank you later =)
using System.Data;
using System.Data.SqlClient;

//a few more variables than necessary were used for code readability. feel free to condense.
//call this function on page load. don't forget your if not postback check
    private void LoadFactories()
    {
        //don't forget to wrap in your exception handling!

          SqlConnection conn = new SqlConnection(
            ConfigurationManager.ConnectionStrings["RobotDBCon"].ConnectionString);

        SqlDataAdapter da = new SqlDataAdapter();
        SqlCommand cmd = new SqlCommand("SP_GET_ROBOTS_IN_FACTORIES", conn);

        cmd.CommandType = CommandType.StoredProcedure;
        //generally you'd probably have some parameters here

        da.SelectCommand = cmd;

        DataTable dtRobots = new DataTable("robots"); //first we get the robots
        
        da.Fill(dtRobots); //notice there's only one SP call and one datatable filled

//this might seem strange using a string array for columns, but the alternative is not as clean IMO
        string[] cols = new string[1]; //if you're uncomfortable using string as primary key add another column and use ID
        cols[0] = "FACTORYNAME";

//these next two lines are the magic makers
        DataTable dtRobotFactories = dtRobots.DefaultView.ToTable("robotfactories", true, cols).Clone();

        dtRobots.DefaultView.ToTable("robotfactories", true, cols).AsEnumerable().Distinct().CopyToDataTable(dtRobotFactories, LoadOption.OverwriteChanges);

        DataSet ds = new DataSet();
        ds.Tables.Add(dtRobotFactories);
        ds.Tables.Add(dtRobots);
       ds.Relations.Add("robotsinfactories",
ds.Tables["robotfactories"].Columns["FACTORYNAME"],
ds.Tables["robots"].Columns["FACTORYNAME"],false);
        ds.Relations[0].Nested = true;

        rptSegments.DataSource = ds.Tables["robotfactories"];
        rptSegments.DataBind();

        conn.Close();
    }

Last piece of code is our itemdatabound event of the parent repeater which loads the child data. Alternatively you can put this inline as the datasource property with a one liner but this approach may allow you more flexibility later:

    protected void rptRobotFactories_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            Repeater rptRobots = (Repeater)e.Item.FindControl("rptRobots");
            rptRobots.DataSource = ((DataRowView)e.Item.DataItem).CreateChildView("robotsinfactories");
            rptRobots.DataBind();
        }
    }

And that’s it! Your result should look something like:

FACTORY1
 *ROBOTA1
 *ROBOTA2
FACTORY2
 *ROBOTB1
 *ROBOTB2

What makes this code different?

The use of data relations is disputable. Rightfully arguable, depending on the scope of your project and the data being returned and formatted, this may be overkill.

Multiple data relations and tables can use excess resources when simple string variables could be pulled from the dataset and the same achieved with only one repeater or listview.

I do not contest this point but keep in a mind, a simple re-usable design pattern can be rapidly applied to many different sets of data, whereas a customized variable or array based solution will likely be specific to your initial implementation, and not easily re-adapted in another page or separate project.

Ultimately, code patterns will improve your code readability and productivity as a developer.

See my article on how to create secure relational databases in sql for more information on why the result should come back in a single stored procedure rather than making multiple calls.

OrderBy Column Name as String using Linq C# .Net Dynamic Sorting of Anonymous Types

If you’re familiar with Linq, you have undoubtedly used the popular “OrderBy” extension method. Unfortunately, this method does not accept a string value with the column name.

var data = from i in db.tablename
select i;

repeatername.datasource = data.OrderBy(i=>i.columnname); //this works

repeatername.datasource = data.OrderBy("columnname"); //this does not

To resolve, you can add the following small class or just the method to a generic DLL you use in your web application projects or create a new class or project for your extension methods.

Kudos to R. Prestol for help researching this one.

using System.Linq;
using System.Linq.Expressions;
using System;

namespace YourAppName.Web
{
    public static class extensionmethods
    {
        public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
        {
            var param = Expression.Parameter(typeof(T), "p");
            var prop = Expression.Property(param, SortField);
            var exp = Expression.Lambda(prop, param);
            string method = Ascending ? "OrderBy" : "OrderByDescending";
            Type[] types = new Type[] { q.ElementType, exp.Body.Type };
            var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
            return q.Provider.CreateQuery<T>(mce);
        }
    }
}

Returning to our first code snippet, you can now do:

repeater.datasource = data.OrderByField("columnname");

Since this is an extension method, and exists in a class within the same namespace as your project or other referenced assembly, you can call the method directly from the IQueryable Linq data object without requiring any other inherits; this works similar to override functionality.

Read up about extension methods on MSDN or Google for other cool tricks you can do. Enjoy. ;)

References
Extension Methods (MSDN), http://msdn.microsoft.com/en-us/library/bb383977.aspx

Follow

Get every new post delivered to your Inbox.