|
|
by Naveen
2. September 2010 05:34
While implementing a high performance search functionality for a site, I ran into some interesting
issues with some UI aspects. So I thought I would share it with everybody so you have answers to
some of the following questions when you run into similar issues.
-
How to set focus in text box when page load
This is a very common requirement that when you are implementing a search box for your site, you
want the users to be able to start typing in search keywords when the page load. Well it is pretty
simple by using a small javascript on the page. Since Microsoft shipd jQuery with
Visual Studio now and jQuery provides very concise implementation of some
very common tasks, so I used jQuery to accomplish the task. Following snippet shows
how to use jQuery to set focus on text box.
$(document).ready(function () {
var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
keywordTextBox.focus();
}
Yes, I could have done whole thing in one line instead of storing the element in local
variable first. But I needed this element for some other user as well. Soon you will see
why. The code simple translates to when document has been loaded and DOM is ready
get text box html element and call focus method to set focus on it.
-
How to set cursor position at end of text in text box
Now that you have seen how to set focus on text box, next thing you will run into is that when
page post backs when you have text in search text box, the focus is set on the text box but
it is set at the start of the text. What you are really looking for is that when you have some
text in text box, the focus should be set at the end of the text so user can either continue
with what is already there or start deleting for a new search term. The following snippet shows
how you can use setSelectionRange or createTextRange depending
on browser, javascript method on text box to set the cursor at the end of the text in text box. Or
for that matter you can use this technique to set cursor in text box at any position.
$(document).ready(function () {
try {
var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
if (null != keywordTextBox) {
var pos = keywordTextBox.value.length;
if (keywordTextBox.setSelectionRange) {
keywordTextBox.setSelectionRange(pos, pos);
}
else if (keywordTextBox.createTextRange) {
var textRange = keywordTextBox.createTextRange();
textRange.collapse(true);
textRange.moveEnd("character", pos);
textRange.moveStart("character", pos);
textRange.select();
}
keywordTextBox.focus();
}
});
-
How to handle enter key click in text box to submit page
Now that we have set focus in text box. Now your user should be able to enter some text
in the text box and hit ENTER key to perform search. Following code snippet
shows how you can hook key events of your text box to look for ENTER key
press and then submit the page.
$(document).ready(function () {
try {
var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
if (null != keywordTextBox) {
var pos = keywordTextBox.value.length;
if (keywordTextBox.setSelectionRange) {
keywordTextBox.setSelectionRange(pos, pos);
}
else if (keywordTextBox.createTextRange) {
var textRange = keywordTextBox.createTextRange();
textRange.collapse(true);
textRange.moveEnd("character", pos);
textRange.moveStart("character", pos);
textRange.select();
}
keywordTextBox.focus();
$("input").keydown(function (e) {
if (e.keyCode == 13) {
__doPostBack("<%=searchButton.UniqueID%>", "");
return false;
}
});
}
});
The above code javascript snippet demonstrates all three features of handling various
text box features together. You can see all this in real action at the following page. Start
typing some search term and see how autocomplete start providing hints and then when you hit
ENTER key, page posts back and returns with search results and then text box focus is
set at the end of text in text box.
Live Demo Of Text Box Features
|
|
|
by Naveen
25. August 2010 17:19
While implementing integrating ASP.Net Ajax AutoComplete control on a site's search text box, I ran into an issue. While I was typing inside the text box, no request was getting sent to my web service to get the list of previously used search terms with a given prefix that user was typing. I checked the mark up for
AutoCompleteExtender on the page and all the required properties etc. There was nothing out of place. Obviously request was not making it to my web service method. That's when I called on handy dandy Fiddler. And there it was the following response from the web service request with Http Status code of 500.
Only Web services with a [ScriptService] attribute on the class definition can be called from script
Thats when I realized that I forgot to enable this attribute on my ASP.Net web service. So remember that if you are using an ASP.Net web service with Ajax toolkit controls, you have to enable ScriptService on
your service.
by Naveen
23. August 2010 13:40
Its been a while since I did some custom work on controls like GridView, DataGrid etc. Last
week I was working on a prototype of some application that required me to add some records into the
database. So I decided to give GridView control in ASP.Net a try. I needed a very simple
UI so I decided to use as much built in functionality of this control. Since I needed to add a new
record, so I needed a way to be able to add a new row into GridView. So I looked at the
CommandField column. One of the properties it has is ShowInsertButton . So
I added this property and set it to true. So now my mark up on ASP.Net on the page looked as shown
below.
<Columns>
<asp:CommandField ShowEditButton="True"
ShowDeleteButton="true"
ShowInsertButton="true"></asp:CommandField>
.... othe bound columns.
</Columns>
I ran the application and my grid shows up and has all three data manipulation links visible. So I clicked on
New link button. Well, I did not see an empty row appear where I was going to add new data for
new row in database. I checked, everything looked in order. I have event handler correctly mapped and
code looked fine. After trying few things around, I searched on internet. I could not find any
useful information on why my event is not firing or why new row is not getting added. All the posts and articles
that I ran into talked about adding a new button in the grid to accomplish taks of added new records. Well
that sounded a little odd that why would I need to add my own button when there is already a command
link buttoon available. Thats when I decided to read the documentation on this property ShowInsertButton.
Here is something in documentation that stood out.
This property applies only to data-bound controls that support insert operations, such as the DetailsView control.
When you look at various events in GridView control, you will not find any related to
Insert. Now that explained why I am not getting new row added to my grid.
Adding new row to GridView
So here is quick solution that I came up with for my prototype. When you click on New
link button in GridView, it does fire RowCommand event. Here you can check for
CommandName value of New. In this event handler, I added a new empty
record into the data source to which my GridView was bound, set the EditIndex of the
grid to first record and bind the grid again. Now I have an empty row in Edit mode open for me to
add some data.
if (e.CommandName == "New")
{
ViewState["_inserting_"] = 1;
var glossaryTerm = new Services.GlossaryTerm();
_terms.Insert(0, glossaryTerm);
GlossaryGrid.EditIndex = 0;
BindGrid();
}
You can see that I added a flag in ViewState that grid is in Insert mode. The reason
for this is that since GridView does not support Insert directly, when you
will click on Update link button, you are going to get RowUpdated event
handed to you. So you will need some way of knowing that this record is actually to be added and not edit
some existing one. The way I did is not one of the best and elegant way. But you get the idea. One nice
of doing is to have an hidden field where some unique ID of each record is stored. And you can keep
this field hidden. Since I did not have any unique ID in my data source, I had to do it
differently. But most grids are bound to some data source with some unique ID. So when you add a new
empty record for adding, you can set its Unique ID value to some token valur like -1. When you
handle RowUpdated event, then you can look for this unique ID value and perform
the database accordingly.
This trick should allow you to use built in command buttons to add new row in GridView.
|
|
|
by Naveen
19. August 2010 11:21
As part of using Membership controls in ASP.Net, one thing lot of people do
as part of user creation is send some sort of email to the new user when they register. This email
could be some welcome email or email that send the user their password etc. Good news is that
CreateUserWizard control takes care of most of the email functionality for you. Here
is what you need to make it all work.
How does it work?
CreateUserWizard control sends an email to the newly registered when the new user
has been created. SendEmail event is fired after CreatedUser event has been
successfully fired and handled. Interestingly, CreateUserWizard sends this email using
method SendPasswordMail. It seems this email feature was designed for sending
passwords to user when password is automatically generated. But this does not mean that it is
only going to be called when certain password option is chosen.
MailDefinition is the key
CreateUserWizard control does not try to send email all the time. It looks for
MainDefinition template to be set in the control. If you do not definie
MailDefinition template, control will not send the email. So what you need to do is
fill this template inside your control container. Here is sample implementation from my sample
code.
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:CreateUserWizard ID="RegisterUser"
runat="server" EnableViewState="false"
OnCreatedUser="RegisterUser_CreatedUser"
OnCreatingUser="RegisterUser_CreatingUser"
BorderStyle="Dotted"
OnSendingMail="RegisterUser_SendingEmail"
OnSendMailError="RegisterUser_SendingEmailError">
<LayoutTemplate>
<asp:PlaceHolder ID="wizardStepPlaceholder" runat="server"></asp:PlaceHolder>
<asp:PlaceHolder ID="navigationPlaceholder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
<MailDefinition
From="xyz@mymail.com"
IsBodyHtml="true"
Priority="Low"
BodyFileName="~/WelcomeEmail.htm"
Subject="Welcome to Project Helpers from ByteBlocks.com">
<EmbeddedObjects>
<asp:EmbeddedMailObject Name="LogoImage" Path="~/Images/ByteBlocksLogo.png" />
</EmbeddedObjects>
</MailDefinition>
</asp:CreateUserWizard>
As you can see, MailDefinition template allows you to configure email parameters. You
do not have to hard code some string as body of your email. It will actually become problem when
you have long HTML content to be sent in email body. You can put content of your email in external file
and then set the path to that file in BodyFileName attribute of MainDefinition.
You can put some token or markers inside that body to replace them with appropriate values at run time. More about it
little later. So remember that MailDefinition is key to sending email as part of
CreateUserWizard control.
Customize email content and attachment
Some time you want to send welcome email to new users with some documents and also want to
have some logo image inside the email body. Well, this all can be handled by using a standard format
that the control provided. You will make use of EmbeddedObjects section of
MailDefinition template. This is where you can include all the external objects or file
paths. Make sure that you have unique names for these objects.
-
To include images inside email body, use the following syntax in HTML email body content.
<img src="cid:LogoImage" alt="ByteBlocks Project Helpers" />
<h2>Welcome To ByteBlocks Project Helper</h2>
This is part of HTML file that I use for email body. The key to this is src=cid:uniqueid part.
This uniqueid is the name of the object that you added in EmbeddedObjects section. You
can see from the markup that I showed earlier that I have included my logo image inside
EmbeddedObjects section.
-
If you need to attach some documents, then include them in EmbeddedObjects section.
Following screenshot shows sample of email that get sent from my application. You can see that at the top of
the email is sample logo image as well.
Configure SMTP Server for CreateUserWizard Email
This is one of the most asked question to me. Where do I set SMTP server settings for emails from
CreateUserWizard?. When SendEmail event is fired, you get
MailMessageEventArgs object as parameter of event handler. This object only provides
you access to email message only. It does not provide a way to configure SMTP settings for outgoing
email. Then how do you set it?
See the following call stack when CreateUserWizard control is trying to send the email
out.
System.Net.Mail.SmtpClient.Send(MailMessage message)
System.Web.UI.WebControls.LoginUtil.SendPasswordMail(String email, String userName,
String password, MailDefinition
Now if you look at constructor of SmtpClient, it initializes the settings of email
transport from mailSettings section of web.config. That means the place
to configure your SMTP server is in web.config file. Add mailSettings section in
system.net section of web.config value. Following snippet shows
you an example from my site.
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="xyz@myisp.com">
<network host="localhost" />
</smtp>
</mailSettings>
</system.net>
You can provide the values as per your server settings. If you are just testing using your local machine
as email relay then you do not have to specify these settings. SmtpClient by default will
use local machine.
Important things
There are few things that you will need to pay attention to when setting up this MailDefinition
template and changing settings for MailMessage.
-
Make sure that you have specified an email address in From section. This does not have
to be a valid emails address. You can simply put something like noreply@mydomain.com. But do not leave
it empty.
-
If your process does not require the users to provide their email address but you still want to send some
email for record keeping then you can add a placeholder email to To collection. You
can not leave To collection empty. Otherwise SmtpClient object will throw exception at you.
protected void RegisterUser_SendingEmail(object sender, MailMessageEventArgs e)
{
var sendTo = RegisterUser.Email;
if (string.IsNullOrEmpty(sendTo))
{
sendTo = "foo@bar.com";
e.Message.To.Add(sendTo);
}
}
Do provide an event handler for SendEmailError. If there is some error or
exception thrown during outoging email process, you can look at the error message. Handle this error gracefully and
then set Handled properly.
protected void RegisterUser_SendingEmailError(object sender, SendMailErrorEventArgs e)
{
System.Diagnostics.Trace.WriteLine(e.Exception.Message);
e.Handled = true;
}
If you do not handle this error, then it will get propagated to the top as unhandled exception and depending
on your CustomError settings, users may see ugly yellow screen with full stack trace and all.
|
|
|
1f16a4fa-9ec8-4790-837b-8d2af0788e1b|0|.0
Views: 406
Tags: ASP.Net
ASP.Net
by Naveen
18. August 2010 10:50
I was working on using CreateUserWizard ASP.Net control on my web site to allow
users to create their account for authorized and authenticated access to certain access of sites. One
of the problems you face on the web sites is that spammers tend to run bots to create accounts
on sites using direct HTTP requests and things like that. One of the ways to fight this is the use of some
CAPTCHA control on the pages. Yes, there are some hackers who claim to bypass some of these
counter measures. But still it protects you from about 80% or so of these spam bots.
So one of things you can do is to add ASP.Net plugin for reCaptcha control in template
for CreateUserWizard control. There are few issues that I ran into when I tried to integrate
into my page. So here are some of the things you can learn from my experience to integrate reCaptch
in ASP.Net.
-
There seems to be a validation bug in older version of reCaptcha control plugin. So I had
to download the latest source code from google SVN and recompile it to use in my ASP.Net web site. The problem
I was running into with bugged plugin was that Postback was not getting fired. After I
will click on Create button, the page will just not fire event handler to postback the page. Once
I replaced it with recompiled version of reCaptch control, the page worked fine.
-
In the post back event handler, add the following code to validate reCaptcha challenge. This
will provide you server side validation of the control. I added following code to my event handler.
protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
{
var captcha =
(Recaptcha.RecaptchaControl)RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("recaptchaCtl");
if (null == captcha)
{
e.Cancel = true;
return;
}
captcha.Validate();
if (!captcha.IsValid)
{
//TODO: Display validation message.
e.Cancel = true;
return;
}
e.Cancel = false;
}
|
|
|
1b3d7020-c71a-4804-b85d-5c1fc53ea44e|0|.0
Views: 391
Tags: ASP.Net
ASP.Net
by Naveen
13. August 2010 13:35
Adding a panel on a web page with rounded corners is something very common that we all do at some point in
web application development. We all have been thought standard solution of using a collection of images to
arrange them in a manner that they form a rectangle with rounded corners.
If you are developing ASP.Net web site then, Ajax Toolkit makes this task every easy for you. By
adding one additional control tag you end up adding a rounded corner panel around an existing panel. Let's
see how this done.
-
I am going to skip the discussion on download of Ajax toolkip, installation and all that good stuff. I am going
to assume that you have already done it.
-
Add reference to AjaxControlToolkit.dll assembly to your ASP.Net project if you do not
already have it added.
-
At the top of the page add tag for registering TagPrefix for the controls in this Ajax assembly.
<%@ Register Assembly="AjaxControlToolkit"
Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
-
Make sure that you add ScriptManager server control tag on the page as well. Otherwise
you will end up with the following run time error.
The control with ID 'intoPanelRoundedCornersExtender' requires a ScriptManager on the page.
The ScriptManager must appear before any controls that need it.
In my case I just added in the master page of the site.
<asp:ScriptManager ID="masterScriptManager" runat="server" />
-
Now add RoundedCornersExtender control on the page. The most important property to
set is TargetControlID. This ID of the control around which rounded corner panel is
going to be added. Without it, the control will not work.
<ajaxToolkit:RoundedCornersExtender ID="intoPanelRoundedCornersExtender" runat="server"
BehaviorID="RoundedCornersBehavior1"
TargetControlID="siteIntroPanel"
Radius="6"
BorderColor="#111"
Color="#696969"
Corners="All" />
Other property that can be set to control behavior of rounded corner panel are Color,BorderColor,
Radious and Corners. The names of these properties pretty much tell what these are supposed
to control.
See how easy it is to add these rounded corners. You can see the demo on this
live site. The top two panel are created using
this RoundedCornerExtender control from Ajax toolkit.
|
|
|
by Naveen
13. August 2010 09:12
Last week I was updating the site to include some new features. I realized that I was missing a very
important component on the blog and that was google search box. I had this search on my other sites
for quite some time. I remember that I had to deal with the fact that Google Custom Search script
is implemented as a POST FORM with the action set to a URL that will be used
to display results.
First you have to deal with the fact that ASP.Net framework does not allow you to have multiple
FORM tags on the page. But if you want have more than one then only one can have
runat='server' attribute on it. And then you have to make sure that your FORM
tags are not nested. Well, depending on your layout of the site and implementation, you may or may not
be able to control location of this google search form. Here is the solution that I implemented few years
ago and deployed on this site as well.
Use of iform
Yes, took the Google Custom Search script and put it in a static HTML page. And then put an
IFRAME on the page where I wanted to display the search box. This is where you will
have to be little careful. You will have to make sure that style of the HTML page matches your main site.
Next make sure that height and width of iframe is big enough to accomodate the search box otherwise
you will end up with horizontal and vertical scroll bars around the frame and that will not be a pretty sign
for site users. You want to give the illusion to users that this search box is sitting on the page itself. Now
perform search and it works. But there is a problem. Search result target URL is being opened in the frame where
search box is. Well that is a little problem.
Fix target of FORM
This is where you will have to make a change in the script that Google Custom Search generated for you. In
FORM tag, set target to _top. Now when this form is
submitted, the action is sent to page contained this iframe. The following snippet
is what I have in my HTML page.
<div class="cse-branding-bottom" style="background-color:#FFFFFF;color:#000000">
<div class="cse-branding-form">
<form action="http://localhost/ByteBlocksWeb/SearchResults.aspx"
id="cse-search-box"
target="_top">
<div>
<input type="hidden" name="cx" value="partner-pub-xxxxxxxxxxxxx:wcbg5i-ahdn" />
<input type="hidden" name="cof" value="FORID:11" />
<input type="hidden" name="ie" value="ISO-8859-1" />
<input type="text" name="q" size="60" />
<input type="submit" name="sa" value="Search" />
</div>
</form>
</div>
<div class="cse-branding-logo">
<img src="http://www.google.com/images/poweredby_transparent/poweredby_FFFFFF.gif" alt="Google" />
</div>
<div class="cse-branding-text">
Custom Search
</div>
</div>
Now perform a search and you will notice that your results show up in main page and not in iframe
anymore. Give it a try right here in this site by using search at top of the page and see how it works.
|
|
|
by Naveen
12. August 2010 10:08
Linq is one of the best things that has happened in recent past in
.Net framework world. It has made data manipulation so much easy. Yes, Linq has its own
set of limitations but for most part it does the job. For those special cases you can
always go back to classic ways. In this post, I will describe use of Linq for Sql and provide
some simple answers to questions like:
- How to connect to database using Linq?
- How to query data from a table using Linq?
- How to use Linq with GridView, DataGrid etc.?
Namespace and reference to use Linq with Sql
The classes that you need to use Linq with Sql live in System.Data.Linq namespace. So
in your project you will have to add the following line at top of your source code file.
using System.Data.Linq;
This namespace lives in System.Data.Linq assembly. That means that you will have to
add reference to this assembly in your project. Now you are all set to us Linq.
How to connect to the databae?
You have been using ADO.Net for a while now and first thing we all do is have a connection object
that will be used to connect to database, open it and later on close it. Well when you are using, all
that plumbing is taken care of for you by Linq frameework. The entry point to all actions in Linq for
Sql is DataContext object. This object takes care of establishing connection with
the database. You can provider either a connection string or connection object to
create instance of DataConext object. Rest will get taken care of for you.
var dataContext =
new DataContext(ConfigurationManager.ConnectionStrings["blogengine"].ConnectionString);
Query data using Linq
Now you have set up DataContext object, it is time to get some data from the database.
You will notice that DataContext object provides methods like GetTable, ExecuteQuery,
ExecuteCommand etc. All the methods that return collection of data, expect another parameter
which is Type of an object that represent the data returned from query or command. In
otherwords, the method is looking for a mapping between table in the database to an object. Here is
an object definition that I used in my code to map to fields from a datatable that I wanted to fetch.
[Table(Name="be_Posts")]
public class BlogPost
{
[Column(IsPrimaryKey=true)]
public Guid PostID
{get;set;}
[Column]
public string Title
{get;set;}
[Column]
public string MiniUrl
{get;set;}
}
There are few attributes on this class that are to be notices. First, there is TableAttribute
on the class itself. By default Linq assumes that name of the class or object is same as table in the
database. But if your table name does not match with the class name, then you can use this attribute to
provide the name of the table that maps witht this obejct. For example in my case table name be_Posts
is to be mapped to BlogPosts object which is my ViewModel. Next attribute is ColumnAttribute.
You will assign this attribute to properties or fields that needs to be queried. If your column name does
match with name of the property or field, you can provide that mapping as well. There are more values you
can set in the column attribute. I will discuss those in subsequent posts. For now this simple
definition of .Net object will work for our simple query purposes.
Bind Linq To GridView
Now we have our Linq query set to go, rest is just setting this collection to our GridView
object on ASP.Net page and rest is all taken care of for us. Following code snippet
shows how in few lines we are able to connect to database, query the data and bind it to a GridView.
void BindGrid()
{
var dataContext =
new DataContext(ConfigurationManager.ConnectionStrings["blogengine"].ConnectionString);
var posts = dataContext.GetTable<BlogPost>();
postsGridView.DataSource = posts;
postsGridView.DataBind();
}
It is as simple as these 4 lines of code to connect to database, query the table and bind to a gridview using
Linq to Sql.
|
|
|
by Naveen
3. June 2010 04:37
Download Source Code (9.09 kb)
Download Binaries (6.28 kb)
Recently I started created some YouTube videos and wanted to embed them in my ASP.Net web site. YouTube
provides Embed button next to each video and that helps you create HTML code that you can
put on your page. But that would mean that you will have to hard code this HTML on all pages
where you want to embed videos. Also if you want to show some random videos on the pages, then this
approach is not flexible.
I created this ASP.Net server control that allows to embed YouTube videos on any page. The control allows
you to embed videos for which you already have URL or you can configure it to fetch any of the standard
YouTube feeds and then display random video from that feed.
How to use it?
- Download source code of the control and compile it or download pre-compiled binaries of the control.
- Add reference to ByteBlocks.YouTubeWeb assembly in your project.
-
On the page where you want to embed YouTube video, add the following directive at the top of the page.
<%@ Register TagPrefix="ByteBlocks" Assembly="ByteBlocks.YouTubeWeb"
Namespace="ByteBlocks.Web.Control" %>
-
Now add the control on the page.
<ByteBlocks:YouTube id="youTubeVideo" runat="server" Width="480" Height="385"
VideoUrl=""
FeedType="MostRecent" RandomResults="true" />
- And you are all set to show random video from Most Recent video feed from YouTube.
Configurable Properties
- VideoUrl: This property allows you to set URL of the video that needs to be embeded.
- Width: Sets the width of the video player
- Height: Set the height of the videeo player
- FeedType: If you do not want to use a pre-defined video URL, you can pick a standard
feed type. The control will fetch that feed from YouTube and display it based on value set for
RandomResults and IndexToShow. This property is mututally exlcusive
with VideoUrl. If you want the control to fetch standard feed, then do not set any
URL in VideoUrl.
- RandomResults: This property indicates to control to pick a random Video Url from
the list of videos from standard feed type.
- IndexToShow: If you set RandomResults to false, then the control
will fetch the video at this index value. If this index is out of range, then the control picks the
last entry in the feed list.
See it in Action
The following web site uses this control to show videos from most featured standard feed.
YouTube Server Control Demo
Under the covers
When you generate HTML code for a video from YouTube, it looks something like as shown below.
<object width="480" height="385">
<param name="movie" value="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="480" height="385"></embed>
</object>
So the control simply renders this HTML on ASP.Net page and uses the control properties to
configure the display accordingly. The important components of this HTML is video ID used with the
video player. I have shown that in bold in snipper above. A video URL looks like as shown below.
http://www.youtube.com/watch?v=Qp9_6ACSWug
Video ID is provided in v query string parameter. The control parses this ID and
replaces it in the URL that is required for URL for video player.
Source Code and Binaries
Attached code is compiled using Visual Studio 2010 and .Net 4.0 framework. If you need code for
earlier versions of Visual Studio, feel free to conttact me.
|
|
|
by Naveen
24. May 2010 10:09
Recently I was working on upgrading this site to from ASP.Net 2.0 to ASP.Net 4.0. As a first quick pass, I
followed my usual procedure of loading the projects into Visual Studio 2010 and set the target for all
projects to use .Net 4.0 framework. So far so good. I tested it on my development machine which is
Windows 7 and everything worked as I expected.
So I went ahead with deployment on my production Windows server. I changed the target ASP.Net framrwork of
my web site to ASP.Net 4.0 from ASP.Net 2.0. And site loaded and started serving requests. After
few hours I got an email from another site owner who is hosting site on my server that all sites have
stopped working and we were getting Server Error or Application Error. I have about dozen sites hosted on the
server and all but one stopped working. Only one that was working was this site that I just upgraded
to use ASP.Net 4.0. Right there I realized the mistake I made. This is the samee mistake that was
made when sites were upgraded from ASP.Net 1.1 to ASP.Net 2.0.
Mixed ASP.Net versions in Application Pool
Yes, now I had one site in the application pool that was using ASP.Net 4.0 and others were using ASP.Net 2.0.
Application pools do not allow mixed version of .Net framework. Here are some things that you will have to take
into consideration when migrating your existing ASP.Net sites from 2.0 t0 4.0 or when adding new sites
on Windows 2003 server.
- Make sure that you do not mix use of ASP.Net version in same pool
- Best option is to make a new Application Pool and put your new or migrated ASP.Net 4.0 sites in
there.
-
If you have already made a mistake (like I did) of mixing ASP.Net versions on application pool, then there
are few options you can use:
- Move the sites using ASP.Net 4.0 framework to a new pool or move ASP.Net 2.0 sites into new pool
depending on whatever is less work.
- I have run into cases where moving ASP.Net 4.0 out of pool did not work. If upgrading
all sites to ASP.Net4.0 framework is not going to break anything, then you may have to consider
that option.
- When you start upgrading existing sites to use new pool or upgrade to new ASP.Net 4.0 you may run
into problem that all sites start showing Service Unavailable error. This has
been happening a lot on Windows 2003 server. During process of upgrading and pool switching, some time
IIS stops working. You will notice a red cross mark on Web Sites node in IIS. You will have
to goto Service Control Manager to restart worldwide web publishing service on your server
I hope this little piece of information helps you get out of problem of upgrading existing site
to ASP.Net 4.0 when there are other sites in same pool that use older version of ASP.Net.
|
|
|
by Naveen
31. March 2010 05:37
Here is the scenario that this post is about. You have an existing DotNetNuke (DNN). Now you have to configure a new ASP.Net web application under this site as virtual directory. So you follow the standard procedure of creating a new virtual directory under your parent DNN site and point it to the location where the new web application's files are. Try to access this site and you will run into the following error.
Server Error in '/DNN53/ProductsSearch' Application.
--------------------------------------------------------------------------------
Configuration Error
Description: An error occurred during the processing of a configuration
file required to service this request. Please review the specific error details
below and modify your configuration file appropriately.
Parser Error Message: The code subdirectory '/DNN53/ProductsSearch/App_Code/IFrame/'
does not exist.
Source Error:
Line 168: -->
Line 169: <codeSubDirectories>
Line 170: <add directoryName="IFrame" />
Line 171: <add directoryName="Survey" />
Line 172: <add directoryName="XML" />
Source File: C:\Projects\DNN\DNN_V531\Install\web.config Line: 170
Now you are wondering what does these folders and files have to do anything with your web application that is hosted under DNN site. The thing that you need to understand is that when you are hosting a child application under parent ASP.Net application, it inherits web.config settings from all the parents as well. So in this case your application is inheriting DNN related settings as well. I have some one suggesting to add these missing folders in your new application as well. Next thing you will run into is that your site is complaining about missing DNN related assemblies.
The solution to this problem is not copy DNN assemblies or mimic the folder structure in your application as well. Because now you have added a very strong dependency on parent application. There is a very simple and elegant solution to this problem.
You can use this technique to restrict propagation on page by page or by folders etc.
|
|
|
by Naveen
26. March 2010 06:19
When you add an ASP.Net control like button, linkbutton, combobox etc. you expect that when you will click on this control, the page will cause a post back and you will be handling server side event handler for click on that control. Sometime you run into an issue when postback event does not fired. The clicking on control does not do anything. You get the feeling that no event is getting fired. There are only couple of reasons that can cause postback to not fire.
The least like cause can be that there is some client side javascript code that is cancelling event bubbling for your click event to respond. This is something that is highly unlikely because if you have some very custom implementation like this, then you are probably aware of it.
Most likely cause is that you have a control validator on the page and validation conditions are not satisfied when you are clicking on that control. And this problem becomes more cryptic when you forgot to add any visual indicator or error that tells you about validation condition violation. Here is another obvious cause of this problem. If you have a tab control on the page and one or more of the tabs have validation control(s). And then you are on tab that does not validation control. So you try to click on some control that has to cause PostBack. Now the problem is that although you are on different tab, but validators from other tabs are still part of the page. So before postback occurs, page is going to try to validate those validators. And if for some reason any of those validators fail, then postback action is cancelled.
So if you are running into this postback issue because of validators on tabs, then you need to handle tab switching event and then enable or disable those validators depending on your application rules etc.
|
|
|
f85fe941-cb24-4d4c-bd4b-d30f8821da59|0|.0
Views: 2761
Tags:
ASP.Net
by Viper
5. November 2009 06:19
When we are creating a web site, one of the main goal we all have is that out site should be listed on first page of search engines like Google, Bing, Yahoo, Baidu etc. As we all know that in SEO world, one of the first thing we all look for in the page is meta tags in header of the page. In the past there was no direct way to set the meta tags on a page programatically when developing ASP.Net web site. We all used the work around of adding metaelements in header element of the page. You can read my previous post Adding meta tags to asp.net page dynamically about that technique. With ASP.Net 4.0 microsoft has introduced following two properties on that allow you to set the meta tags on a page.
- MetaDescription
- MetaKeywords
Following code snippet shows how it is used in your code.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SetMetaTags();
}
private void SetMetaTags()
{
Title = "Hello Meta";
MetaDescription = "This is description of my ASP.Net 4.0 page.";
MetaKeywords = "ASP.Net,.Net4.0,Meta";
}
}
And it works. You can see from the source of the page as shown below.
<head>
<title>Hello Meta</title>
<meta name="description" content="This is description of my ASP.Net 4.0 page." />
<meta name="keywords" content="ASP.Net,.Net4.0,Meta" />
</head>
|
|
|
by Viper
6. October 2009 14:06
Download Demo Projects
This is one of the projects I have been planning to work on for some time. I was looking into building an event notifier in one of
my ASP.Net application. I wanted it to be more like Outlook Web Access (OWA) new email notifier pop-up. It is the one
that slides up from bottom right corner of your browser when there is a new email in your inbox. I had built it in the past
using all javascript solution. Yes, this Microsoft is one of the earliest implementation of so called AJAX applications.
I did not want to deal with all the javascript code related to setting up HTTP calls and then dealing with response and
rendering the results.
I wanted to leverage Silverlight to do all the heavy lifting. And use light weight javascript implementation on client
to do animated sliding and positioning of the popup notifier box. At the end it turned out be quite an elegant solution
that worked on major browsers like Internet Explorer, FireFox and Chrome. This article is an attempt to describe
How to implement OWA style new email notifier popup using Silverlight and Javascript.
The implementation involved the following technologies and I will describe how each component was implemented
- ASP.Net web application
- ASP.Net web service
- Silverlight application
ASP.Net Web Service
Let's start with discussion of the component that is responsible for communication of data between client and server application.
The client requests data from server at certain frequency to check if there are any new messages. So I implemented as simple
ASP.Net web service application with few web methods. For this demo I had a simple method with following signature.
[WebMethod]
public string GetGlobalMessages()
{
List msgs = MockData.GetGlobalMessages();
return msgs.ToJson();
}
For demo application, I implemented a MockData class that creates a random list of messages and then
serializes that collection as JSON and sends it in response. I implemented ToJson as an
extension method on List<StatusMessage> object. You will find it in Extension.cs
file in ActivityData project.
public static string ToJson(this List<StatusMessage> msgs)
{
var ser = new DataContractJsonSerializer(msgs.GetType());
var ms = new MemoryStream();
ser.WriteObject(ms, msgs);
var serializedData = System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray());
return serializedData;
}
You can see there is nothing fancy about this whole implementation to make it work with a Silverlight client. A very
simple ASP.Net web service.
Silverlight Application
This is where all the action happens. There are few components of this application, rendering and data access. Lets us first
discuss data access. The client application is to talk to server at certain frequency. That means I need some kind of
timer going in the application. When this timer ticks at specified interval of time, it send asynchronous request to server
to get new messages. I have implemented this whole mechanism in MessageMonitor application. When
this class is constructed, it creates an instance of DispatchTimer. You may be asking why DispatchTimer and
why not simple Timer application. The problem is that when you are dealing with user interface application, you
can only update the controls on the thread on which they were dispatched. Regular timer does not executes on that dispatcher
thread. So if you will try to update your user interface on that thread you will get exception complaining about
cross threaded access. Here is the code that created DispatcherTimer for my application.
private void CreateMessagePollTimer()
{
_messagePollTimer = new DispatcherTimer();
_messagePollTimer.Tick += new EventHandler(MessagePollTimer_Tick);
_messagePollTimer.Interval = new TimeSpan(0, 0, MessagePollInterval);
}
When the timer ticks it calls MessagePollTimer_Tick method. And that method makes async request to server
to get new messages.
void MessagePollTimer_Tick(object sender, EventArgs e)
{
if (Stopping || MessagePollInProgress) return;
GetMessages();
}
When async request to server completes, the following method gets called. You can see that now it uses the
same JsonSerializer class to de-serialize the response into list of StatusMessage objects. And
then it raises event for objects that have subscribed to the event.
void GetGlobalMessagesCompleted(object sender,
SiteMessagePanel.ActivityDataServices.GetGlobalMessagesCompletedEventArgs e)
{
if (e.Error != null)
{
return;
}
var msgsData = e.Result as String;
var msgs = msgsData.FromJson();
System.Diagnostics.Debug.WriteLine(msgs);
StatusMessageEventArgs args = new StatusMessageEventArgs(msgs);
OnStatusMessageReceieved(args);
}
Page class that implements user interface for popup, handles this event and renders all the
messages.
void Monitor_StatusMessageReceieved(object sender,
ByteBlocks.ActivityData.StatusMessageEventArgs arg)
{
if (arg.Messages.Count == 0)
{
msgTextBlock.Text = "No messages received";
ShowClientPanel(false);
return;
}
msgTextBlock.Text = string.Empty;
messagesPanel.Children.Clear();
foreach (var msg in arg.Messages)
{
StackPanel sp = new StackPanel();
TextBlock tb = new TextBlock();
tb.Text = msg.Title;
tb.TextWrapping = TextWrapping.Wrap;
sp.Children.Add(tb);
messagesPanel.Children.Add(sp);
}
ShowClientPanel(true);
}
ASP.Net application and javascript
ASP.Net application acts as a host for the silverlight control that I created to render messages. I have
implemented a simple Server Control that hosts it. Then I added that control inside a simple
div on the master page. And I have very simple vanilla implementation of the server control. It does
not have very complicated implementation. I simply copied the code generated by silverlight wizard for test page
into that control
<div id="statusslideup">
<ByteBlocks:StatusPanel runat="server" id="statusPanel" />
</div>
Calling Javascript Method From Silverlight
So far we have implemented two pieces of the application that drive the data and render it. Now comes the
fun part. How are we going to trigger the client to show the popup and animate it to come up from bottom.
First, it is Silverlight application that is running the timer. So it is the one that has to trigger the
client. I implemented some java script code that shows the DIV that hosts silverlight client
component. And then small piece of code that implements animation. Silverlight framework
provides a very simple mechanism to invoke any Javascript method that is implemented on client side.
I implemented a very simple method in silvelight application to call my JS method whenever
there are new messages for the user.
private void ShowClientPanel(bool show)
{
HtmlPage.Window.Invoke("_showStatusPanel", show);
}
It could not be any simpler. And the following Javascript function implements
small piece of code that calculates position of popup notifier window based on browser height and
height of element containing silverlight control.
setStatusPanelPosition = function() {
if (_statusdiv) {
_maxPanelPos = document.body.scrollTop + ($(document).height() - _statusdiv.clientHeight);
_curPanelPos = $(document).height();
if (!_isStatusVisible) {
_sliderInterval = setInterval("_slidePanel()", 5);
}
else {
_statusdiv.style.top = _maxPanelPos + "px";
}
_isStatusVisible = true;
}
}
Demo Project
Attached demo project is a collection of Visual Studio 2010 projects and solution. If you do not have VS2010, you
can simply create a new solution and projects in VS2008 and copy the source files in there. You are also
going to need to download Silverlight 3 Toolkit because I use theming controls from that toolkit to give
some zing to the UI.
I hope this demo project helps you in building cooler implementations of OWA like message and event notifier windows.
|
|
|
by Viper
1. October 2009 13:59
Recently I installed Visual Studio 2010 and was working on a prototype User Activity Monitoring administration application. When I tried to launch the application in Visual Studio IDE, I got the following error message box.
---------------------------
Microsoft Visual Studio
---------------------------
Unable to start debugging on the web server. Debugging failed because integrated
Windows authentication is not enabled. Please see Help for assistance.
---------------------------
OK Help
---------------------------
As the error suggests that I need to enable windows authentication. And that is a pre-requisites for running ASP.Net application under debugger. But thing that was different is that till Visual Studio 2008 when you made the IDE to create Virtual Directory, it used to enable windows authentication in IIS for that virtual directory. It seems that Visual Studio 2010 does things differently. It only enables anonymous access. You will have to explicitly enable windows authentication. It is simple procedure.
- Launch IIS manager
- Right click on virtual directory and select Properties menu option
- Select Directory Security tab on the dialog box.
- On this view click on Edit button in Anonymous access and authentication control section at top
- On this dialog box, check the check box at the bottom in front of Integrated Windows Authentication option.
- Click OK and apply your changes.

|
|
|
by Viper
2. September 2009 06:02
Transition from Windows XP to Windows 7 has been raising new issues every day during development
of desktop as well as web applications. Most of these are not issues per se. They are changes that were introduced
during Windows Vista and are part of Windows 7 as well. This piece of information has to do
with network protocols on Windows 7. Here is what happened. I am developing a web application. One of the
things I had to do in the application is to check if the request URL is from localhost or loopback
address then do something different otherwise follow normal routine. So I was comparing Request.UserHostAddress with
standard loopback address of 127.0.0.1. It was working fine. Then I started an instance of IE and
tried to test the page. Well, nothing seemed to work. When I debugged the code, I saw that value of Request.UserHostAddress
was ::1 instead of 127.0.0.1. By looking at the IP address I could tell that it was standard IPv6
loop back IP address. Actually the loopback address on an IPv6 network is 0:0:0:0:0:0:0:1 which is abbreviated as ::1. Then
I paid close attention to IPAddress class in .Net framework. There is a method IsLoopback that you can
use to test for loopback address. And you will use Parse method to create instance of IPAddress object.
After making these changes, my implementation looked as below.
private void GetUserFromIp()
{
UserGeoLocator geoLocator = new UserGeoLocator();
_userLocation = null;
var ip = IPAddress.Parse(Request.UserHostAddress);
if (IPAddress.IsLoopback(ip) ||
string.Compare(Request.UserHostAddress, "127.0.0.1", 0) == 0)
{
_userLocation = geoLocator.GetUserLocationByIp("68.xxx.xxx.xxx");
}
else
{
_userLocation = geoLocator.GetUserLocationByIp(Request.UserHostAddress);
}
}
IPv6 is enabled by default on Windows Vista as well as Windows 7. If you use Visual Studio
Development Server to debug your application, you will notice that loopback address is in IPv4 format but if you use
IIS to debug your ASP.Net application, the loopback address is in IPv6 format. To avoid any issues like this, using
IsLoopback makes the implementation neutral to format because framework will take care of interpretting the IP
address correctly when you use Parse to create instance of IPAddress object.
You can diable use of IPv6 on Windows 7 by following instructions in
How to disable certain Internet Protocol version 6 (IPv6) components in Windows Vista, Windows 7 and Windows Server 2008. If you
are not using any format specific implementation, then you do not have to do that and I would not suggest doing it if you
are not comfortable dealing with changing registry entries.
|
|
|
by Viper
6. August 2009 05:26
I have been working with VS2010 and ASP.Net 4.0 for quite some time now. Every time i create a web application, I just use the handy feature of Visual Studio of creating virtual directory for web application. Last week I was manually creating virtual directory for a web application using IIS manager. Since the application was targeting ASP.Net 2.0, so from ASP.Net tab of IIS, I selected V2.0 framework. Now there is a confirmation dialog box that comes up when you change ASP.Net framework.
Changing the Framework version requires a restart of the W3SVC service. Alternatively, you can change the Framework version without restarting the W3SVC service by running: aspnet_regiis.exe -norestart -s IIS-Viirtual-Path
Do you want to continue (this will change the Framework version and restart the W3SVC service)?
Everything is good so far. Moment i accessed the application in browser, I got the following error message.
Server Error in '/Foo' Application.
The application domain or application pool is currently running version 4.0 or later of the .NET Framework. This can occur if IIS settings have been set to 4.0 or later for this Web application, or if you are using version 4.0 or later of the ASP.NET Web Development Server. The <compilation> element in the Web.config file for this Web application does not contain the required 'targetFrameworkMoniker' attribute for this version of the .NET Framework (for example, '<compilation targetFrameworkMoniker=".NETFramework,Version=v4.0">'). Update the Web.config file with this attribute, or configure the Web application to use a different version of the .NET Framework.
I was little surprised because I never configured virtual directory for this application to use ASP.Net 4.0. I fired up IIS manager and went to ASP.Net tab. There it was, the application was configured to use ASP.Net 4.0. So I changed it back to use ASP.Net 2.0. Accessed the application in browser and got the same error again. I experimented with the drop down box for ASP.Net version in IIS manager. The application will get configured to use ASP.Net 4.0 no matter what option I picked from the drop down box. It seems that this is some bug in beta version of Visual Studio 2010 installation.
For now the work around I have been using is to let Visual Studio create virtual directory for my web application. It targets the correct ASP.Net version and modifies IIS meta data correctly.
|
|
|
by Viper
22. July 2009 12:31
While experimenting with setting up of Cache-Control headers on Response object, i ran into following exception when I tries to access Headers property of Response object directly.
Exception type: PlatformNotSupportedException
Exception message: This operation requires IIS integrated pipeline mode.
If i had read the documentation for Headers property I would have not done it at the first place. Here is what documentation says. The Headers property is only supported with the IIS 7.0 integrated pipeline mode and at least the .NET Framework 3.0. So if you are setting an headers in the response on IIS6 or earlier, use AddHeader method of Response object.
a6971319-714e-4a64-a830-c822ae1eb6a9|0|.0
Views: 5193
Tags:
ASP.Net
by Viper
22. July 2009 03:43
I have been developing AJAX enabled applications before the term AJAX was coined. I have been doing it for so long that some of things that I do come kind of naturally. And one of the things that I always do is to make sure that response is not cached to ensure that client is never working on stale response even though it sent new request every few seconds. So I have a small piece of code that I pretty much use in all applications that sets some headers.
Response.ContentType = "text/plain";
Response.Expires = -1;
Response.CacheControl = "no-cache";
These are not just the only headers but gives you an idea how cache was being control. I never ran into any trouble with any applications till last week when I was told that our application is filling up Temporary Internet Files folder of the users. This was the first time ever I was reported such issue and actually this was first time I observed this behavior in my applications. So I fired up Fiddler to see whats going on with my requests. I looked at the response headers and saw the following.
First, I was not expecting to see Cache-Control: private. So that was little out of whack. Second, the expiration time was correct because I always set to an hour behind the response time to make sure that it is stale for caching. I have been using the same caching utility routine for so long that I did not suspect that something is wrong there. Then I looked inside Temporary Internet Files folder again and noticed that this was the only request that was being saved in the folder, others were not. So I looked at the implementation and found that the server side implementation for this request was not using my standard utility to set cache headers. Following is the code snippet that I ad in place. Well why i changed the implementation for this particular call is whole different story.
Response.ContentType = "text/plain";
Response.Expires = -1;
Notice that it is missing Cache-control : no-cache header. That explained everything. After I added this header, everything went back to normal. So I decided to do some experiment to observe behavior of setting different headers.
No Cache-control: no-cache header on any call
You will notice that from my earlier post How to serialize multiple AJAX calls in jQuery, I have two AJAX calls being made. And you can see from snapshot above that both are being saved in Temporary Internet File folder.
Cache-control: no-cache header set on one request only
Now you can see that only one request is being saved in the folder and other has disappeared.
Cache-Control:no-cache header set on all requests
Well, there is nothing to show here in Temporary Internet Files folder because nothing is being saved there any more. But here is the snapshot of response headers as seen in Fiddler.
Now you can see that no-cache header and pragma has been set correctly.
Set cache-control header correctly
As more and more applications are using AJAX or Web2.0 style of implementations, if you do not set these cache control headers correctly, you will see that browser cache folders will accumulate lot of entries. It is not that big of a deal as far as application working goes because this temporary cache will not grow beyond specified limits for a particular browser. But it will hurt performance of other internet sites that you visit because their content will not be found in cache and will have to reloaded from server again. Other performance hit you will take is that now browser has to spend an extra CPU cycle to save these entries on the disk.
|
|
|
by Viper
20. July 2009 15:06
Download Sample Project
For one of my current project, I have been using ASP.Net AJAX to make async request into my ASP.Net to get some time related data. First, I am not a big fab of ASP.Net AJAX implementation. I will not go into debate on why. There are plenty of discussions on this topic. I will just spare myself from it. Second, the application was already using jQuery for other javascript related implementation. I was like, if we are already using jQuery why have an overhead of introducing Ajax tool kit. So I started porting the implementation to use jQuery. Through this series of posts, I will describe how you can use jQuery to make AJAX calls in ASP.Net applications. Well, the client side javascript can be used in any browser. So other than the server side implementation, there is no nothing specific to ASP.Net per se.
The sample project for these articles is a time synchronization service. The idea is that I want to display clock on the client machine that will display server time. Well you can say there is no big deal with that implementation. On page load, get the server time. Save in some client side variable and run one second timer on it. Well, that works for most part. There are situations where clients are behind really slow connections that can cause of lot latency in request and response. So in those cases, by the time your response gets to the client side, the server time that you returned to client is already behind by few seconds. For applications that has users who depend very heavily on this server time, this latency of few seconds can be very critical. In this first post I am not going to go into details of algorithm that I implemented to reduce this latency adjustment over time. This first sample does a very simple task. It sends asynchronous request to server every 10 seconds. The server returns its time and then client uses that to display clock.
Server Side Implementation
I have a class ClockData that has DataContract attribute set on it. You can pretty much figure out that I am planning on converting this service to WCF service and use the framework facilities to serialize and de-serialize data as well. So I am populating this class with three pieces of data (server time, latency and a cookie) and then using DataContractJsonSerializer class to serialize the data into JSON format and sending it to client.
private void SerializeServerClockData(ClockData data, Stream strm)
{
var spSer =
new DataContractJsonSerializer(typeof(ClockData));
spSer.WriteObject(strm, data);
}
void SendResponse()
{
long ms = (long)(_serverTime - new DateTime(1970, 1, 1)).TotalMilliseconds;
var clockData = new ClockData()
{ServerTime = ms.ToString(), Latency = _latency, ResponseKey = Guid.NewGuid().ToString("N")};
Response.ContentType = "text/plain";
Response.Expires = -1;
Response.CacheControl = "no-cache";
SerializeServerClockData(clockData, Response.OutputStream);
Response.End();
}
From the code snippet above, you can see how plain and simple server side implementation is for this first sample. This will get little complicated as I get more into the actual algorithm of calculation of latency reduction.
Client Side Implementation
Since we are going to be using jQuery to make Ajax call, so we will need to include reference to jQuery javascript file. For this sample, I am going to show the AJAX request you can send using jQuery. The library has method named .getJSON that you can call to send the request. You can set the URL where request is to be sent, set the parameters that needs to be passed with request and set the callback function that should be called when request completes. It is that simple. Here is the implementation from the sample.
function getServerTime() {
cTime = firstRequest ? -1 : curTime.getTime();
$.getJSON(clockServiceUrl, { clientTime: cTime, requestKey: respKey }, gotServerTime);
}
function gotServerTime(data) {
firstRequest = false;
latency = data.Latency;
curTime = new Date(parseInt(data.ServerTime));
if (!clockTicking) createClockTimer();
createServiceTimer(defaultServiceTimer);
}
function clockTick() {
clockTicking = true;
curTime.setTime(curTime.getTime() + 1000);
elClockDisplay.text(curTime.toString());
if (latency == -1)
{ elLatencyDisplay.text(""); }
else
{elLatencyDisplay.text(latency + " ms");}
}
$(function() {
elClockDisplay = $('#clockDisplay');
elLatencyDisplay = $('#latencyDisplay');
getServerTime();
});
In subsequent posts I will discuss how you can control the request little bit more instead of using .getJSON to use default settings.
|
|
|
Powered by BlogEngine.NET 1.5.1.7
Theme by Naveen Kohli
|
|