A Solution For BlogEngine.NET Comment Spam

by James Climer 15. August 2009 15:47

The spam in the comments on my blog has really gotten bad lately.  It seems like almost 10 to 20 comments a day are added to my site that I have to go search around for and delete.  I should receive an e-mail every time a comment is added, but somehow, maybe my spam filter is catching them, I don't receive an e-mail.  Which means I have to go through all of my blog entries and search them out and delete them.

My original plan was to use recaptcha, but I'd like to get the spam under control soon, and it's hard to find time to work on things like this.  So anyway, here is my quick fix:

First, I'm assuming the spam is coming from bots, scripts that are specially programmed for BlogEngine.NET.  So if I add any kind of required field that the bot is not expecting, I would think it would mess up the bot.

Now adding such a simple thing would be easy for the bot scripter to get around.  They would simply modify their script to put a value in the new field I created; so what I'm hoping is that they won't waste their time modifying their script just for my site.

I added a checkbox that must be checked to submit a comment.  I'll give this a week to see if it helps, and if so, I'll put a link in the BlogEngine.NET forums.  I would suggest everyone do something a little different so that the bot scripter will have to work hard to keep up.

Update 10/07/2009

"This has worked tremendously well on cutting down on spam, but I have to say, some spam comments are still getting through and they seem to be getting sneakier.  I suspect that the spammers are keeping a list of blogs that they have trouble automatically spamming and then send real people to read a little of the blog entries and manually submit comments.  I say this because, not only am I still getting spam comments from time-to-time, but the comments are actually related to details, usually in the first couple of sentences, of the blog entry.  Pretty sneaky.  Naturally, neither this solution nor the recaptcha will work against actual humans posting comments.  Perhaps the next thing I will work on is a common source for comment spammer data including the spammer's e-mail and the url they include in the comment."

Here is the technical part.

I should note, I'm using BlogEngine.NET version 1.4.5

More...

Tags: ,

Downloads | Technology | Coding | ASP.NET | C#

Rotate a DataTable in .NET

by James Climer 9. March 2009 14:23

I doubt I'll ever use this again, but regardless I'll post it anyway.  I had two datatables, each containing one row that I wanted to compare.  So I copied the second datatable row to the first and wrote a function to "rotate" the table counter-clockwise (moving the header row to the left column and each row appearing vertically as addtional columns):

 

 /// <summary>
        /// Rotate a table by making the header row the first column and each
        /// additional row a new column.
        /// </summary>
        /// <param name="dataTable"></param>
        /// <returns></returns>
        protected DataTable RotateDataTable(DataTable dataTable)
        {
            DataTable dt = new DataTable(dataTable.TableName);

            if (dataTable.Rows.Count > 0)
            {
                // Make a column for the header
                dt.Columns.Add();

                foreach (DataColumn col in dataTable.Columns)
                {
                    dt.Rows.Add(col.ColumnName);
                }

                int rowIndex = 0;
                foreach (DataRow dr in dataTable.Rows)
                {
                    // Add a column for each row
                    dt.Columns.Add();
                    rowIndex++;

                    for (int colIndex = 0; colIndex < dataTable.Columns.Count; colIndex++)
                    {
                        dt.Rows[colIndex][rowIndex] = dataTable.Rows[rowIndex - 1][colIndex];
                    }
                }
            }

            return dt;
        }

Tags: , ,

Technology | Coding | C#

The network link was interrupted while negotiating a connection...

by James Climer 2. March 2009 08:17

This was one I thought I would share, just in case.   The following is an error that I got in FireFox, just seemingly out of nowhere:

 

The network link was interrupted while negotiating a connection. Please try again.

 

This is a general error that could mean a lot of things.  I tried the page in IE and got a similarly vague error.

 After looking around a bit, it occurred to me that my GridView contained a significantly larger number of rows than usual.  I then discovered a little more specific error in IE.  Something like Maximum Request value exceeded.  Jinkies! (Scooby-Doo Moment)

My GridView had ViewState turned on and was posting back a ridiculusly large number of rows.  I had no need to keep the state of the GirdView in the first place.  So I turned it off and all is well.

I hope this helps somebody out there.

Tags: ,

Technology | Coding | ASP.NET

Recursive FindControl Function for ASP.NET

by James Climer 24. February 2009 11:58

I've had to write this function a few times to find various controls on a form.  Once again, I thought I'd share:

  private Control FindControl(Control searchControl, string id)
        {
            if (searchControl.ID != null)
            {
                if (searchControl.ID == id)
                {
                    return searchControl;
                }
            }

            foreach (Control childControl in searchControl.Controls)
            {
                Control control = FindControl(childControl, id);

                if(control != null)
                {
                    return control;
                }
            }

            // Not found
            return null;
        }

 

This function recursively searches through all child controls of child controls until it finds one that matches the id passed.  This breaks down in the event that more than one child control has the same id.   But, if you're sure the id is unique, this will work just fine.  The following is an example of how I use it:

 Button submitButton = (Button)FindControl(this.Page, "SearchButton");


                // If a submit button is found, call it
                if (submitButton != null)
                {
                    SearchButtonClick(submitButton, null);
                }

Tags: , ,

Technology | Coding | ASP.NET | C#

Convert a DataTable to CSV

by James Climer 17. February 2009 08:34

You would think such a common task would be included in the .NET framework, and maybe it is and I just couldn't find it.  There are many samples online where people use Excel to do this, and that just seems like a waste to have to include such a huge library (and possibly even install MS Excel on a server) just to get a csv file.  So, with that in mind I wrote the following C# class:

Download CSVUtil.cs.zip (1.49 kb)

I used the following as a premise:

  • Each record is one line - Line separator may be LF (0x0A) or CRLF (0x0D0A), a line seperator may also be embedded in the data (making a record more than one line but still acceptable).
  • Fields are separated with commas.
  • Leading and trailing whitespace is ignored - Unless the field is delimited with double-quotes in that case the whitespace is preserved.
  • Embedded commas - Field must be delimited with double-quotes.
  • Embedded double-quotes - Embedded double-quote characters must be doubled, and the field must be delimited with double-quotes.
  • Embedded line-breaks - Fields must be surounded by double-quotes.
  • Always Delimiting - Fields may always be delimited with double quotes, the delimiters will be parsed and discarded by the reading applications.
  • Fields with leading or trailing spaces must be delimited with double-quote characters.
  • Fields may always be delimited with double quotes.
  • The first record in a CSV file may be a header record containing column (field) names.

There is nothing special about the code, so I wont bother going into detail about it.  This simple class will convert the datatable to a huge csv string that will need to either be written to a file or streamed back to a client over a browser.

Tags: , ,

Downloads | Technology | Coding | ASP.NET | C#

DateFormatString formatting short date issues

by James Climer 6. February 2009 12:36

I've recently promoted a web application to production and had all of the dates in my GridViews change their format from 1/1/2009 to 01/01/2009 12:00:00 AM.  In my GridView I have the column property DateFormatString set to {0:d}.

The problem is that this formatting takes into account the culture of the server it's being run on.  My development and test environments were configured to display short dates while the production environment was configured to display long ones. 

My fix was to change the DateFormatString from: {0:d} to {0:MM/dd/yyyy}.  Now the date appears like: 01/01/2009.

Tags: ,

Technology | Coding | ASP.NET

Using Active Directory for Security in ASP.NET

by James Climer 3. February 2009 08:30

This is a very common topic as evidenced by the number of results from searching for the title of this entry, however, it took me almost two hours to muddle through all of that to come-up with the following in the web.config:

 <authentication mode="Windows" />
 <authorization>
      <allow roles="<Domain Name>\<Group Name>" />
      <allow roles="Climers.com\James" />
      <deny users="*" />
 </authorization>

So I added this here to hopefully help!

Use the above code to limit access to a web application to only members of the AD Group "<Group Name>" on the domain "<Domain Name>".  The second "allow" shows that multiple groups can be given access as well as single user access.  The "deny" tag denies everybody else.

 

Tags: , ,

Technology | Coding | ASP.NET

Random Banner Images Using CSS And JavaScript

by James Climer 20. January 2009 08:16

I've recently had to create a banner for a webpage that randomly selects a background image.  I thought I'd share my code:

The following javascript function is called on the body onload event:

<script language="javascript">

function setupPage(){
/* Randomly select a background image */
var imagePath = 'images/bannerImage' +
(Math.floor(6*Math.random()) + 1) + '.jpg';
var headerDiv = document.getElementById('headerBanner');
headerDiv.style.backgroundImage='url(' + imagePath + ')';
}
</script>

<body onload="setupPage()">

<div id="headerBanner">
Banner Text
</div>
In a nutshell, I created six images in the image directory named: bannerImage1.jpg, bannerImage2.jpg, ... bannerImage6.jpg.  All of the images have the same dimensions.  On page load, a random number from 1 to 6 is selected and an image file name is generated.  Then, using javascript, I find the headerBanner and set the style background image to the generated name.
 

 

Tags: ,

Technology | ASP.NET

Web Comic RSS Viewer

by James Climer 14. January 2009 12:34

Web Comic RSS Viewer

 

My web comic Climer Comics is hosted in BlogEngine.NET.  This is convenient for me because of the ease of uploading my comics and the automatic RSS feed that is available.  However, it is not so convenient for viewing, because the comic must be shown in a highly restrictive area (in terms of height and width) and the user has to scroll to read the next comic.  And since I use this blog for other things, I can't dedicate a theme to viewing comics only.

So my dilemma was, how to get my comic in a Word Press Web Comic format with the First, Previous, Next, Last and Random navigation links, and I believe I have solved this with the Web Comic RSS Viewer web application. 

Technical Summary

  • To get my RSS Feed in a manageable object I used the RSS Toolkit.
  • To parse for images, I used regular expressions to find the source for the image.  Currently this only works if the comic is the first image in the body of the RSS item.  For RSS feeds that only pass links to comics, the app not show the comic.

Online Demo: http://comics.climers.com

Source: Download

Tags: , ,

Technology | BlogEngine | Coding | ASP.NET | C# | Downloads

Working in the RowDataBound event on the GridView

by James Climer 13. January 2009 13:42

There are a few coding tasks that I do just far enough apart to forget the details and so I have to look them up everytime.  It's not that these tasks are difficult, I just can't remember them.  One of these is working with the RowDataBound event on the GridView. 

When I work with this event, I usually have one or two things I'm trying to do.  One, modify a row or cell based on something passed in the row data, or two, modify a row or cell based on something in one of the cells in the row.  So, this blog entry will show how to do both of these things.

 

protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                int cycleID = int.Parse(DataBinder.Eval(e.Row.DataItem, "CycleID").ToString());
                e.Row.Cells[0].Text = (cycleID < 10) ? "Low CycleID" : cycleID.ToString();           
            }
        }

 

This simple snippet demonstrates getting an integer value cycleID from the data used to populate the grid.  The next line, takes the first cell in the row and sets the text to either "Low CycleID" if the cycleID is less than 10 or to the CycleID.

Now this seems so simple you say, why bother blogging about it.  Well, the DataBinder.Eval line ALWAYS throws me off.  I always have to look it up.  This code shows how to reference the data as well as the text in a cell. So there you have it. More...

Tags: ,

Technology | Coding | ASP.NET | C#

RecentPosts