25 June, 2010

Save and Display YouTube Videos on ASP.NET Website

Save and Display YouTube Videos on ASP.NET Website: "
About two months ago, a member in the asp.net forums asked a question
regarding similar issue. For this purpose, I have prepared short article that
shows how you can achieve this using ASP.NET Repeater (or similar) control, a
database table with three columns and few code-lines to make this work.

As we already know, YouTube shares the HTML <object /> which can be
embedded in any web site by simple copy/paste of the html for each video
file.

A sample example of the html for embedding YouTube video is as follows


   1: <object width='640' height='385'>
   2: <param name='movie' value="http://www.youtube.com/v/jpiU5Y8luOQ&hl=en_US&fs=1&"></param>
   3: <param name='allowFullScreen' value='true'></param>
   4: <param name='allowscriptaccess' value='always'></param>
   5: <embed src="http://www.youtube.com/v/jpiU5Y8luOQ&hl=en_US&fs=1&" 
   6:        type='application/x-shockwave-flash' 
   7:        allowscriptaccess='always' 
   8:        allowfullscreen='true' 
   9:        width='640' 
  10:        height='385'>
  11: </embed>
  12: </object>

There are three standard <params> and the embed tag which is important
to make this work properly. Anyway, you should not concern much about this
because you will use a standard format of this HTML object example that will be
generated automatically in your website. You should pay attention a bit more on
the format of the YouTube URL link, which is as follows:

http://www.youtube.com/v/<video-file-id>&hl=en_US&fs=1

where hl is the hosted language and
fs if is 1 will allow the full screen button
to shows up, 0 will disallow.

We can leave the hl and fs query string
parameters by default. The only part in the url string we should care about is
the <video-file-id>.

Someone would ask, why paying attention to the ID of the video, when user can
simply paste the link in a ASP.NET text box and just display it as it is. Well,
the problem is that user can enter url while he/she was searching in related
items or even in different cases when the youtube link does not have the same
format, which cannot be embedded as it is, so we need to get the video id and
put it in a url link with standard format. Usually, the URLs instead of showing
/v/<video-id>, these are shown as v=<video-id> which does not show
correctly the video link when embedded to the html object shown previously.


Let’s start with the ASP.NET part.

First of all, drag and drop ASP.NET Repeater control from the Data Controls.
Also you will need SqlDataSource, but of course, you may use any other data
sources or even bind the data control even programmatically in code-behind.

Here is the sample ASPX code I have created so far:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id='Head1' runat="server">
<title></title>
</head>
<body>
<form id='form1' runat="server">
<div>
<asp:TextBox ID='TextBox1' runat='server' Width="461px"></asp:TextBox>
<asp:Button ID='btnAddLink'
runat='server' Text='Add Link' onclick="btnAddLink_Click" />           
</div>
<asp:Repeater ID='Repeater1' runat='server' DataSourceID="SqlDataSource1">
<ItemTemplate>
<object width='480' height="385"><param name='movie'
 value='<%#DataBinder.Eval(Container.DataItem, 'url') %>'></param>
<param name='allowFullScreen' value="true"></param>
<param name='allowscriptaccess' value="always"></param>
<embed src='<%#DataBinder.Eval(Container.DataItem, 'url') %>' type='application/x-shockwave-flash' 
 allowscriptaccess='always' allowfullscreen='true' width='480' height="385">
</embed>
</object>
<br />   
</ItemTemplate>
</asp:Repeater>
<asp:SqlDataSource ID='SqlDataSource1' runat='server'
ConnectionString='<%$ ConnectionStrings:MySampleDBConnectionString %>'
SelectCommand="SELECT [url], [description], [id] FROM [YouTubeVideos]">
</asp:SqlDataSource>
</form>
</body>
</html>


Short explanation:

1. I have created one TextBox which will be used to enter the YouTube URL
link (in any format which comes from the YouTube video service)
2. Button
which will be used for inserting the link into database.
3. There is
Repeater control with ItemTemplate containing the HTML tags for embedding the
video with <%# DataBinder.Eval(Container.DataItem, “url”) %> which will
contain the URL tag retrieved from database.
4. SqlDataSource with
ConnectionString pointing to MS SQL Server database where connection string is
in the Web.config file. You can create new connection string using the
SqlDataSource Wizards or by typing it manually (if you are experienced to do
that so).

If you have noticed in the SqlDataSource, there is a SelectCommand which
selects three columns ([url], [description] and [id]) from table with name
[YouTubeVideos]. Here is the SQL Script to create the sample database table
which I am using in this article:
CREATE TABLE YouTubeVideos --creates table where we will save YouTube Videos
(
id int not null primary key identity(1,1),
url varchar(1000) not null,
[description] text
)



The last thing, which we always leave it for the end, is the C#.NET /
VB.NET code.



Here we have the code behind the Add Link Button click event, method to
extract the ID of the video using Regular Expression and method to check for
Duplicate videos in DB.

First, do not forget to add the following directives
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Text.RegularExpressions;


- Function to get the YouTube Video ID

private string GetYouTubeID(string youTubeUrl)
{
//RegEx to Find YouTube ID
Match regexMatch = Regex.Match(youTubeUrl, '^[^v]+v=(.{11}).*',
RegexOptions.IgnoreCase);
if (regexMatch.Success)
{
return 'http://www.youtube.com/v/' + regexMatch.Groups[1].Value +
"&hl=en&fs=1";
}
return youTubeUrl;
}

I have found this method on the following website: here

The code behind the Add Link button click event is as follows:
protected void btnAddLink_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings['MySampleDBConnectionString'].ToString());
string url = TextBox1.Text;
if (url.Contains('youtube.com'))
{
string ytFormattedUrl = GetYouTubeID(url);

if (!CheckDuplicate(ytFormattedUrl))
{
SqlCommand cmd = new SqlCommand('INSERT INTO YouTubeVideos ([url]) VALUES ('' + ytFormattedUrl + '')', con);
using (con)
{
con.Open();
int result = cmd.ExecuteNonQuery();
if (result != -1)
{
Repeater1.DataBind();
}
else { Response.Write('Error inserting new url!'); }
}
}
else { Response.Write('This video already exists in our database!'); }
}
else
{
Response.Write('This URL is not a valid YOUTUBE video link because it does not contain youtube.com in it');
}
}

and at end, I have created method to check whether the video exists or
not
public bool CheckDuplicate(string youTubeUrl)
{
bool exists = false;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings['MySampleDBConnectionString'].ToString());           
SqlCommand cmd = new SqlCommand(String.Format('select * from YouTubeVideos where url='{0}'',youTubeUrl), con);

using (con)
{
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
dr.Read();
exists = (dr.HasRows) ? true : false;               
}

return exists;
}

Mainly, thats it.

You can format the apperance of the html inside the Repeater control, which
is very flexible for customized HTML.
Download the complete source code:
C#.NET or VB.NET

[Cool Tool] Assembly minifier tool

[Cool Tool] Assembly minifier tool: "
If you are using Silverlight controls from the Telerik suite, you’re going to love this.
Telerik provide a new free tool to help reduce the size of your Silverlight xap. The Telerik Assembly Minifier can be found here:
http://minifier.telerik.com/
From the website: “Telerik Assembly Minifier is a tool that lets you extract only the controls’ classes and resources you need to use in your application development, thus significantly reducing the size of the assemblies. Using the Assembly Minifier you will achieve significantly better loading time when the Silverlight XAP files containing the minified (optimized) assemblies are to be loaded on the client side.”
Note: this apply to Telerik assemblies only (for now).

I decided to give it a try and create a fresh new Silverlight 4 app then insert a Telerik GridView in a page. VS automatically adds reference to these assemblies:
  • Telerik.Windows.Data.dll
  • Telerik.Windows.Controls.Input.dll
  • Telerik.Windows.Controls.GridView.dll
  • Telerik.Windows.Controls.dll

That’s 645KB (compressed) added in your xap file, ouch!

Now let’s add a CoverFlow and a Scheduler controls in my app. This adds 2 more assemblies in the resulting xap:
  • Telerik.Windows.Controls.Scheduler.dll
  • Telerik.Windows.Controls.Navigation.dll

That’s an additional 413KB in the xap.

At that point my xap file is 1.2MB, and my app is quite empty, most of the size is coming from the Telerik assemblies. Great features comes with a price, right ?

Now let’s try the Assembly Minifier tool.
Go to http://minifier.telerik.com/ and upload the Telerik assemblies used in your app.

Then I select the controls to be extracted (GridView, CoverFlow and Scheduler here):

Now I can click on the “Extract” button to download the compressed assemblies and reference them in my app (I removed the originals first).
After recompiling my xap is now 845KB, that’s 32% off.
So finally for my very specific test (empty Silverlight 4 app with 3 Telerik controls: GridView, CoverFlow and Scheduler) I get this result:
xap file size
Before
After
1.2MB
845KB
[32% gain]
Overall this is good, as always Telerik innovate in new tools and it’s nice to see them answering concern like xap files size. But to me the whole process to manually choose your controls and manually upload and manually replace dll is totally inefficient for now. The tool is still beta (and free!) so I do not complain, I just hope to see more features and a better integration in VS later. In a perfect world a VS add-in would do the job automatically when I build in release mode.
Note the tool is working properly, but the way to replace your dll in VS is not (always grab the old replaced dll). You can find some tips to fix it but it is definitely painful for now. Hope VS will provide an easier way to handle this in the future, or maybe Telerik to create a VS addin or something...
Waiting for that you’ll find great help here:
http://www.telerik.com/community/forums/silverlight/assembly-minifier.aspx
"

24 June, 2010

Testing Email Sending

Testing Email Sending: "
Recently I learned a couple of interesting things related to sending emails. One doesnt relate to .NET at all, so if youre a developer and you want to easily be able to test whether or not emails are working correctly in your application without actually sending them and/or installing a real SMTP server on your machine, pay attention. You can grab the smtp4dev application from codeplex, which will listen for SMTP emails and log them for you (and will even pop-up from the system tray to notify you when it receives them) but it will never send them. Heres what the notification looks like:
image
The other interesting tidbit about emails that is specific to .NET is that the MailMessage class is IDisposable. I never realized that before, but I noticed it while reading through the Ben Watsons C# 4 How To book I picked up at TechEd last week (which is done cookbook style and has a ton of useful info in it). Looking at the MailMessages Dispose() method in Reflector reveals that it only really matters if youre working with AlternateViews or Attachments (this.bodyView is also of type AlternateView):
image
All the same, you should get in the habit of wrapping your calls to MailMessage in a using() { } block. Heres some sample code showing how I would typically work with MailMessage:
Bad Example (dont cut and paste and use):
string fromAddress = "nobody@somewhere.com";



string toAddress = "somebody@somewhere.com";



string subject = "Test Message from IDisposable";



string body = "This is the body.";



var myMessage = new MailMessage(fromAddress, toAddress, subject, body);






var myClient = new SmtpClient("localhost");



myClient.Send(myMessage);




And heres how that code would look once its properly set up using IDisposable / using:


Good Example (use this one!):




string fromAddress = "nobody@somewhere.com";



string toAddress = "somebody@somewhere.com";



string subject = "Test Message from IDisposable";



string body = "This is the body.";






using(var myMessage = new MailMessage(fromAddress, toAddress, subject, body))



using(var myClient = new SmtpClient("localhost"))



{



myClient.Send(myMessage);                



}






Note also that SmtpClient is also IDisposable, and that you can stack your using() statements without introducing extra { } when you have instances where you need to work with several Disposable objects (like in this case).


Note that if you run Code Analysis in VS2010 (not sure which version you have to have right click on a project in your solution explorer and look for Analyze Code) you will get warnings for any IDisposable classes youre using outside of using statements, like these:


image




Summary


Sometimes things you dont expect to be Disposable are. Its good to run some code analysis tools from time to time to help find things like this. Visual studio has some nice static analysis built into some versions, or you can use less expensive tools like Fx Cop or Nitriq.