asp:PlaceHolder can be put within html table, if the table is not runat=”server”

I had a table in user control, taht included asp:PlaceHolder. In the code some other user controls are loaded into the placeholder.
            <table cellSpacing=”0″ cellPadding=”0″ border=”0″ >
                        <TR>
                              <TD >Header</TD>
                        </TR>
                        <asp:PlaceHolder id=”plc1″ Runat=”server”></asp:PlaceHolder>
                  <table>

It worked fine until I decided make the table  conditionally invisible based on some server logic. I’ve added an ID ans runat=”server” to the table and got an error:

System.Web.HttpCompileException: error CS1502: The best overloaded method match for ‘System.Web.UI.HtmlControls.HtmlTableRowCollection.Add(System.Web.UI.HtmlControls.HtmlTableRow)’ has some invalid arguments

To solve the problem I had to wrap table in asp:panel
                     <asp:panel id=”pnl1″ runat=”server” Visible=”false” BorderWidth=”0″>
                  <table cellSpacing=”0″ cellPadding=”0″ border=”0″ >
                        <TR>
                              <TD >Header</TD>
                        </TR>
                        <asp:PlaceHolder id=”plc1″ Runat=”server”></asp:PlaceHolder>
                  <table>
            </asp:panel>

NullReferenceException in EntitySpaces_C#_ASPX.csgen template after copy template instance

I am using MyGeneration Project  to generate admin web pages using EntitySpaces Templates for ASP.NET  . Filling templates is  very time consuming, and I decided to copy  template instance for one table as a start point for other table. It didn’t save much , because it require you to do everything differently for each table anyway. And it also causes an errors.
I’ve done selections im multiple tabs, but when I Executed template instances, I’ve got errors
**ERROR*** [NullReferenceException] Object reference not set to an instance of an object.
Canceled Template execution: EntitySpaces C# ASPX Page.
 
I would prefer to see mote detailed(with full call stack) message from MyGeneration.
 Fortunately, templates are relatively  easy to Debug  , and I found that when I’ve copied template instance, foreign keys from one table were copied to another, even if they are not applicable.
Debugger showed  lookupColumns={|CountryCode|FK_tblCarHireCompanyCountries_tblRefCountryName|CountryName^|HireCompanyCode|FK_tblCarHireCompanyCountries_tblRefCarHireCompanies|ShortName}

During execution code reads the foreign key name for a table and tryes to foreign key. If the name is wrong, it returns null, which causes the NullReferenceException in the call to

 Dnp.Utils.TableRelation(table, fk);
It is relatively easy to fix code by adding not null check.but there are a few places in the code where it should be done.
For example see my changes  in bold:
 
 // Lookups section
                              IForeignKey fk = table.ForeignKeys[fkName];    
                              if(fk!=null) //mnf
                              {//mnf
                                    Dnp.Utils.TableRelation tr = new Dnp.Utils.TableRelation(table, fk);
                        %>
            this.vlnk<%=esPlugIn.PropertyName(col)%>.Text = <%=tr.LookupName%>(entity.<%=esPlugIn.PropertyName(tr.PrimaryColumns[0])%>);
            this.vlnk<%=esPlugIn.PropertyName(col)%>.NavigateUrl = Globals.ApplicationPath + “/tabid/” + TabId + “/pagename/<%=esPlugIn.Entity(tr.ForeignTable)%>/<%=esPlugIn.PropertyName(tr.ForeignColumns[0])%>/” + entity.str.<%=esPlugIn.PropertyName(tr.PrimaryColumns[0])%> + “/default.aspx”;<%
                              }//mnf
  Mike.Griffin promises  that the ASP.NET templates will be completely fixed in EntitySpaces 2008.
I’ve reported the problem on EntitySpaces forum in
 
NullReferenceException in EntitySpaces_C#_ASPX.csgen template whe…

 Related link:My notes about MyGeneration Templates.

My HttpRequestHelper class

Previously I’ve posted a few Helper Classes . This post describes my HttpRequestHelper class.
      using System;
      using System.Text;
      using System.Web;
      using System.Web.UI;
      using System.Web.UI.WebControls;
 
      ///<summary>
      /// Summary description for HttpRequestHelper.
      ///</summary>
      public class HttpRequestHelper
      {
            // Methods
            public HttpRequestHelper()
            {
            }
            // from http://groups.google.com.au/groups?hl=en&lr=&threadm=oOiDc.121011%24Sw.26011%40attbi_s51&rnum=1
            public static bool IsBrowserOnServer()
            {
                  bool foundIPmatchFlag = false; // Assume no match
                  string userHostAddr= HttpContext.Current.Request.UserHostAddress;
                  string serverhost = Dns.GetHostName(); // get name of server
            IPHostEntry ipserverhost = Dns.GetHostEntry(serverhost);// GetHostByName
                  IPAddress[] addresses = ipserverhost.AddressList; // get list
                  // Look for an IP address match
                  foreach ( IPAddress address in addresses )
                  {
                        if (userHostAddr == address.ToString())
                        {
                              foundIPmatchFlag = true; // got a match
                              break;
                        }
                  }
                  if(foundIPmatchFlag == false) //try more options in case if DNS is not working
                  {
                        if (userHostAddr == “127.0.0.1”)
                        {
                              foundIPmatchFlag = true; // got a match
                        }
                        else
                        {
                              string userhostName=HttpContext.Current.Request.UserHostName;
                              userhostName=userhostName.ToLower();
                              if ( (userhostName== “localhost”)||(userhostName== serverhost.ToLower()) )
                              {
                                          foundIPmatchFlag = true; // got a match
                              }
                        }
                  }
                  return foundIPmatchFlag;
            }
 
            //created 15/4/2005
            public static string HttpURL(string ServerName, string VirtualDirectory, string ServiceUrl)
            {
            return UriHelper.CombineUrl(HttpBaseUrl(ServerName, VirtualDirectory), ServiceUrl); //8/5/2006 use CombineUrl
            }
        ///<summary>
        /// Returns BaseUrl(e.g. http://Server/VirtualDirectory/” including tailing “/”
        ///</summary>
        ///<param name=”ServerName”></param>
        ///<param name=”VirtualDirectory”></param>
        ///<returns></returns>
            public static string HttpBaseUrl(string ServerName, string VirtualDirectory)
            {
                  string sBaseUrl=string.Format(“{0}/{1}/”, ServerName,VirtualDirectory);
                  if(false==sBaseUrl.ToLower().StartsWith(“http://”))
                  {
                        sBaseUrl=“http://”+sBaseUrl;
                  }
                  return sBaseUrl;
            }
//from http://www.thescripts.com/forum/thread344270.html
        ///<summary>
        /// consider invalid URI as null
        ///</summary>
        ///<param name=”Request”></param>
        ///<returns></returns>
        public static Uri SafeUrlReferrer(HttpRequest Request)
        {
            Uri uriReferrer = null;
            try
            {
                uriReferrer = Request.UrlReferrer;
            }
            catch (UriFormatException exc)//ignore errors Invalid URI: The hostname could not be parsed
            {
                //consider invalid as null,            //ignore in production
                Debug.Assert(false, “just debug when it happens” + exc.ToString());
            }
            return uriReferrer;
        }
        public static string GetReferrerHost(HttpRequest Request)
        {
            Uri uriReferrer = SafeUrlReferrer(Request);
            string referrerHost = null;
            if (uriReferrer != null)
            {
                referrerHost = uriReferrer.Host.ToUpper();
            }
            else
            {
                referrerHost = string.Empty;
            }
            return referrerHost;
        }

 

      }
 
 

My HtmlHelper class

Previously I’ve posted a few Helper Classes . This post describes my HtmlHelper class:

      using System;
      using System.Text;
      using System.Web;
      using System.Web.UI;
      using System.Web.UI.WebControls;
 
      ///<summary>
      /// Summary description for HtmlHelper.
      ///</summary>
      public class HtmlHelper
      {
            // Methods
            public HtmlHelper()
            {
            }
 
            public static void AddBookMark(Control parent, string bookMarkName)
            {
                  LiteralControl control1 = new LiteralControl();
                  control1.Text = “<a name=”” + bookMarkName + “”>”;
                  parent.Controls.Add(control1);
            }
            //    ‘idea from http://www.dotnetjunkies.com/Article/6614EF8F-2ADB-4AEB-B2B7-D96278B53D74.dcik
            //    ‘MNF seems that I can’t use bookmark this way.BookMark appends to url and seems lost viewstate
            //    ‘Didn’t find workaround so far -see for research http://www.eggheadcafe.com/articles/20030531.asp
            public static void GoToBookMark(Page page, string bookMarkName)
            {
                  StringBuilder sb = new StringBuilder();
                  sb.Append(“”);
                  sb.Append(“location.href=”#” + bookMarkName + “”;”);
                  sb.Append(“”);
                  page.ClientScript.RegisterClientScriptBlock(TypeForClientScript(),“GoToBookMark”, sb.ToString());
            }
 
            public static string ReplaceNewLine(string sMsg)
            {
                  return sMsg.Replace(Environment.NewLine, NewLine);
            }
 
            //    ‘set text and tooltip
            public static void SetClickToBtnText(Button btn, string text)
            {
                  btn.ToolTip = “Click here to “ + text;
                  btn.Text = text;
            }
 
            public static string WriteLine(HttpResponse Response, string sMsg)
            {
                  string text1= WriteLine( sMsg);
                  Response.Write(text1);
                  return text1;
            }
            public static string WriteLine( string sMsg)
            {
                  return sMsg + NewLine;
            }
 
            ///<summary>
            /// Function replaces 2 or more spaces to one space.
            /// Function was created for use MetaBuilder ComboBox to modify list values.
            /// Client DHTML innerText replaces multiple spaces with one,
            /// but when return back to server string with single space doesn’t match Listbox strings in ListItemCollection.FindByText Method
            ///</summary>
            public static string RemoveNonPreservedSpace(string strText)
            {
                  Regex reNonPreservedText = new Regex(@”s{2,}”, RegexOptions.IgnoreCase);
                  // Do the replacements
                  strText = reNonPreservedText.Replace(strText, ” “);
                  return strText;
            }
            //from ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/vbcon/html/vbwlkWalkthroughCreatingCustomWebControls.htm
            public static string WriteHyperLinkHtml(string Url,string Text)
            {
                        StringWriter sw = new StringWriter();
                        HtmlTextWriter tw = new HtmlTextWriter(sw);
 
                        HyperLink placeholderLink = new HyperLink();
 
                        // put control text into the link’s Text
                        placeholderLink.NavigateUrl = Url;
                        if ((Text==null) || (0==Text.Length)) Text=Url;
                        placeholderLink.Text = Text;
                        placeholderLink.RenderControl(tw);
 
                        return sw.ToString();
            }
        private static Type TypeForClientScript()
        {
            return typeof(HtmlHelper);
        }
 
 
            // Fields
            public const string NewLine = “<BR />”;
      }
 

My StringArrayHelper class

Previously I’ve posted a few Helper Classes . This post describes my StringArrayHelper class:

    using Iesi.Collections;
    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using System.Xml;
    using System.Text;
 
    public static class StringArrayHelper
    {
        //created from CollectionsHelper.cs
        // Methods
            //’ignore new string, if already exist in the array
            // empty string considered as separate entry
            // function is case sensitive
            public static string[] AddToArray(string[] arrStrings, string NewString)
        {
                  if (null==arrStrings)
                  {
                        arrStrings=new string[0];
                  }
            if (Array.IndexOf(arrStrings, NewString) < 0)
            {
                ArrayList list1 = new ArrayList(arrStrings);
                list1.Add(NewString);
                return (string[]) list1.ToArray(Type.GetType(“System.String”));
            }
            return arrStrings;
        }
        // empty string considered as separate entry
        // function is case sensitive
        public static bool Replace(string[] arrStrings, string OldString,string NewString)//,bool bCaseSensitive)
        {
            if(arrStrings==null){   throw new ArgumentNullException(“arrStrings”);}
            int nPos = Array.IndexOf(arrStrings, OldString);
            if (nPos >= 0)
            {
                arrStrings[nPos] = NewString;
                return true;
            }
            return false;
        }
 
 
//          ‘May be useful? http://www.peterblum.com/CollectionsLibrary/AutoSortArrayList.aspx
//          ‘ignore duplicate strings
            public static string[] MergeArrays(string[] arrStrings, string[] NewArray)
        {
            ArrayList list1;
            if (arrStrings == null)
            {
                list1 = new ArrayList();
            }
            else
            {
                list1 = new ArrayList(arrStrings);
            }
            if(NewArray!=null)
            {
                list1.AddRange(NewArray);
                //        ‘Use Set to Remove Duplicates in an ArrayList http://www.devx.com/tips/Tip/20864
                // Iesi.Collections from http://www.codeproject.com/csharp/sets.asp#xx1367973xx ‘
                // alternatively use http://www.itu.dk/research/c5/ or http://www.codeproject.com/csharp/GenericISet.asp
                HybridSet set1 = new HybridSet(list1);
                list1.Clear();
                list1.AddRange(set1);
            }
            return (string[]) list1.ToArray(Type.GetType(“System.String”));
        }
 
        public static string[] RemoveEmptyLines(string[] arrStrings)
        {
            ArrayList list1 = new ArrayList(arrStrings);
            IEnumerator enumerator1 = arrStrings.GetEnumerator();
            while (enumerator1.MoveNext())
            {
                if (DataHelper.IsDBNullOrEmpty(RuntimeHelpers.GetObjectValue(enumerator1.Current)))
                {
                    list1.Remove(RuntimeHelpers.GetObjectValue(enumerator1.Current));
                }
            }
            return (string[]) list1.ToArray(Type.GetType(“System.String”));
        }
        public static string[] Trim (string[] arrStrings)
        {
            // http://blogs.msdn.com/marcod/archive/2005/11/01/GenericForEach.aspx
         //doesn’t work   Array.ForEach<string>(arrStrings, new Action<string>(delegate(string s)   { s = s.Trim(); }));
            for (int i = 0; i < arrStrings.Length; i++)
            {
                arrStrings[i] = arrStrings[i].Trim();
            }
            return arrStrings;
        }
        //24/10/2006 moved from StringHelper
        public static string[] ToLower(string[] Strings)
        {
            if (Strings != null)
            {
                for (int i = 0; i < Strings.Length; i++)
                {
                    Strings[i] = Strings[i].ToLower();
                }
            }
            return Strings;
        }
        public static string ConvertToQuotedCommaSeparatedValues(string[] asVal)
        {
            return ConvertToQuotedCommaSeparatedValues(asVal, true);
        }
        public static string ConvertToQuotedCommaSeparatedValues(string[] asVal,bool bIgnoreNullOrEmpty)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string s in asVal)
            {
                if (!String.IsNullOrEmpty(s))
                {
                    sb.AppendFormat(“{0},”, DataHelper.Quoted(s.Trim()));
                }
                else
                {if(bIgnoreNullOrEmpty==false)
                    {
                     sb.AppendFormat(“”,”);
                    }
                }
            }
            string sRet = StringHelper.LeftBeforeLast(sb.ToString(), “,”);
            return sRet;
        }
 
    }//end of 
 


My ArrayHelper class.

Previously I’ve posted a few Helper Classes . This post describes my ArrayHelper class.

    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using System.Xml;
 
    public static class ArrayHelper
    {
            public static void FillBytesRange(Array array,int indexStart,int indexEnd,      byte value)
        {
            for (int i = indexStart; i <= indexEnd; i++)
            {
                Buffer.SetByte(array, i, value);
            }
        }
    }//end of class ArrayHelper
 

 

Generic LoadFromCache method to reliably read data from cache.

The typical procedure to work with cache is
1.to check if item for specified key exist in a cache;
2.if yes, return it;
3.if no, create it (e.g load from database),
4.save to the cache
5. and then return it.
Some developers use the code like the following
:

If (DataCache.GetCache[“key”] == null)
{   // code for loading object
   …
   
DataCache.SetCache(“key”, obj);
}
return DataCache.GetCache[“key”]; //Not good, can cause problems (at least in ASP.Net 2.0).
Sometimes SetCache is not effected immediately(or expired immediately) and subsequent GetCache returns null.

Back in 2006 I lost a lot of time trying to debug the problem in DotNetNuke “DataCache.GetCache usage pattern causes random Null reference exceptions”.
Now in a different application I noticed the same unreliable pattern.

To avoid mistakes and make process of getting objects from cache consistent, I’ve created a Generic function with delegate as a parameter  to implement the safe pattern.

<!–

.csharpcode{font-size: 10pt;color: black;font-family: Courier New , Courier, Monospace;background-color:Transparent;}.csharpcode pre { margin: 0px; }.rem { color: #008000; }.kwrd { color: #0000ff; }.str { color: #006080; }.op { color: #0000c0; }.preproc { color: #cc6633; }.asp { background-color: #ffff00; }.html { color: #800000; }.attr { color: #ff0000; }.alt{background-color: #f4f4f4;width: 100%;margin: 0px;}.lnum { color: #606060; }

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
 
    public static class CacheHelper
    {
        
public delegate T CreateInstanceDelegate<T>();
        public  static T  LoadFromCache<T>(String cacheKey, CreateInstanceDelegate<T> dlgt) where T:class 
        {
            T coll = HttpRuntime.Cache[cacheKey] as T;
            if (coll == null)
            {
                coll = dlgt() as T;
                if (coll != null)
                {
                    HttpRuntime.Cache[cacheKey] = coll;
                }
            }
            return coll;
        }
       public static string GetFileFromHttpServerToCache(String url,bool throwIfNotFound) 
        {
            //TODO: alternatively  add file dependancy
            //System.Web.HttpContext.Current.Cache.Add(cacheKey, contents, new CacheDependency(fileName), DateTime.MaxValue, TimeSpan.FromHours(2), CacheItemPriority.Normal, null);
            String content = CacheHelper.LoadFromCache<String>(url, delegate
            {
              string filePath=  HttpContext.Current.Server.MapPath(url);
              if (throwIfNotFound == false && !File.Exists(filePath))
              {
                  return "";
              }
              string sContent = StreamHelper.FileToString(filePath);
              return sContent;
            });
            return content;
        }
       public static string GetFileFromHttpServerToCache(String url,bool throwIfNotFound) 
        {
            //TODO: alternatively  add file dependancy
            //System.Web.HttpContext.Current.Cace.Add(cacheKey, contents, new CacheDependency(fileName), DateTime.MaxValue, TimeSpan.FromHours(2), CacheItemPriority.Normal, null);
            String content = CacheHelper.LoadFromCache<String>(url, delegate
            {
              string filePath=  HttpContext.Current.Server.MapPath(url);
              if (throwIfNotFound == false && !File.Exists(filePath))
              {
                  return "";
              }
              string sContent = StreamHelper.FileToString(filePath);
              return sContent;
            });
            return content;
        }

}
Example of call, utilizing C# anonymous delegates(available starting from .Net 2.0) :
           MyClass entity =
                CacheHelper.LoadFromCache<MyClass >(sCacheKey, delegate
                {
                    return LoadFromDb(localParameters);
                });
Another article describing similar approach is The ‘Reluctant Cache’ Pattern
Related(sort of) links: New feature about Generics in .Net 3.5