Click here to Skip to main content
15,896,063 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Dear all,

I am trying to create a functionality,which will display tag's name as hyperlinks, within the content of the article.

I have attempted to create a onPreRender method, which computes the above task. However, the code below, is failing to output tag names, as hyperlinks, in the article content, on the client-side.
C#
protected override void OnPreRender(EventArgs e)
 {
     var ctrl = new HtmlGenericControl("div");
   string html = this.GetArticleText();
   string link = this.CreateLinkHtml();
   string tags = this.LoadAllTags();

          html.Replace(tags, link);

      ctrl.InnerHtml = html;
      this.txtDescription.Controls.Add(ctrl);
     base.OnPreRender(e);
 }

GetSArticleText(), CreateLinkHTML() and LoadAllTags(), are method which return a string, as an output. I am little unsure, where I may be going wrong and when debugging the code, what parameter should i be looking for?

GetSArticleText(), CreateLinkHTML() and LoadAllTags() Methods:
C#
  public string CreateLinkHtml()
        {
            string tag = "";
            tag = @"###########";
            return tag;
        }
		
-----------------------------------------
   public string GetArticleText()
        {
        string htmlStr = "";
        string strConnectionString = ConfigurationManager.ConnectionStrings["######"].ConnectionString;
        SqlConnection thisConnection = new SqlConnection(strConnectionString);
        SqlCommand thisCommand = thisConnection.CreateCommand();
        thisCommand.CommandText = "SELECT top 1 title, body from [article] order by UploadDate desc";
        thisConnection.Open();
        SqlDataReader reader = thisCommand.ExecuteReader();
        while (reader.Read())
        {          
            string Name = reader.GetString(0);
            string Pass = reader.GetString(1);

            Pass = Pass.Replace("<p>", "");
            Pass = Pass.Replace("<p>", "");
            Pass = Pass.Replace("</p>", "");
            htmlStr += "<tr><h2>" + Name + "</h2></tr><tr>" + Pass + "</tr>";
        }
        thisConnection.Close();
        return htmlStr;
        }

-------------------------------------------
  public string LoadAllTags()
        {

            string table = "";
            try
            {
                string tag = "";=          
                string strConnectionString = ConfigurationManager.ConnectionStrings["#######"].ConnectionString;
                SqlConnection myConnect = new SqlConnection(strConnectionString);
                string strCommandText = "select [fullname] from [dbo].[tag_Library]";
                SqlCommand cmd = new SqlCommand(strCommandText, myConnect);
                cmd.Parameters.AddWithValue("fullname", tag);
                myConnect.Open();             
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    string result = reader.GetString(0);

                    table += "<tr>" + result + "</tr>";
                 
                }
                myConnect.Close();                
            }
            catch (Exception ex)
            {
                throw ex;

            }
            return table;
            }

Client-side HTML code:
ASP.NET
<asp:TextBox
                    ID="txtDescription"
                    runat="server"
                    TextMode="MultiLine"
                    Height="150px"
                    OnClientClick= "tinyMCE.triggerSave(false,true);"
                    Width="400px"></asp:TextBox>
    <br />
 <table width="100%" align="center" cellpadding="2" cellspacing="2" border="0" >                      
        <%=GetArticleText()%>
    </table>


C#
htmlStr += "<tr><td><h2>" + Name + "</h2></td></tr><tr><td>" + Pass + "</td></tr>";


Please advice, if possible.

Thank you
Posted
Updated 22-Oct-14 1:42am
v4
Comments
Sinisa Hajnal 22-Oct-14 6:34am    
Do functions return correct HTML? Did you check final ctrl content? Also, is there any exception or you just don't get the output you expect? Can you post the output of each function (real, shortened output, not something you THINK it should come out of it)? Or post the functions themselves. Use Improve Question link. Thank you
miss786 22-Oct-14 6:47am    
Thank you for your reply. I have updated my code with the requested methods. I have tested the return for each method and they seem to work fine. I am little unsure, of how to implement the logic in the preRender() method. Some guide/hints would be very much appreciated. Many thanks.
Sinisa Hajnal 22-Oct-14 7:00am    
You're returning <tr> </tr> without <td> tags. The generated html is not correct.

Also, why are you using Name and Pass variables to hold title and body?
Please ensure that your returned HTML is valid. Copy it from the code and insert into empty div on a test page. If it renders, all is well.
miss786 22-Oct-14 7:40am    
Thank you for your reply. I changed my output string for the Article() method to the following above in the post(htmlStr).

I tested the getArticle() method separately, it renders the article on the client-side, as whole, its still failing to display the tags' name within the article, as hyperlink, on the client-side. I have attached my html in the above post, as further reference.
miss786 22-Oct-14 7:44am    
Would i need call something in page_load method, to trigger the preRender method. Please advice further. Thanks

1 solution

Your OnPreRender method is being called; it's just not doing what you think it's doing.

String.Replace will only replace a sub-string which precisely matches the string to replace. Since it's unlikely that your article body contains all of your tag names, in order, surrounded by <tr>...</tr> tags, it's not going to find a match.

Also, as Sinisa Hajnal pointed out, you can't add a HtmlGenericControl inside a TextBox control.

The easiest option to fix this is probably to build a Regular Expression[^] for the tag names:
C#
public string GetArticleText()
{
    string strConnectionString = ConfigurationManager.ConnectionStrings["######"].ConnectionString;
    const string commandText = "SELECT top 1 title, body from [article] order by UploadDate desc";
    
    // Wrap disposable objects in a "using" block:
    using (SqlConnection thisConnection = new SqlConnection(strConnectionString))
    using (SqlCommand thisCommand = new SqlCommand(commandText, thisConnection))
    {
        thisConnection.Open();
        
        using (SqlDataReader reader = thisCommand.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
        {
            // No need for a "while" loop, as you're only returning a single row:
            if (!reader.Read()) return string.Empty;
            
            string title = reader.GetString(0);
            string body = reader.GetString(1);
            
            // This regular expression replicates the three "Replace" calls from the current code.
            body = Regex.Replace(body, "</?p(>|&gt;)", string.Empty);
            
            return "<tr><td><h2>" + title + "</h2></tr><tr><td>" + body + "</td></tr>";
        }
    }
}

public Regex LoadAllTags()
{
    string strConnectionString = ConfigurationManager.ConnectionStrings["######"].ConnectionString;
    const string commandText = "select [fullname] from [dbo].[tag_Library]";
    
    using (SqlConnection thisConnection = new SqlConnection(strConnectionString))
    using (SqlCommand thisCommand = new SqlCommand(commandText, thisConnection))
    {
        thisConnection.Open();
        
        using (SqlDataReader reader = thisCommand.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleResult))
        {
            List<string> result = new List<string>();
            while (reader.Read())
            {
                string tagName = reader.GetString(0);
                
                // Escape any "special" characters which could break the regular expression:
                tagName = Regex.Escape(tagName);
                
                result.Add(tagName);
            }
            
            if (result.Count == 0)
            {
                return null;
            }
            
            // Create a regular expression to match any of the tag names:
            string pattern = string.Join("|", result);
            return new Regex(pattern, RegexOptions.IgnoreCase);
        }
    }
}

public string CreateLinkHtml(string tagName)
{
    // By using a MatchEvaluator (below), you can now pass the matched tag name to this method.
    ...
}

protected override void OnPreRender(EventArgs e)
{     
    string html = GetArticleText();
    
    Regex tags = LoadAllTags();
    if (tags != null)
    {
        // The MatchEvaluator lets you examine the matched value:
        html = tags.Replace(html, match => match.Value);
    }
    
    // Can't add controls under a TextBox; set the Text property instead:
    txtDescription.Text = html;
    
    base.OnPreRender(e);
}
 
Share this answer
 
v3
Comments
miss786 23-Oct-14 10:39am    
Thank you so much for solution and your time, into explaining the issue and improvement in my code. I really appreciate your help and from generous answer, i was able to implement my task. Many thanks. Have great evening. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900