Tuesday, September 8, 2009

Passing Anonymous Types as Method Parameters with LINQ to SQL

I was looking for a way to Pass Anonymous types as parameters to a method as I didnt want to create code redundancy. Based on the research, I found out that Creating a Class with the same properties with that of the anonymous type would do the trick. Here's an Example:


public class articleitems
{
public string title { get; set; }
public string web_blurb { get; set; }
public DateTime publish_date { get; set; }
public string webauthor { get; set; }
public string body { get; set; }
}


using this class in your LINQ to SQL query, this is what u get:


List articlelist = (from cat in db.articleposts
where cat.columntypeid == 1
select new articleitems
{
title = cat.title,
web_blurb = cat.web_blurb,
publish_date = cat.publish_date,
webauthor = cat.authorname,
body = cat.body
}).ToList();



The returned List can now be used in your method:
GetItems(articlelist);

Yippy!

Tuesday, July 7, 2009

Code Highlighter for Blogger

UPDATE : Now using syntaxhighlighter. Much customizable to each language. See link below. Supports c++ , c#, sql, javascript, etc.

http://code.google.com/p/syntaxhighlighter/wiki/Usage 

TIP : Place the mentioned code just before the end of body tag

I had this nasty issue of Formatting the code for putting it up on the Blogger. With it being so popular, it was definately a turn off for geeks who would like to post some code on their Blog. I dont know how they manage, but it eats up a lot of my time. I have used other editors like TinyMCE and FreeTextbox and they work great. I dont know why the blogger Editor is so dumb! So I did some googling and found out a solution for making it easy for me. Its still not easy though. I still need to find a better way to do it. But as of now this should be good. Without doing the copy/ paste job, here's the link that will explain you the stuff. After its implementation, you would be able to see what it looks like in my previous post made today.

http://urenjoy.blogspot.com/2008/10/publish-source-code-in-blogger.html

Make sure you are able to tweek for Firefox. Let me know if you have any issues.

Happy source coding!

Regular Expression Restricting the type of file to Upload

I was working on the file upload control yesterday, and I wanted to restrict the users to be able to upload only html files.

Here's the html that will take care of that:


<asp:RegularExpressionValidator id="RegularExpressionValidator1"
ControlToValidate="flUpload"
ValidationExpression=".*([.]html)$"
Display="Dynamic"
ErrorMessage="Only Html Uploads Allowed"
EnableClientScript="True"
runat="server"/>


Oh, and by the way, I found out how to retain the color coding of the html/codebehind text! Yay!

Inserting and Retrieving Images from SQL Database using LINQ

I was trying out to find a way to do this the other day and got it to work after a few tweeks. I have SQL 2005 installed and wanted to save the Uploaded Company Logos into the Database. First make sure that the table has a column of "image" type. the Upload control id is "flUploadImage". I will limit the code to that specific Image Upload, while removing the rest of the table fields/properties.

Inserting the Record:


article_sponsorship sponsorship = db.article_sponsorships.Single(artsp => artsp.id == ddlCampaigns.SelectedValue.ToInt16());

if (flUploadImage.HasFile && flUploadImage.PostedFile.ContentLength > 0)
{
byte[] img = null;
img = new byte[flUploadImage.PostedFile.ContentLength];
flUploadImage.PostedFile.InputStream.Read(img, 0, img.Length);
System.Data.Linq.Binary postedimage = new System.Data.Linq.Binary(img);
sponsorship.Logo = postedimage;
}

Fetching the Record:

To Display the Image, I had a seperate page built for rendering the image. The Image was queried on the basis of the querystring parameter that was passed on the page.

So my Image control named "imgLogo" was assigned this way


imgLogo.ImageUrl = "~/sponsorshipimage.aspx?imageid=" + sponsorship.id;

On the sponsorshipimage.aspx page, I had the code to fetch the image and put it in the OutPutStream. Here's the code:

sponsorshipimage.aspx
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.QueryString["imageid"]))
{
DataClassesDataContext db2 = new DataClassesDataContext();
article_sponsorship sponsorship = db2.article_sponsorships.Single(sp => sp.id == Request.QueryString["imageid"].ToInt16());

Response.ContentType = "image/jpeg";
Response.BinaryWrite(sponsorship.Logo.ToArray());

db2.Dispose();
db2 = null;
}
}

The ToArray() method was a pretty simple way to convert the System.Linq.Binary to an Array of bytes, which initially had made me little crazy figuring out how to do that, until I found out this Method. The image appeared without a doubt! Perfect!

Update : 03/01/2011

If you would like to post a default image if no image is present, here's how you go about it.

FileStream fileStream = new FileStream(Server.MapPath("~/images/noimage.png"), FileMode.Open, FileAccess.Read);
byte[] img = new byte[fileStream.Length];
fileStream.Read(img, 0, (int)fileStream.Length);
fileStream.Close();
System.Data.Linq.Binary postedimage = new System.Data.Linq.Binary(img);
sponsorship.Logo = postedimage;

Wednesday, June 10, 2009

Running Cassini (local) Web Server without having the Application Name in the url

One of the small issues of the Cassini server thats built in with Visual Studio IDE is that when you run it, it also has the Folder name of your application/project in the url. While this is not a major issue, it surely does some damage to the relative urls of images and/or other files which are relative. This would mean changing the relative paths for the development and production copies. I have done that in the past and know it is annoying if one forgets to change them, even though they can be stored in Application web.config file

One of the fixes that I found out was to configure the site using the external tools section of the IDE:


Clicking on the external tools takes you to the following window:



And thats what it is.

Follow this to have it done.

Click on "Add" to add a new Item to the project.
Title : This could be your project name
Command : This is the path for the Cassini Web server. Locate its exe and provide over here. This is what I have
(C:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE)

Arguments : Here you would assign a port number and your application folder as your arguments. The port number can be any number. The Application folder is where your project resides

/port:8085 /path:"C:\Users\Username\Documents\Visual Studio 2008\WebSites\SD30"


Once you are done. Click on Ok.

Now click on "Tools" from the IDE and you will see your Application Name in the Menu. Click on your Application Name to instantiate the Cassini Web Server for your Application. You will see the Web server activated in the task bar. Click on it to open your default page.

Thats all! Nice and Easy!

Monday, June 8, 2009

Using Google SiteMaps

Today I wanted to create a dynamic google sitemap file for my site. So I started reading the documentation for creation of a sitemap. Google has a very good documented format, making all the points clear. you can vew it here. The Google Webmaster tools are also one of the powerful features where you could view the site stats, and thats where you need to submit your google sitemap.

The sitemaps protocol is defined at http://www.sitemaps.org/protocol.php

The sitemap is placed in the root directory which contains all the site urls for google to index pages. You can have a maximum of 50,000 urls per Sitemap. For additional urls, another sitemap file can be created and then linked with each other using SiteMap indexing file. Google does great at explaining all this stuff, so make sure you go through all the stuff in the link that I have put up here above to get the best of both worlds.

Generating the dynamic SiteMap file:

Generation is just like any other xml file, except that you have to adhere to the standards mentioned in the sitemap protocol.

Here's the code. You have to modify the query to suit your needs.


public partial class NewsSiteMap : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
DataClassesDataContext db = new DataClassesDataContext();

var latestNewsArticles = (from articles in db.article_to_magazine_mappings
where
articles.magazine_id == 1 && articles.article.article_type_id != 20
select new
{
ID = articles.article.id,
Title = articles.article.web_title,
TitleLink = articles.TitleLink,
Author = articles.AuthorName,
TitleKeywords = articles.article.meta_tags,
Date = articles.publish_date,
LegacyID = articles.article.legacy_id
})
.Take(49999);


Response.Clear();

Response.ContentType = "text/xml";

using (XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Encoding.UTF8))
{
writer.WriteStartDocument();

writer.WriteStartElement("urlset");

writer.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");

foreach (var newsarticle in latestNewsArticles)
{
writer.WriteStartElement("url");

writer.WriteElementString("loc", ConcatenateUrls(newsarticle.TitleLink,newsarticle.Author,newsarticle.TitleKeywords,newsarticle.ID.ToString()));

writer.WriteElementString("lastmod", String.Format("{0:yyyy-MM-dd}", newsarticle.Date));

writer.WriteElementString("changefreq", "daily");

writer.WriteElementString("priority", "1.0");

writer.WriteEndElement();
}

writer.WriteEndDocument();

writer.Flush();

}

db.Dispose();
db = null;

Response.End();
}

protected string ConcatenateUrls(string title, string author, string keywords, string articleid)
{
return GetHost(title + "/By_" + author + keywords + "/" + articleid);
}
}


In the html, you just need to add the following line
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="newsSitemap.aspx.cs" Inherits="NewsSiteMap" %>


Make sure you have encoded your content so that it doesnt break.
After you are done, submit your sitemap file to Google, and you are good!

Tuesday, June 2, 2009

Firefox and Mouseout Issue

Today I had an a very minor issue, but it was worth writing here. Firefox had this nasty delay of triggering from the mouseover even to mouseout event on my menu which had a javascript to be executed in order to change the text inside a span tag. Having done this tons of times before, I cannot recall this issue. However, this might be due to the fact that the anchor tag encompassing the span tag of the menu had a background image applied and this might be the cause of conflict or delay on the triggering of the mouseout event of the span tag. This issue was not displayed in IE, Opera or Safari, though.

I tried using innerHTML to change the text, but of no avail. After a couple of quick searches, I found out using the
obj.firstChild.data
element, where obj is your span tag. It worked perfect miraculously! This brings to the conclusion that the old school DOM model is still worthwhile!

Monday, May 18, 2009

Url Fetching from content and making "clickable" using Regular Expressions in .net

Here's a quite and easy way to find a url and surround it with anchor tags, and also putting a target='_blank' so that you could open up the link in a new tab. Very useful and powerful feature of Regex.

string yourtext = "Heres the link to the site: http://www.yoursite.com/content.html"

yourtext = Regex.Replace(yourtext, @"(http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?)", "<a target='_blank' href='$1'>$1</a>");

Now the text would look like:

Heres the link to the site: <a target='_blank' href='http://www.yoursite.com/content.html'>http://www.yoursite.com/content.html</a>

Regex Rocks!

Thursday, April 16, 2009

Sort by Date for Google Site Search

Google Searches by Relevance by Default. One of the things that was on my TODO list was to have the articles search sorted by date, irrespective of the article relevance. So I had a radiobutton list which lets the users to choose if they want the results by relevance, or by date. There were not really lot of information about it on google blogs/forums, and nobody was sure whats the correct way to do it. After some clicks and head bashings, I found out the closest way to get to the results to sort by date is to have its own Annotation file and context file. So I logged into my google account and went to the custom search section, where I had customized my google site search. On the advanced Tab, I downloaded the Annotation file and the context file.

The Idea is that, when the user opts to sort by date, call these customized xml files to show results sorted out by date.

In the context file you will find the following tag


<Context>
<BackgroundLabels>
<Label name="_cse_bolrua_bzhw" mode="FILTER" />
<Label name="_cse_exclude_bolrua_bzhw" mode="ELIMINATE" />
</BackgroundLabels>
</Context>


Add the following Label to the xml file and save it in your website directory.


<Label name="recent4" mode="BOOST"/>


This tag does the trick.

Also Just before the </GoogleCustomizations> tag, add the following line:


<Include type="Annotations" href="http://www.yourwebsite.com/annotations.xml"/>


This references the annotations file that you downloaded from the "Advanced Console"

There wont be any change in the annotations file, except that a copy will reside on the server. Make sure that when you change the site restrictions (Adding/Removing folders/files for site search), compare your downloaded version with the one on the Custom search.

Based upon the Radio Button selection, just select the annotation file:


if (rbSearchby.SelectedValue == "r") //Search by Relevance
Response.Redirect(GetRoot() + "content/googlesearch.aspx?cx=01054907335329%3Abolrua_bzhw&cof=FORID%3A11&ie=UTF-8&q=" + HttpUtility.UrlEncode(SearchBox_TextBox.Text) + "&sa=Search");
else
//Search by Date
Response.Redirect(GetRoot() + "content/googlesearch.aspx?cref=http%3A%2F%2Fwww.yourwebsite.com%2Fgooglespecc.xml&cof=FORID%3A11&ie=UTF-8&q=" + HttpUtility.UrlEncode(SearchBox_TextBox.Text) + "&sa=Search");