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
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/
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