tag:blogger.com,1999:blog-6233489493094911302023-06-20T06:04:43.980-07:00Dhaval UpadhyayaArticles on Microsoft TechnologyDhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-623348949309491130.post-42554234122054511652013-06-03T05:17:00.000-07:002017-06-01T01:55:05.511-07:00What a boon. MVC 4.0 + JQuery Mobile + SignalR<strong><span style="color:#ff9900;">MVC 4.0 + JQuery Mobile + SignalR</span></strong><br/><br/><strong>What a boon!</strong><br/><br/>MVC 4.0 + JQuery Mobile + SignalR<br/>Few of the best technologies when clubbed together can create a fabulous masterpiece within a time you blink your eye.<br/><br/>Here in this post I will brief you about how to create mobile application using MVC4.0, JQuery Mobile and SignalR.<br/><br/>For detail Chat application and SignalR technicalities please refer my previous posts.<br/><a href="http://dhavalupadhyaya.wordpress.com/2012/11/13/srchat-plug-play-enjoy/" target="_blank"> http://dhavalupadhyaya.wordpress.com/2012/11/13/srchat-plug-play-enjoy/</a><br/><a href="http://dhavalupadhyaya.wordpress.com/2012/10/09/signalr-to-rescue/" target="_blank"> http://dhavalupadhyaya.wordpress.com/2012/10/09/signalr-to-rescue/</a><br/><br/><span style="text-decoration:underline;"><strong>Prerequisite:</strong></span><br/><br/>MVC 4.0 ( <a href="http://www.asp.net/mvc/mvc4" target="_blank">http://www.asp.net/mvc/mvc4</a> )<br/>Basic Knowledge of Razor ( <a href="http://www.w3schools.com/aspnet/razor_intro.asp" target="_blank">http://www.w3schools.com/aspnet/razor_intro.asp</a> )<br/>Basic Knowledge of SignalR ( <a href="https://github.com/SignalR/SignalR/wiki" target="_blank">https://github.com/SignalR/SignalR/wiki</a> )<br/>Basic Knowledge of JQuery Mobile ( <a href="http://view.jquerymobile.com/1.3.1/dist/demos/" target="_blank">http://view.jquerymobile.com/1.3.1/dist/demos/</a> )<br/><br/>So let’s gets started<br/><br/>Step 1) Start visual studio and create a new Web Project with ASP.NET MVC 4 WEB Application template as shown below.<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_1.png"><img class="alignnone size-medium wp-image-238" alt="Step 1" src="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_1.png?w=300" width="300" height="228" /></a><br/><br/>Step 2) Select Mobile Application Project Template and click OK.<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_2.jpg"><img class="alignnone size-medium wp-image-281" alt="Step 2" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_2.jpg?w=286" width="286" height="300" /></a><br/><br/>Step 3) This will create a fresh web application with MVC 4.0 framework and some prebuild models, views and controllers for asp.net membership. We will use this as base project and add chat module to it in later steps. Change the “DefaultConnection” connectionstring into web.config file to point to your valid blank database. (Asp.Net will create the sql database to be used by membership when user registers for the first time)<br/><br/>Step 4) Install SignalR infrastructure. Go to Tools > Library Package Manager > Package Manager Console and Run below command as shown below<br/><br/>[sourcecode language="csharp"]<br/>Install-Package Microsoft.AspNet.SignalR<br/>[/sourcecode]<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_3.jpg"><img class="alignnone size-medium wp-image-282" alt="Step 4" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_3.jpg?w=300" width="300" height="257" /></a><br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_4.jpg"><img class="alignnone size-medium wp-image-283" alt="Step 4" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_4.jpg?w=300" width="300" height="228" /></a><br/><br/>Step 5) Once SignalR infrastructure is added, Goto Global.asax.cs and add “RouteTable.Routes.MapHubs();” line to the “Application_Start” method of the page as shown below. Without this route mapping MVC framework would not be able to map the requests sent by SignalR infrastructure. Also make sure you register this routs before you map any other routes in this method.<br/><br/>[sourcecode language="csharp"]<br/><br/>using System;<br/>using System.Collections.Generic;<br/>using System.Linq;<br/>using System.Web;<br/>using System.Web.Http;<br/>using System.Web.Mvc;<br/>using System.Web.Optimization;<br/>using System.Web.Routing;<br/><br/>namespace SRJQM<br/>{<br/> // Note: For instructions on enabling IIS6 or IIS7 classic mode,<br/> // visit http://go.microsoft.com/?LinkId=9394801<br/><br/> public class MvcApplication : System.Web.HttpApplication<br/> {<br/> protected void Application_Start()<br/> {<br/> // Register the default hubs route: ~/signalr<br/> RouteTable.Routes.MapHubs();<br/><br/> AreaRegistration.RegisterAllAreas();<br/><br/> WebApiConfig.Register(GlobalConfiguration.Configuration);<br/> FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);<br/> RouteConfig.RegisterRoutes(RouteTable.Routes);<br/> BundleConfig.RegisterBundles(BundleTable.Bundles);<br/><br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Step 6) Create a new Class named “SRChatServer” that inherits from “Hub” class. Add a simple new method named “SendMessage” that will broadcast message to all the mobile clients that are connected to this hub.<br/><br/>[sourcecode language="csharp"]<br/><br/>using System;<br/>using System.Collections.Concurrent;<br/>using System.Linq;<br/>using System.Threading.Tasks;<br/>using Microsoft.AspNet.SignalR.Hubs;<br/>using Microsoft.AspNet.SignalR;<br/><br/>namespace SRJQM<br/>{<br/> [HubName("sRChatServer")]<br/> public class SRChatServer : Hub<br/> {<br/> public void SendMessage(string user, string message)<br/> {<br/> Clients.All.addMessage(user, message);<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Step 7) Now let’s create the Chat Model\View\Controller using which user will be able to send and receive broadcasted messages from the hub created in above step.<br/><br/>Step 8) Create a Class named “ChatController” in Controllers section. Add [Authorize] attribute to this class as we want to restrict its access only to the users who are logged into the application. Add “Index” method that will simply redirect the user to the Index.cshtml view inside the chat area which we will create in next step.<br/><br/>[sourcecode language="csharp"]<br/><br/>using System;<br/>using System.Collections.Generic;<br/>using System.Linq;<br/>using System.Web;<br/>using System.Web.Mvc;<br/>using System.Web.Security;<br/><br/>namespace SRJQM.Controllers<br/>{<br/> [Authorize]<br/> public class ChatController : Controller<br/> {<br/> public ActionResult Index()<br/> {<br/> try<br/> {<br/> ViewBag.Message = "Welcome to chat sample : " + User.Identity.Name;<br/> return View();<br/> }<br/> catch (Exception ex)<br/> {<br/> throw ex;<br/> }<br/> }<br/><br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>9) Create a folder (area) named “Chat” inside “Views” folder. Add “Index.cshtml” inside this folder. This is the main page that will connect to SignalR Server Hub created above. It also contains UI that is used for sending and receiving messages that are broadcasted by the SignalR server hub.<br/><br/>[sourcecode language="html"]<br/><br/><script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script><br/><script src="../../Scripts/jquery.signalR-1.1.2.min.js" type="text/javascript"></script><br/><script src="~/signalr/hubs"></script><br/>@model SRJQM.Models.LoginModel<br/>@{<br/> ViewBag.Title = "Chat Page";<br/>}<br/><h2>@ViewBag.Message</h2><br/><p><br/> To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website"><br/> http://asp.net/mvc</a>.<br/></p><br/><div data-role="content"><br/> <div data-role="fieldcontain"><br/> <ul id="messages"><br/> </ul><br/> </div><br/> <div data-role="fieldcontain"><br/> <label for="txtMessage"><br/> Message:<br/> </label><br/> <input name="txtMessage" id="txtMessage" placeholder="Type Message" value="" type="text"><br/> </div><br/> <div class="ui-grid-a"><br/> <div class="ui-block-a"><br/> <a id="btnSendChat" data-role="button" data-theme="b" href="#">Send </a><br/> </div><br/> <div class="ui-block-b"><br/> <a id="btnClear" data-role="button" data-theme="b" href="#">Clear </a><br/> </div><br/> </div><br/></div><br/><ul data-role="listview" data-inset="true"><br/> <li data-role="list-divider">Navigation</li><br/> <li>@Html.ActionLink("Home", "Index", "Home")</li><br/> <li>@Html.ActionLink("About", "About", "Home")</li><br/> <li>@Html.ActionLink("Contact", "Contact", "Home")</li><br/></ul><br/><script type="text/javascript"><br/> $(function () {<br/> var chatHub = $.connection.sRChatServer;<br/><br/> // Start the connection<br/> $.connection.hub.start();<br/><br/> // Declare a function on the blog hub so the server can invoke it<br/> chatHub.client.addMessage = function (user, message) {<br/> $('#messages').append('<li><strong>' + user + '</strong>: ' + message + '</li>');<br/> };<br/><br/> $("#btnSendChat").click(function (event) {<br/> chatHub.server.sendMessage("@User.Identity.Name", $("#txtMessage").val());<br/> $("#txtMessage").val("")<br/> });<br/><br/> $("#btnClear").click(function (event) {<br/> $("#txtMessage").val("")<br/> });<br/> });<br/></script><br/><br/>[/sourcecode]<br/><br/>10) Goto Views > Home folder and code conditional link inside Index.cshtml, About.cshtml, and Contact.cshtml views as shown below. This link will help user to navigate to chat module.<br/><br/>[sourcecode language="csharp"]<br/><br/><ul data-role="listview" data-inset="true"><br/> <li data-role="list-divider">Navigation</li><br/> <li>@Html.ActionLink("About", "About", "Home")</li><br/> <li>@Html.ActionLink("Contact", "Contact", "Home")</li><br/> @if (Request.IsAuthenticated)<br/> {<br/> <li>@Html.ActionLink("Chat", "Index", "Chat", routeValues: null, htmlAttributes: null)</li><br/> }<br/></ul><br/><br/>[/sourcecode]<br/><br/>That’s it.<br/>Compile the project and open multiple instances of browser or mobile, login into the application using different registered users and start using the application.<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_5.jpg"><img class="alignnone size-medium wp-image-284" alt="Step 5" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_5.jpg?w=161" width="161" height="300" /></a> <a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_6.jpg"><img class="alignnone size-medium wp-image-285" alt="Step 6" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_6.jpg?w=162" width="162" height="300" /></a><br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_7.jpg"><img class="alignnone size-medium wp-image-286" alt="Step 7" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_7.jpg?w=161" width="161" height="300" /></a> <a href="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_8.jpg"><img class="alignnone size-medium wp-image-279" alt="Step 8" src="http://dhavalupadhyaya.files.wordpress.com/2013/06/srjqm_8.jpg?w=155" width="155" height="300" /></a>Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-28516183751661713142012-11-13T04:32:00.000-08:002017-06-01T01:55:05.495-07:00SRChat Plug Play Enjoy<strong><span style="color:#ff9900;">SignalR Chat Plug Play Enjoy</span></strong><br/><br/>Hey as per my promise and continuation to my previous SignalR To Rescue article here I present the more, in-depth concepts and overview of Chat application build over SignalR and asp.net.<br/>For those who are novice to SignalR or have not read my previous post about basic infrastructure and overview and notification sample of SignalR are advised to go through this post first.<br/>Coming straight to the point below is the overview of the chat module that you will build step by step while progressing this post<br/>- It uses SignalR infrastructure as the base.<br/>Used for coding “SRChatServer” server hub and “SRChatClient” client hub.<br/>- It uses JQuery version 1.8.2<br/>Used for all the power pact code on “SRChatClient” client hub<br/>- It uses JQuery Template based binding mechanism for creating UI on client as part of best practice.<br/>Used for binding the json data coming from “SRChatServer” methods and binding it to templates to generate the html based UI quickly<br/>- It uses JQuery Dialog Extension from crab community at http://code.google.com/p/jquery-dialogextend/. Thanks a ton guys for such a beautiful and sleek master piece.<br/>Used for showing the minimizable and movable dialog boxes for each chat instances with different users.<br/><br/><strong>Brief Architecture Overview</strong><br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2012/11/srchat.jpg"><img class="alignnone size-medium wp-image-263" title="SRChat" alt="" src="http://dhavalupadhyaya.files.wordpress.com/2012/11/srchat.jpg?w=300" height="288" width="300" /></a><br/><br/>Step 1) Create the asp.net web application project and install the SignalR infrastructure. Please refer SignalR to Rescue for basic configuration<br/><br/>Step 2) Create a serializable class named “MessageRecipient“. This class would act as an object for the users connecting to server hub. The reason for marking it serializable is to make easy transfer across the ajax request easily.<br/><br/>[sourcecode language="csharp"]<br/> [Serializable]<br/> public class MessageRecipient<br/> {<br/> publicMessageRecipient()<br/> {<br/> chatRoomIds = new List();<br/> }<br/> public string messageRecipientId { get; set; }<br/> public string messageRecipientName { get; set; }<br/> public string connectionId { get; set; }<br/> public ListchatRoomIds { get; set; }<br/> }<br/>[/sourcecode]<br/><br/>Step 3) Create a serializable class named “ChatRoom “.This class would act as a bridge between the users who want to chat with each other. The same concept can be enhanced for providing Group Chat feature to this module with few lines of code.<br/><br/>[sourcecode language="csharp"]<br/> [Serializable]<br/> public class ChatRoom<br/> {<br/> public string chatRoomId { get; set; }<br/> public string chatRoomInitiatedBy { get; set; }<br/> public string chatRoomInitiatedTo { get; set; }<br/> public ListmessageRecipients { get; set; }<br/><br/> publicChatRoom()<br/> {<br/> chatRoomId = Guid.NewGuid().ToString();<br/> messageRecipients = new List();<br/> }<br/> }<br/>[/sourcecode]<br/><br/>Step 4) Create a serializable class named “ChatMessage“. This class would act as an object for each chat messages that are exchanged between the users over chat.<br/><br/>[sourcecode language="csharp"]<br/> [Serializable]<br/> public class ChatMessage<br/> {<br/> publicChatMessage()<br/> {<br/> }<br/><br/> public string chatMessageId { get; set; }<br/> public string conversationId { get; set; }<br/> public string senderId { get; set; }<br/> public string senderName { get; set; }<br/> public string messageText { get; set; }<br/> public string displayPrefix { get { return string.Format("[{0}] {1}:", timestamp.ToShortTimeString(), senderName); } }<br/> publicDateTime timestamp { get; set; }<br/> }<br/>[/sourcecode]<br/><br/>Step 5) Create a serializable class named “OnlineContacts“. This class would act as an object for each userconnecting to server hub. It is used here so that a list of Message Recipients can be transferred back to client hub when the user wants to initiate the chat.<br/><br/>[sourcecode language="csharp"]<br/> [Serializable]<br/> public class OnlineContacts<br/> {<br/> public ListmessageRecipients { get; set; }<br/> publicOnlineContacts()<br/> {<br/> messageRecipients = new List();<br/> }<br/> }<br/>[/sourcecode]<br/><br/>Step 6) Finally create a class named “SRChatServer” and inherit from Hub class. This is the server hub that would act as the main heart for building the chat server. Decorate the class with [HubName] attribute. This is the name that Client hub uses to connect to sever hub. We will also add two private static variables for holding our data related to chat rooms and users connected to server hub. As SignalR core is totally thread safe I am using ConcurrentDictionary in order to maintain our collection in thread safe manner.<br/><br/>[sourcecode language="csharp"]<br/>[HubName("sRChatServer")]<br/> public class SRChatServer : Hub<br/> {<br/> #region Private Variables<br/> private static readonly ConcurrentDictionary<string, MessageRecipient> _chatUsers = new ConcurrentDictionary<string, MessageRecipient>(StringComparer.OrdinalIgnoreCase);<br/> private static readonly ConcurrentDictionary<string, ChatRoom> _chatRooms = new ConcurrentDictionary<string, ChatRoom>(StringComparer.OrdinalIgnoreCase);<br/> #endregion<br/> }<br/>[/sourcecode]<br/><br/>Now let’s start adding more ingredients to our server hub.<br/><br/>First we will add connect and disconnect method. Connect method is called whenever the client is loaded for first time and theninitiates the request to connect to server hub. It will simply fetch some data related to connecting client like its connection ID, user IDetc. and store or modify the collection maintained on server hub. Similarly the Disconnect method is called just before the client moves out from the server hub.<br/><br/>[sourcecode language="csharp"]<br/>public bool Connect(string userId, string userName)<br/> {<br/> try<br/> {<br/> if (string.IsNullOrEmpty(userId) | string.IsNullOrEmpty(userName))<br/> {<br/> return false;<br/> }<br/> if (GetChatUserByUserId(userId) == null)<br/> {<br/> AddUser(userId, userName);<br/> }<br/> else<br/> {<br/> ModifyUser(userId, userName);<br/> }<br/> SendOnlineContacts();<br/> return true;<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in connecting to chat server!");<br/> }<br/> }<br/> public override Task Disconnect()<br/> {<br/> try<br/> {<br/> DeleteUser(Context.ConnectionId);<br/> return null;<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in disconnecting from chat server!");<br/> }<br/> }<br/>[/sourcecode]<br/><br/>Now let’s add few methods that will help clients to initiate and end chat with other users. InitiateChat method simply takes in required data about the users who want to get connected and start the chat. The code simply builds a technical bridge between the two and initiates a pipeline through ChatRoom using which messages will be exchanged. The EndChat method simply ends the chat and removes the bridge between the two.<br/><br/>[sourcecode language="csharp"]<br/>public bool InitiateChat(string fromUserId, string fromUserName, string toUserId, string toUserName)<br/> {<br/> try<br/> {<br/> if (string.IsNullOrEmpty(fromUserId) || string.IsNullOrEmpty(fromUserName) || string.IsNullOrEmpty(toUserId) || string.IsNullOrEmpty(toUserName))<br/> {<br/> return false;<br/> }<br/><br/> var fromUser = GetChatUserByUserId(fromUserId);<br/> var toUser = GetChatUserByUserId(toUserId);<br/><br/> if (fromUser != null && toUser != null)<br/> {<br/> if (!CheckIfRoomExists(fromUser, toUser))<br/> {<br/> //Create New Chat Room<br/> ChatRoom chatRoom = new ChatRoom();<br/> chatRoom.chatRoomInitiatedBy = fromUser.messageRecipientId;<br/> chatRoom.chatRoomInitiatedTo = toUser.messageRecipientId;<br/><br/> chatRoom.messageRecipients.Add(fromUser);<br/> chatRoom.messageRecipients.Add(toUser);<br/><br/> //create and save blank message to get new conversation id<br/> ChatMessage chatMessage = new ChatMessage();<br/> chatMessage.messageText = "Chat Initiated";<br/> chatMessage.senderId = fromUser.messageRecipientId;<br/> chatMessage.senderName = fromUser.messageRecipientName;<br/><br/> fromUser.chatRoomIds.Add(chatRoom.chatRoomId);<br/> toUser.chatRoomIds.Add(chatRoom.chatRoomId);<br/><br/> //Create SignalR Group for this chat room and add users connection to it<br/> Groups.Add(fromUser.connectionId, chatRoom.chatRoomId);<br/> Groups.Add(toUser.connectionId, chatRoom.chatRoomId);<br/><br/> //Add Chat room object to collection<br/> if (_chatRooms.TryAdd(chatRoom.chatRoomId, chatRoom))<br/> {<br/> //Generate Client UI for this room<br/> Clients[fromUser.connectionId].initiateChatUI(chatRoom);<br/> }<br/> }<br/> }<br/> return true;<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in starting chat!");<br/> }<br/> }<br/> public bool EndChat(ChatMessage chatMessage)<br/> {<br/> try<br/> {<br/> ChatRoom chatRoom;<br/> if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))<br/> {<br/> if (_chatRooms[chatRoom.chatRoomId].chatRoomInitiatedBy == chatMessage.senderId)<br/> {<br/> chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);<br/> if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))<br/> {<br/> Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);<br/> foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)<br/> {<br/> if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))<br/> {<br/> messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);<br/> Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);<br/> }<br/> }<br/> }<br/> }<br/> else<br/> {<br/> MessageRecipient messageRecipient = GetChatUserByUserId(chatMessage.senderId);<br/> if (messageRecipient != null && messageRecipient.chatRoomIds.Contains(chatRoom.chatRoomId))<br/> {<br/> chatRoom.messageRecipients.Remove(messageRecipient);<br/> messageRecipient.chatRoomIds.Remove(chatRoom.chatRoomId);<br/> if (chatRoom.messageRecipients.Count < 2)<br/> {<br/> chatMessage.messageText = string.Format("{0} left the chat. Chat Ended!", chatMessage.senderName);<br/> if (_chatRooms.TryRemove(chatRoom.chatRoomId, out chatRoom))<br/> {<br/> Clients[chatRoom.chatRoomId].receiveEndChatMessage(chatMessage);<br/> foreach (MessageRecipient messageReceipient in chatRoom.messageRecipients)<br/> {<br/> if (messageReceipient.chatRoomIds.Contains(chatRoom.chatRoomId))<br/> {<br/> messageReceipient.chatRoomIds.Remove(chatRoom.chatRoomId);<br/> Groups.Remove(messageReceipient.connectionId, chatRoom.chatRoomId);<br/> }<br/> }<br/> }<br/> }<br/> else<br/> {<br/> chatMessage.messageText = string.Format("{0} left the chat.", chatMessage.senderName);<br/> Groups.Remove(messageRecipient.connectionId, chatRoom.chatRoomId);<br/> Clients[messageRecipient.connectionId].receiveEndChatMessage(chatMessage);<br/> Clients[chatRoom.chatRoomId].receiveLeftChatMessage(chatMessage);<br/> Clients[chatRoom.chatRoomId].updateChatUI(chatRoom);<br/> }<br/> }<br/> }<br/> }<br/> else<br/> {<br/> throw new InvalidOperationException("Problem in ending chat!");<br/> }<br/> return true;<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in ending chat!");<br/> }<br/> }<br/>[/sourcecode]<br/><br/>Finally add below methods that actually send the message to particular client. SendChatMessage sends the message from one user to another and invokes the client hub method to push message to that particular client. SendOnlineContacts is just used for getting the online users list using which the chat can be initiated with anyone of them. I have kept this method private so that I can call it from connect method to broad cast the entire list including new user to all the users. If you want to fetch online contacts on some trigger on client do not forget to make it public.<br/><br/>[sourcecode language="csharp"]<br/>public bool SendChatMessage(ChatMessage chatMessage)<br/> {<br/> try<br/> {<br/> ChatRoom chatRoom;<br/> if (_chatRooms.TryGetValue(chatMessage.conversationId, out chatRoom))<br/> {<br/> chatMessage.chatMessageId = Guid.NewGuid().ToString();<br/> chatMessage.timestamp = DateTime.Now;<br/> Clients[chatMessage.conversationId].receiveChatMessage(chatMessage, chatRoom);<br/> return true;<br/> }<br/> else<br/> {<br/> throw new InvalidOperationException("Problem in sending message!");<br/> }<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in sending message!");<br/> }<br/> }<br/> private bool SendOnlineContacts()<br/> {<br/> try<br/> {<br/> OnlineContacts onlineContacts = new OnlineContacts();<br/> foreach (var item in _chatUsers)<br/> {<br/> onlineContacts.messageRecipients.Add(item.Value);<br/> }<br/> Clients.onGetOnlineContacts(onlineContacts);<br/> return false;<br/> }<br/> catch (Exception ex)<br/> {<br/> throw new InvalidOperationException("Problem in getting contacts!");<br/> }<br/> }<br/>[/sourcecode]<br/><br/>Apart from the above methods there are few auxiliary methods for supporting the above business logic.<br/><br/>That’s it for server hub. Now let’s plug Client Hub Code step by step<br/><br/>Step 1) Add a new asp.net webform and name it “SRChatClient.aspx”<br/>This webform will be our chat client using which users can chat with each other. This webform when loaded will generate a random number and using this random number it connects with SRChatServer and registers itself. When multiple instances of different browsers are opened we have a group of users getting online who can chat with each other.<br/><br/>[sourcecode language="html"]<br/><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SRChatClient.aspx.cs" Inherits="SRChat.SRChatClient" %></pre><br/><style><!--<br/> .chatRooms<br/> {<br/> max-height: 500px;<br/> overflow: auto;<br/> }<br/> .chatRoom<br/> {<br/> width: 100%;<br/> height: 250px;<br/> border: 1px solid #ccc;<br/> }<br/> .chatMessages<br/> {<br/> width: 100%;<br/> height: 200px;<br/> overflow: auto;<br/> margin-left: 0px;<br/> padding-left: 0px;<br/> }<br/> .chatMessages li<br/> {<br/> list-style-type: none;<br/> padding: 1px;<br/> }<br/> .chatNewMessage<br/> {<br/> border: 1px solid #ccc;<br/> width: 200px;<br/> float: left;<br/> height: 18px;<br/> }<br/> .chatMessage<br/> {<br/> }<br/> .chatSend<br/> {<br/> float: left;<br/> }<br/><br/>--></style><br/><pre><br/><br/></pre><br/><form id="form1"><br/><h3>SRChat - By Dhaval Upadhyaya - <a href="http://dhavalupadhyaya.wordpress.com/about-me/" target="_blank">http://dhavalupadhyaya.wordpress.com/about-me/</a></h3><br/><div><br/><div id="userNameLabel"></div><br/><div id="chatRooms"></div><br/><div id="chatOnlineContacts"></div><br/></div><br/></form><br/><pre><br/><br/>[/sourcecode]<br/><br/>Step 2) Add references to style and js files required to bootstrap this page.<br/><br/>[sourcecode language="html"]<br/> <link href="Styles/jquery-ui.css" rel="stylesheet" /><script type="text/javascript" src="Scripts/jquery-1.8.2.js"></script><script type="text/javascript" src="Scripts/jquery-ui.js"></script><br/><script type="text/javascript" src="Scripts/jquery.dialogextend.1_0_1.js"></script><script type="text/javascript" src="Scripts/jquery.signalR.js"></script><br/><script type="text/javascript" src="Scripts/jQuery.tmpl.js"></script><script type="text/javascript" src="signalr/hubs"></script><br/>[/sourcecode]<br/><br/>Step 3) Add templates that can be used to bind the json data and generate the html based UI quickly. Each template as the name justifies is used to generate the html UI when that particular type of triggers occur from the server.<br/><br/>[sourcecode language="html"]<br/><script id="new-online-contacts" type="text/x-jquery-tmpl">// <![CDATA[<br/><div><br/><ul><br/> {{each messageRecipients}}<br/><br/> <li id="chatLink${messageRecipientId}"><a href="javascript:;" onclick="javascript:SRChat.initiateChat('${messageRecipientId}','${messageRecipientName}');">${messageRecipientName}</a></li><br/><br/> {{/each}}</ul><br/><br/></div><br/><br/>// ]]></script><br/><script id="new-chatroom-template" type="text/x-jquery-tmpl">// <![CDATA[<br/><br/><div id="chatRoom${chatRoomId}" class="chatRoom"><br/><br/><ul id="messages${chatRoomId}" class="chatMessages"></ul><br/><br/><form id="sendmessage${chatRoomId}" action="#"><br/> <input type="text" id="newmessage${chatRoomId}" class="chatNewMessage"/><br/><br/><div class="clear"></div><br/><br/> <input type="button" id="chatsend${chatRoomId}" value="Send" class="chatSend" onClick="javascript:SRChat.sendChatMessage('${chatRoomId}')" /><br/> <input type="button" id="chatend${chatRoomId}" value="End Chat" class="chatSend" onClick="javascript:SRChat.endChat('${chatRoomId}')" /><br/> </form><br/><br/></div><br/><br/>// ]]></script><br/><script id="new-chat-header" type="text/x-jquery-tmpl">// <![CDATA[<br/><br/><div id="chatRoomHeader${chatRoomId}"><br/> {{each messageRecipients}}<br/> {{if $index == 0}}<br/> ${messageRecipientName}<br/> {{else}}<br/> , ${messageRecipientName}<br/> {{/if}}<br/> {{/each}}<br/><div><br/><br/>// ]]></script><br/><script id="new-message-template" type="text/x-jquery-tmpl">// <![CDATA[<br/><br/> <li class="message" id="m-${chatMessageId}"><br/> <strong>${displayPrefix}</strong><br/> {{html messageText}}</li><br/><br/>// ]]></script><br/><script id="new-notify-message-template" type="text/x-jquery-tmpl">// <![CDATA[<br/><br/> <li class="message" id="m-${chatMessageId}"><br/> <strong>{{html messageText}}</strong></li><br/><br/>// ]]></script><br/>[/sourcecode]<br/><br/>Step 5) Finally we will plug the magical code that would connect to our SRChatServer and registers all the client methods that would be invoked from server side in order to trigger and inject various messages and chat window instances.<br/><br/>[sourcecode language="html"]<br/><script type="text/javascript">// <![CDATA[<br/>$(document).ready(function () { SRChat.attachEvents(); }); SRChat = new function () { var chatRooms = 0; var numRand = Math.floor(Math.random() * 1000) var senderId = numRand; var senderName = 'User ' + numRand; var sRChatServer; window.onbeforeunload = function () { if (chatRooms > 0)<br/> return "All chat instances will be ended!";<br/> };<br/><br/> this.attachEvents = function () {<br/> $("#userNameLabel").html(senderName);<br/> if ($.connection != null) {<br/> jQuery.support.cors = true;<br/> $.connection.hub.url = 'signalr/hubs';<br/> sRChatServer = $.connection.sRChatServer;<br/><br/> $.connection.hub.start({ transport: 'auto' }, function () {<br/> sRChatServer.server.connect(senderId, senderName).fail(function (e) {<br/> alert(e);<br/> });<br/> });<br/><br/> sRChatServer.client.initiateChatUI = function (chatRoom) {<br/> var chatRoomDiv = $('#chatRoom' + chatRoom.chatRoomId);<br/> if (($(chatRoomDiv).length > 0)) {<br/> var chatRoomText = $('#newmessage' + chatRoom.chatRoomId);<br/> var chatRoomSend = $('#chatsend' + chatRoom.chatRoomId);<br/> var chatRoomEndChat = $('#chatend' + chatRoom.chatRoomId);<br/><br/> chatRoomText.show();<br/> chatRoomSend.show();<br/> chatRoomEndChat.show();<br/> }<br/> else {<br/> var e = $('#new-chatroom-template').tmpl(chatRoom);<br/> var c = $('#new-chat-header').tmpl(chatRoom);<br/><br/> chatRooms++;<br/><br/> //dialog options<br/> var dialogOptions = {<br/> "id": '#messages' + chatRoom.chatRoomId,<br/> "title": c,<br/> "width": 360,<br/> "height": 365,<br/> "modal": false,<br/> "resizable": false,<br/> "close": function () { javascript: SRChat.endChat('' + chatRoom.chatRoomId + ''); $(this).remove(); }<br/> };<br/><br/> // dialog-extend options<br/> var dialogExtendOptions = {<br/> "close": true,<br/> "maximize": false,<br/> "minimize": true,<br/> "dblclick": 'minimize',<br/> "titlebar": 'transparent'<br/> };<br/><br/> e.dialog(dialogOptions).dialogExtend(dialogExtendOptions);<br/><br/> $('#sendmessage' + chatRoom.chatRoomId).keypress(function (e) {<br/> if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {<br/> $('#chatsend' + chatRoom.chatRoomId).click();<br/> return false;<br/> }<br/> });<br/> }<br/> };<br/><br/> sRChatServer.client.updateChatUI = function (chatRoom) {<br/> var chatRoomHeader = $('#chatRoomHeader' + chatRoom.chatRoomId);<br/> var c = $('#new-chat-header').tmpl(chatRoom);<br/> chatRoomHeader.html(c);<br/> };<br/><br/> sRChatServer.client.receiveChatMessage = function (chatMessage, chatRoom) {<br/> sRChatServer.client.initiateChatUI(chatRoom);<br/> var chatRoom = $('#chatRoom' + chatMessage.conversationId);<br/> var chatRoomMessages = $('#messages' + chatMessage.conversationId);<br/> var e = $('#new-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);<br/> e[0].scrollIntoView();<br/> chatRoom.scrollIntoView();<br/> };<br/><br/> sRChatServer.client.receiveLeftChatMessage = function (chatMessage) {<br/> var chatRoom = $('#chatRoom' + chatMessage.conversationId);<br/> var chatRoomMessages = $('#messages' + chatMessage.conversationId);<br/> var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);<br/> e[0].scrollIntoView();<br/> chatRoom.scrollIntoView();<br/> };<br/><br/> sRChatServer.client.receiveEndChatMessage = function (chatMessage) {<br/> var chatRoom = $('#chatRoom' + chatMessage.conversationId);<br/> var chatRoomMessages = $('#messages' + chatMessage.conversationId);<br/> var chatRoomText = $('#newmessage' + chatMessage.conversationId);<br/> var chatRoomSend = $('#chatsend' + chatMessage.conversationId);<br/> var chatRoomEndChat = $('#chatend' + chatMessage.conversationId);<br/><br/> chatRooms--;<br/><br/> var e = $('#new-notify-message-template').tmpl(chatMessage).appendTo(chatRoomMessages);<br/><br/> chatRoomText.hide();<br/> chatRoomSend.hide();<br/> chatRoomEndChat.hide();<br/><br/> e[0].scrollIntoView();<br/> chatRoom.scrollIntoView();<br/> };<br/><br/> sRChatServer.client.onGetOnlineContacts = function (chatUsers) {<br/> var e = $('#new-online-contacts').tmpl(chatUsers);<br/> var chatLink = $('#chatLink' + senderId);<br/> e.find("#chatLink" + senderId).remove();<br/> $("#chatOnlineContacts").html("");<br/> $("#chatOnlineContacts").html(e);<br/> };<br/> }<br/> };<br/><br/> this.sendChatMessage = function (chatRoomId) {<br/> var chatRoomNewMessage = $('#newmessage' + chatRoomId);<br/><br/> if (chatRoomNewMessage.val() == null || chatRoomNewMessage.val() == "")<br/> return;<br/><br/> var chatMessage = {<br/> senderId: senderId,<br/> senderName: senderName,<br/> conversationId: chatRoomId,<br/> messageText: chatRoomNewMessage.val()<br/> };<br/><br/> chatRoomNewMessage.val('');<br/> chatRoomNewMessage.focus();<br/> sRChatServer.server.sendChatMessage(chatMessage).fail(function (e) {<br/> alert(e);<br/> });<br/><br/> return false;<br/> };<br/><br/> this.endChat = function (chatRoomId) {<br/> var chatRoomNewMessage = $('#newmessage' + chatRoomId);<br/><br/> var chatMessage = {<br/> senderId: senderId,<br/> senderName: senderName,<br/> conversationId: chatRoomId,<br/> messageText: chatRoomNewMessage.val()<br/> };<br/> chatRoomNewMessage.val('');<br/> chatRoomNewMessage.focus();<br/> sRChatServer.server.endChat(chatMessage).fail(function (e) {<br/> //alert(e);<br/> });<br/> };<br/><br/> this.initiateChat = function (toUserId, toUserName) {<br/> if (sRChatServer == null) {<br/> alert("Problem in connecting to Chat Server. Please Contact Administrator!");<br/> return;<br/> }<br/> sRChatServer.server.initiateChat(senderId, senderName, toUserId, toUserName).fail(function (e) {<br/> alert(e);<br/> });<br/> };<br/><br/> };<br/>// ]]></script><br/>[/sourcecode]<br/><br/>That It run the application and start chatting.<br/><br/>In next version I will add the feature of group chat. Though just few lines of code with the above version will do the job, I leave this to reader as a small exercise.<br/><br/>The full source code of Version 1.0 can be found on my GitHub repo at below link.<br/><br/><a title="SRChat - Dhaval Upadhyaya" href="https://github.com/upadhyayadhaval/SRChat">https://github.com/upadhyayadhaval/SRChat</a>Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com14tag:blogger.com,1999:blog-623348949309491130.post-4424462208269228802012-10-09T04:45:00.000-07:002017-06-01T01:55:05.514-07:00SignalR To Rescue<strong><span style="color:#ff6600;">SignalR To Rescue</span></strong><br/><br/>Asynchronous library for .NET to help build real-time, multi-user interactive web applications.<br/><p style="text-align:justify;">Many asp.net based real time applications uses some traditional techniques to trigger some business on client. Some old techniques include an recursive timely call like Ajax call to server to fetch data at intervals, a trigger from server using duplex channel when using WCF etc… These all traditional techniques has some or more disadvantages like a constant callbacks increasing server load, firewalls restricting duplex protocols hiding clients and resulting in broken links in duplex channels etc.</p><br/><p style="text-align:justify;">But now SignalR has emerged to rescue us from these types of architectural bottlenecks. One can easily build notification systems, chat applications, triggers across multiple applications and other myriads of real-time application using this simple yet powerful technology.</p><br/><p style="text-align:justify;">In this article I will jot down a very basic sample of broadcasting message to a group or to a specific client using SignalR and asp.net. For further technical documentation please refer <a href="https://github.com/SignalR/SignalR/wiki">https://github.com/SignalR/SignalR/wiki</a></p><br/><p style="text-align:justify;"><span style="text-decoration:underline;"><strong>Prerequisites</strong></span></p><br/><p style="text-align:justify;">In order to take advantage of SignalR a small integration of its infrastructure is required. To keep it simple I will use use Package Manager Console and Nuget package of SignalR later in the project.</p><br/><p style="text-align:justify;"><strong><span style="text-decoration:underline;">Application</span></strong></p><br/><p style="text-align:justify;">Two important parts needs to be coded for creating basic SignalR based applications.</p><br/><p style="text-align:justify;">- <span style="text-decoration:underline;">Server Hub</span>: A simple class containing methods that can be called from client hub. Also it is the main container of logic on server side. It can trigger methods on client hub with specific connection or with a group of connections.</p><br/><p style="text-align:justify;">- <span style="text-decoration:underline;">Client Hub</span>: A piece of code that is used for registering to server hub. It can contain methods that call server hub methods. It can also contain methods that are called from server hub. Client hubs can be coded in native ASP.Net or JavaScript.</p><br/><strong>Step 1)</strong> Create a new Asp.Net Web Application (“SignalRNotification”) in Visual Studio. Remove all the default folders and web forms created by template if any.<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_1.png"><img class="alignnone size-medium wp-image-238" title="New Project" src="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_1.png?w=300" alt="" width="300" height="228" /></a><br/><br/><strong>Step 2)</strong> Install SignalR infrastructure<br/>Go to Tools > Library Package Manager > Package Manager Console<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_2.png"><img class="alignnone size-medium wp-image-239" title="Package Manager Console" src="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_2.png?w=300" alt="" width="300" height="257" /></a><br/><br/>Run below command<br/>Install-Package SignalR<br/><br/><a href="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_3.png"><img class="alignnone size-medium wp-image-240" title="SignalR Installed" src="http://dhavalupadhyaya.files.wordpress.com/2012/10/signalrtorescue_3.png?w=300" alt="" width="300" height="228" /></a><br/><br/>The above steps will install SignalR infrastructure required to make use of this technology<br/><br/>For detail description and latest news for SignalR release please refer <a href="http://nuget.org/packages/signalr">http://nuget.org/packages/signalr</a><br/><br/><strong>Step 3)</strong> Create a new class named NotificationHub that inherits from Hub.<br/><br/>[sourcecode language="csharp"]<br/>using System;<br/>using SignalR.Hubs;<br/><br/>namespace SignalRNotification<br/>{<br/> [HubName("notificationHub")]<br/> public class NotificationHub:Hub<br/> {<br/> public void NotifyUsers(string message)<br/> {<br/> //Invokes onReceiveNotification function for all the Clients<br/> Clients.onReceiveNotification(string.Format("{0} {1}", message, DateTime.Now.ToString()));<br/> }<br/> }<br/>}<br/>[/sourcecode]<br/><br/>In the above code one can chose to send message to all clients, a group of clients or to a specific client. To keep things simple the above code simply broadcast the message to all clients.<br/><br/><strong>Step 4)</strong> Create a web form Admin.aspx. Add a textbox and a button to it as shown below. It includes reference to magical scripts that is actually responsible for connecting to SignalR hub and creating the proxy class. Internally this script registers the client using a unique GUID by making an ajax call. We will use this form for sending messages.<br/><br/>[sourcecode language="html"]<br/><br/><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Admin.aspx.cs" Inherits="SignalRNotification.Admin" %><br/><br/> Admin<br/><script type="text/javascript" src="Scripts/jquery-1.6.4.min.js"></script><script type="text/javascript" src="Scripts/jquery.signalR-0.5.3.min.js"></script><br/><script type="text/javascript" src="/signalr/hubs"></script><script type="text/javascript">// <![CDATA[<br/> $(function () {<br/> // the generated client-side hub proxy<br/> var server = $.connection.notificationHub;<br/> // Start the connection<br/> $.connection.hub.start();<br/> $('#xbtnNotify').click(function () {<br/> var message = document.getElementById('txtMessage').value;<br/> //call the method on server using the proxy<br/> server.notifyUsers(message);<br/> });<br/> });<br/><br/>// ]]></script><br/><br/><form id="form1"><br/><h1>Administrator</h1><br/><div>Message :<br/> <textarea id="txtMessage" style="width: 400px;" rows="3" cols="1"></textarea><br/> <input id="xbtnNotify" type="button" value="Send this to All Users" /></div><br/></form><br/><br/>[/sourcecode]<br/><br/><strong>Step 5)</strong> Create a web form User.aspx as shown below. We will use this form for receiving messages.<br/><br/>[sourcecode language="html"]<br/><br/><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="User.aspx.cs" Inherits="SignalRNotification.User" %><br/><br/> User<br/><br/><script type="text/javascript" src="Scripts/jquery-1.6.4.min.js"></script><script type="text/javascript" src="Scripts/jquery.signalR-0.5.3.min.js"></script><br/><script type="text/javascript" src="/signalr/hubs"></script><script type="text/javascript">// <![CDATA[<br/>// the generated client-side hub proxy<br/> $(function () {<br/> var server = $.connection.notificationHub;<br/> //This is the method that will be invoked from the server!!<br/> server.onReceiveNotification = function (message) {<br/> $("#messages").append('<br/> <li>' + message + '</li><br/><br/>');<br/> };<br/> // Start the connection<br/> $.connection.hub.start();<br/> });<br/>// ]]></script><pre><br/><form id="form1"><br/><div><br/><h1>User</h1><br/></div><br/><ul id="messages"></ul><br/></form><br/></pre><br/><br/>[/sourcecode]<br/><br/>That’s it.<br/><br/>A simple way to do complex things.<br/>In my next article I will explain how to create CHAT server using SignalR.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com1tag:blogger.com,1999:blog-623348949309491130.post-28710896117618957932012-01-12T19:24:00.000-08:002017-06-01T01:55:05.498-07:00Screen Readers with Silverlight Applications<strong><span style="color:#ff6600;">Screen Readers with Silverlight Applications.</span></strong><br/><p style="text-align:justify;"><strong></strong><br/>Web based applications fly across global boundaries due to which accessibility and ease of use becomes one of the most important factor that drives the sales count of the service we provide.</p><br/><p style="text-align:justify;">As per 508 Compliance if we require our service served to audience with disabilities it should follow various aspects.</p><br/><p style="text-align:justify;">For thorough details please refer</p><br/><p style="text-align:justify;"><a href="http://en.wikipedia.org/wiki/Section_508_Amendment_to_the_Rehabilitation_Act_of_1973">http://en.wikipedia.org/wiki/Section_508_Amendment_to_the_Rehabilitation_Act_of_1973</a></p><br/><p style="text-align:justify;">This article is specifically targeted for users interested to know</p><br/><p style="text-align:justify;">How do we provide support for Screen Readers software with the applications developed in one of the most cutting edge technology Silverlight?</p><br/><p style="text-align:justify;">Traditional web based applications that emits html to browsers easily comply with Screen readers based on specifications followed for HTML.<br/>With Silverlight based applications the Silverlight plug-in takes care for screen readers. We just need to follow some methodologies provided in form of Automation Properties in Silverlight. Automation Properties provide several methods and attachable properties which help us define access keys, instruction text for screen readers and much more.</p><br/><p style="text-align:justify;">For details please refer</p><br/><p style="text-align:justify;"><a href="http://msdn.microsoft.com/en-us/library/system.windows.automation.automationproperties(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.automation.automationproperties(v=vs.95).aspx</a></p><br/><p style="text-align:justify;">By following these properties the work is pretty much simple.</p><br/><span style="text-decoration:underline;"><strong>Sample 1</strong></span><br/><br/>[sourcecode language="html"]<br/><TextBox id=” nameTextBox” AutomationProperties.Name=”Please enter name” /><br/>[/sourcecode]<br/><br/>Screen reader will voice over “Please enter name” when this textbox receives focus.<br/><br/><span style="text-decoration:underline;"><strong>Sample 2</strong></span><br/><br/>[sourcecode language="html"]<br/><TextBlock id=”nameTextBlock” Text=”Please enter name” /><br/><TextBox id=”nameTextBox” AutomationProperties.LabeledBy="{Binding ElementName= nameTextBlock }" /><br/>[/sourcecode]<br/><p style="text-align:justify;">Screen reader will voice over “Please enter name” when this textbox receives focus. Here is the case when we want to directly bind the AutomationProperties.Name property of textbox to any control, in this case a label beside text box.</p><br/>Pretty much simply till here.<br/><p style="text-align:justify;"><strong>But wait!</strong></p><br/><p style="text-align:justify;">Silverlight SDK and Controls are very powerful and includes number of controls that can be bound directly to objects. Here is where most of the screen readers fail while generating voice over for such control. I will depict the problem with one of the control “Combo Box”</p><br/><p style="text-align:justify;"><span style="text-decoration:underline;"><strong>Problem</strong></span><br/>If your combo box is bound to any dictionary object including collection than screen readers will work perfectly. But if combo box is bound to any object like “Person” than screen readers will fail.</p><br/><span style="text-decoration:underline;"><strong>Sample Code</strong></span><br/><br/>[sourcecode language="html"]<br/><ComboBox Name="personsComboBox" ItemsSource="{Binding}" DisplayMemberPath="Name"/><br/>[/sourcecode]<br/><br/> <br/><br/>[sourcecode language="csharp"]<br/>public class Person : INotifyPropertyChanged<br/> {<br/> private string name;<br/> public string Name<br/> {<br/> get<br/> {<br/> return name;<br/> }<br/> set<br/> {<br/> if (value != name)<br/> {<br/> name = value;<br/> OnPropertyChnaged("Name");<br/> }<br/> }<br/> }<br/><br/> private string surname;<br/> public string Surname<br/> {<br/> get<br/> {<br/> return surname;<br/> }<br/> set<br/> {<br/> if (value != surname)<br/> {<br/> surname = value;<br/> OnPropertyChnaged("Surname");<br/> }<br/> }<br/> }<br/><br/> private Int32 age;<br/> public Int32 Age<br/> {<br/> get<br/> {<br/> return age;<br/> }<br/> set<br/> {<br/> if (value != age)<br/> {<br/> age = value;<br/> OnPropertyChnaged("Age");<br/> }<br/> }<br/> }<br/><br/> #region INotifyPropertyChanged Members<br/><br/> public event PropertyChangedEventHandler PropertyChanged;<br/><br/> private void OnPropertyChnaged(string propertyName)<br/> {<br/> if (PropertyChanged != null)<br/> {<br/> PropertyChanged(this, new PropertyChangedEventArgs(propertyName));<br/> }<br/> }<br/><br/> #endregion<br/><br/> }<br/>[/sourcecode]<br/><br/><span style="text-decoration:underline;"><strong>Solution</strong></span><br/><p style="text-align:justify;">Screen Readers works on strings attached to the controls using attachable property AutomationProperties.Name as described in above example code. With the case were we are binding objects directly to control, screen readers fail and voice over the entire path (Namespace.ObjecName) were the object reside. In order to overcome this issue simply override ToString() method for your objects.</p><br/><p style="text-align:justify;">Adding this code with the Person object designed above will ask screen readers to voice over “Name” property.</p><br/><br/>[sourcecode language="csharp"]<br/>public override string ToString()<br/> {<br/> return Name;<br/> }<br/>[/sourcecode]<br/><br/>Tricky but yet simple.<br/><br/>Enjoy Coding.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-75190274532874009962011-02-11T23:52:00.000-08:002017-06-01T01:55:05.529-07:00Automatic File Download<strong><span style="color:#ff6600;">Troubleshooting automatic file download issue in IE7.0 and later version</span></strong><br/><br/><strong>Problem</strong>: File download using .aspx page or HTTP handler does not work in IE 7.0 and later version.<br/><br/><strong>Solution</strong>: If you are storing your files in database and using .aspx page or HTTP handler to write the file to the response, than you must have been bugged by this issue. This is not an error or IE bug but it’s just that the newer version of IE wants to protect its users from malicious contents that could sniff or simply harm your computer or data.<br/>To make it more secure IE has provided option to its users to allow\disallow the automatic downloading of files. This can be set in any kind of security zones. To turn On\Off user needs to perform below steps<br/><br/>Step1) Open IE and click Tools > Internet Options<br/>Step2) Go to Security Tab. Select desired zone and then click Custom Level Button.<br/>Step3) Now look for Downloads > Automatic prompting for file downloads. By default this is disabled due to which any automatic file downloads will be blocked. Enable this feature as shown below.<br/><br/><strong>Note</strong>: If you do not want your users to make any changes for above mentioned settings than you can achieve the automatic download but as a tweak you need to have an interim page which requires some user action like button click to download a file.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-20759517579938065552011-02-11T23:48:00.000-08:002017-06-01T01:55:05.491-07:00Animating Grid Column<strong><span style="color:#ff6600;">Troubleshooting InvalidOperationException: DoubleAnimation cannot be used to animate property Width due to incompatible type.</span></strong><br/><br/>Silverlight has great support for Animation and you might have experienced animating most of the controls on one or the other aspect. But animating ColumnDefinition.Width or RowDefinition.Height properties for Grid control is not straight forward. To achieve this one has to make a tweak.<br/><br/><strong>Problem </strong>: InvalidOperationException: DoubleAnimation cannot be used to animate property Width due to incompatible type.<br/><br/><strong>Reason </strong>: Width property of grid is not of type double but is of type GridLength. Further GridLength has a property called Value of type Double, but Value is ReadOnly so to change the width or height you have to create a new instance of the GridLength object and set it to the Width Property of the grid.<br/><br/><strong>Solution</strong>: To achieve this we simply create a dependency property in our page and in the change event of that property we set the new instance of GridLength to width property of the grid.<br/><br/>[sourcecode language="html"]<br/><br/><Grid x:Name="myGrid"><br/> <Grid.Resources><br/> <Storyboard x:Name="myStoryboardC"><br/> <DoubleAnimation From="150" To="0" Duration="00:00:1"<br/> Storyboard.TargetName="myPageName"<br/> Storyboard.TargetProperty="ColumnWidth"><br/> <DoubleAnimation.EasingFunction><br/> <CubicEase EasingMode="EaseOut"/><br/> </DoubleAnimation.EasingFunction><br/> </DoubleAnimation><br/> </Storyboard><br/> <Storyboard x:Name="myStoryboardE"><br/> <DoubleAnimation From="0" To="150" Duration="00:00:1"<br/> Storyboard.TargetName= “myPageName"<br/> Storyboard.TargetProperty="ColumnWidth"><br/> <DoubleAnimation.EasingFunction><br/> <CubicEase EasingMode="EaseOut"/><br/> </DoubleAnimation.EasingFunction><br/> </DoubleAnimation><br/> </Storyboard><br/> </Grid.Resources><br/> <Grid.ColumnDefinitions><br/> <ColumnDefinition x:Name="Column1" Width="150" MaxWidth="250" MinWidth="0"><br/> </ColumnDefinition><br/> <ColumnDefinition Width="15" MaxWidth="15" MinWidth="15"/><br/> <ColumnDefinition Width="*"/><br/> </Grid.ColumnDefinitions><br/> <Grid.RowDefinitions><br/> <RowDefinition Height="*"/><br/> </Grid.RowDefinitions><br/><br/> <Rectangle x:Name="myRectangle"<br/> Fill="Blue" Width="200" Height="30" Grid.Column="0"/><br/><br/> <layoutToolkit:Accordion x:Name="acc" SelectionMode="ZeroOrMore" Grid.Column="0"><br/> <layoutToolkit:AccordionItem Header="hi"><br/> <StackPanel><br/> <TextBlock Text="1"/><br/> <TextBlock Text="2"/><br/> <TextBlock Text="3"/><br/> </StackPanel><br/> </layoutToolkit:AccordionItem><br/> <layoutToolkit:AccordionItem Header="hi" Content="Task 2"/><br/> <layoutToolkit:AccordionItem Header="hi" Content="Task 3"/><br/> </layoutToolkit:Accordion><br/><br/> <Button x:Name="btnEC" Content="&lt;" Grid.Column="1" Click="Button_Click" /><br/><br/> <data:DataGrid x:Name="dataGrid1" Margin="0" Grid.Column="2"><br/> <data:DataGrid.RowDetailsTemplate><br/> <DataTemplate><br/> <StackPanel Background="LightBlue"><br/> <StackPanel Orientation="Horizontal"><br/> <TextBlock Text="This item has details." /><br/> </StackPanel><br/> <StackPanel Orientation="Horizontal"><br/> <TextBlock Text="Here is some data: " /><br/> <TextBlock Text="{Binding FirstName}" /><br/> <TextBlock Text=" LastName" /><br/> <TextBlock Text="{Binding LastName}" /><br/> </StackPanel><br/> </StackPanel><br/> </DataTemplate><br/> </data:DataGrid.RowDetailsTemplate><br/> </data:DataGrid><br/><br/> </Grid><br/><br/>[/sourcecode]<br/><br/>[sourcecode language="csharp"]<br/><br/>public partial class MainPage : UserControl<br/> {<br/><br/> bool toogle;<br/> public MainPage()<br/> {<br/> InitializeComponent();<br/> this.Name = "myPageName";<br/> }<br/><br/> public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth",<br/> typeof(double),<br/> typeof(MainPage),<br/> new PropertyMetadata<br/> (ColumnWidthChanged));<br/> public double ColumnWidth<br/> {<br/> get<br/> {<br/> return (double)GetValue(ColumnWidthProperty);<br/> }<br/> set<br/> {<br/> SetValue(ColumnWidthProperty, value);<br/> }<br/> }<br/><br/> private static void ColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<br/> {<br/> var mainPage = (MainPage)d;<br/> mainPage.Column1.Width = new GridLength((double)e.NewValue);<br/> }<br/><br/> private void Button_Click(object sender, RoutedEventArgs e)<br/> {<br/> if (!toogle)<br/> {<br/> myStoryboardC.Begin();<br/> btnEC.Content = ">";<br/> toogle = !toogle;<br/> }<br/> else<br/> {<br/> myStoryboardE.Begin();<br/> btnEC.Content = "<";<br/> toogle = !toogle;<br/> }<br/> }<br/> }<br/><br/>[/sourcecode]Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com5tag:blogger.com,1999:blog-623348949309491130.post-47718508920734317842010-09-04T01:10:00.000-07:002017-06-01T01:55:05.517-07:00Show loading while downloading XAP modules in prism.<strong><span style="color:#ff9900;">Show loading while downloading XAP modules in prism.</span></strong><br/><br/><strong>Scenario :</strong> To show progress bar when modules (xap’s) in prism are downloaded.<br/><br/><strong>Problem : </strong>Currently in prism the default ModuleManager class does not expose a progress event that can be tracked to show some progressing of the modules (xap’s) being downloaded.<br/><br/><strong>Solution : </strong>Prism’s ModuleManager internally uses instance of XapModuleTypeLoader to load modules (xap’s) asynchronously. Thanks to the community of prism for providing CreateDownloader() as virtual method.<br/><br/>Straight to the point I will jot down the steps to achieve the above mentioned goal.<br/><br/><strong>Step 1</strong> - Create an event and an event argument classes that will be used in custom class below<br/><br/>[sourcecode language="csharp"]<br/><br/>public class ModuleDownloadProgressEvent : CompositePresentationEvent<ModuleDownloadProgressArgs><br/>{<br/>}<br/><br/>public class ModuleDownloadProgressArgs<br/>{<br/> public ModuleDownloadProgressArgs(int BytesReceived, bool IsComplete) { _BytesReceived = BytesReceived; _IsComplete = IsComplete; }<br/> private int _BytesReceived;<br/> public int BytesReceived { get { return _BytesReceived; } set { _BytesReceived = value; } }<br/> private bool _IsComplete;<br/> public bool IsComplete { get { return _IsComplete; } set { _IsComplete = value; } }<br/>}<br/><br/>[/sourcecode]<br/><br/><strong>Step 2</strong> - Create a class that derives from IFileDownloader.<br/><br/>[sourcecode language="csharp"]<br/><br/>public class CustomFileDownloader : IFileDownloader<br/>{<br/> private readonly WebClient webClient = new WebClient();<br/> private readonly IEventAggregator eventAgg;<br/><br/> public CustomFileDownloader()<br/> {<br/> eventAgg = ServiceLocator.Current.GetInstance<IEventAggregator>();<br/> }<br/><br/> private event EventHandler<DownloadCompletedEventArgs> _downloadCompleted;<br/> public event EventHandler<DownloadCompletedEventArgs> DownloadCompleted<br/> {<br/> add<br/> {<br/> if (this._downloadCompleted == null)<br/> {<br/> this.webClient.OpenReadCompleted += this.WebClient_OpenReadCompleted;<br/> this.webClient.DownloadProgressChanged += this.DownloadProgressChanged;<br/> }<br/><br/> this._downloadCompleted += value;<br/> }<br/><br/> remove<br/> {<br/> this._downloadCompleted -= value;<br/> if (this._downloadCompleted == null)<br/> {<br/> this.webClient.OpenReadCompleted -= this.WebClient_OpenReadCompleted;<br/> this.webClient.DownloadProgressChanged -= this.DownloadProgressChanged;<br/> }<br/> }<br/> }<br/><br/> void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)<br/> {<br/> RaiseDownloadProgressChanged(e.ProgressPercentage, false);<br/> }<br/><br/> private void RaiseDownloadProgressChanged(int val, bool isComplete)<br/> {<br/> eventAgg.GetEvent<ModuleDownloadProgressEvent>().Publish(new ModuleDownloadProgressArgs(val, isComplete));<br/> }<br/><br/> public void DownloadAsync(Uri uri, object userToken)<br/> {<br/> this.webClient.OpenReadAsync(uri, userToken);<br/> }<br/><br/> private void WebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)<br/> {<br/> this._downloadCompleted(this, ConvertArgs(e));<br/> RaiseDownloadProgressChanged(0, true);<br/> }<br/><br/> private static DownloadCompletedEventArgs ConvertArgs(OpenReadCompletedEventArgs args)<br/> {<br/> return new DownloadCompletedEventArgs(args.Error == null ? args.Result : null, args.Error, args.Cancelled, args.UserState);<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/><strong>Step 3 </strong>- Create a class that derives from XapModuleTypeLoader and override its virtual method CreateDownloader returning your class object prepared in step 1<br/><br/>[sourcecode language="csharp"]<br/><br/>public class CustomXapModuleTypeLoader : XapModuleTypeLoader<br/>{<br/> protected override IFileDownloader CreateDownloader()<br/> {<br/> return new CustomFileDownloader();<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/><strong>Step 4</strong> - Create a class that derives from ModuleManager and override its virtual method ModuleTypeLoaders replacing default XapModuleTypeLoader with your class object prepared in step 2.<br/><br/>[sourcecode language="csharp"]<br/><br/>public class CustomModuleManager : ModuleManager<br/>{<br/> public CustomModuleManager(IModuleInitializer moduleInitializer, IModuleCatalog moduleCatalog, ILoggerFacade loggerFacade)<br/> : base(moduleInitializer, moduleCatalog, loggerFacade) { }<br/> private System.Collections.Generic.IEnumerable<IModuleTypeLoader> typeLoaders;<br/> public override System.Collections.Generic.IEnumerable<IModuleTypeLoader> ModuleTypeLoaders<br/> {<br/> get<br/> {<br/> if (this.typeLoaders == null)<br/> {<br/> this.typeLoaders = new List<IModuleTypeLoader>()<br/> {<br/> new CustomXapModuleTypeLoader()<br/> };<br/> }<br/><br/> return this.typeLoaders;<br/> }<br/> set<br/> {<br/> this.typeLoaders = value;<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/><strong>Step 5</strong> - Register your custom ModuleManager class prepared in step 4, in overridden method ConfigureContainer() of your Bootstrapper class.<br/><br/>[sourcecode language="csharp"]<br/><br/> base.RegisterTypeIfMissing(typeof(IModuleManager), typeof(CustomModuleManager), true);<br/><br/>[/sourcecode]<br/><br/><strong>Step 6</strong> – Create a method in Shell that will respond to the ModuleDownloadProgressEvent event when published<br/><br/>[sourcecode language="csharp"]<br/><br/>public void ShowHide(ModuleDownloadProgressArgs e)<br/>{<br/> // Your Dream Goes Here<br/>}<br/><br/>[/sourcecode]<br/><br/><strong>Step 7</strong> – Finally in the Shell subscribe to the ModuleDownloadProgressEvent event prepared in Step 1.<br/><br/>[sourcecode language="csharp"]<br/><br/> eventAggregator.GetEvent<ModuleDownloadProgressEvent>().Subscribe(ShowHide, ThreadOption.UIThread);<br/><br/>[/sourcecode]<br/><br/>That’s it!!!<br/><br/>Enjoy Prism.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com2tag:blogger.com,1999:blog-623348949309491130.post-38582098730017002902010-08-06T22:51:00.000-07:002017-06-01T01:55:05.508-07:00Packing and Deploying Custom Templates in Visual Studio.<span style="color:#ff6600;"><strong>Packing and Deploying Custom Templates in Visual Studio.</strong></span><br/><br/>Once you have created your own template<span style="color:#ff6600;"> (<a href="http://dhavalupadhyaya.wordpress.com/2010/08/07/creating-project-templates-for-visual-studio/" target="_blank">Creating project templates for Visual Studio</a>) </span>its time for its distribution.<br/>To make the template appear into the “New Project” window it is important to place the zip file of the template to correct location. This can be done manually and through .vsi (Visual Studio Installer) file. Also .vsi file will be helpful for distribution of your template to different community or users.<br/><br/>To create the .vsi file for your template follow the below steps<br/>1)Create a file in the project folder with .vscontent extension having the below code<br/><br/>[sourcecode language="html"]<br/><br/><VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005"><br/> <Content><br/> <FileName>MyFirstWebProjectTemplate.zip</FileName><br/> <DisplayName>My First Web Project Template</DisplayName><br/> <Description>A project template created for this example.</Description><br/> <FileContentType>VSTemplate</FileContentType><br/> <ContentVersion>1.0</ContentVersion><br/> <Attributes><br/> <Attribute name="ProjectType" value="Visual C#"/><br/> <Attribute name="ProjectSubType" value="CSharp"/><br/> <Attribute name="TemplateType" value="Project"/><br/> </Attributes><br/> </Content><br/></VSContent><br/><br/>[/sourcecode]<br/><br/><span style="text-decoration:underline;">File Name:</span> Name of the file that needs to be deployed. Here it is our custom template zip file.<br/><br/><span style="text-decoration:underline;">DisplayName:</span> Name that appears in the deployment wizard<br/><br/><span style="text-decoration:underline;">Description:</span> Small description regarding the component that is being deployed. It appears as tooltip for the Display Name<br/><br/><span style="text-decoration:underline;">FileContentType:</span> Type of the file being deployed. It can be Toolbox Control, Code Snippet, VSTemplate etc.<br/><br/><span style="text-decoration:underline;">ContentVersion:</span> Version of the content being deployed. Let be 1.0<br/><br/><span style="text-decoration:underline;">ProjectType:</span> Type of the project. It can be Visual Basic, Visaul C#, Visual J# etc<br/><br/><span style="text-decoration:underline;">ProjectSubType:</span> Type of subcategory to which the template would be placed. It can be CSharp, JSharp, Visual Basic etc<br/><br/><span style="text-decoration:underline;">TemplateType:</span> Type of the template that is being deployed. It can be Project, Item.<br/><br/>2)Select all the files to be included in your template (including the .vscontent file) and compress it to prepare a standard zip file. In above case it will produce MyFirstWebProjectTemplate.zip.<br/><br/>3)Rename the extension of the .zip file to .vsi.<br/><br/><strong>Alternate Approach</strong><br/><br/>1)Select all the files to be included in your template (including the .vstemplate file) and compress it to prepare a standard zip file.<br/><br/>2)Create a file in the project folder with .vscontent extension as shown in the above scenario<br/><br/>3)Select the zip file created in step 1 and .vscontent file created in step 2. Right click and click “Add to archive”. In the Archive name give MyTemplate.vsi and zip it. It will create a new MyTemplate.vsi file.<br/><br/>That’s it distribute the .vsi file.<br/><br/><strong>Note:</strong> In order to avoid the “No Signature Found” warning and to display the publisher information into the .vsi package you must sign your .vsi file<br/><br/>[sourcecode language="html"]<br/><br/><VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project"><br/> <TemplateData><br/> <Name>ASP.NET AJAX Control Project</Name><br/> <Description>Create new ASP.NET AJAX Control Extenders and Behaviors</Description><br/> <ProjectType>CSharp</ProjectType><br/> <SortOrder>1000</SortOrder><br/> <CreateNewFolder>true</CreateNewFolder><br/> <DefaultName>AjaxControlExtender</DefaultName><br/> <ProvideDefaultName>true</ProvideDefaultName><br/> <LocationField>Enabled</LocationField><br/> <EnableLocationBrowseButton>true</EnableLocationBrowseButton><br/> <Icon>__TemplateIcon.ico</Icon><br/> </TemplateData><br/> <TemplateContent><br/> <CustomParameters><br/> <CustomParameter Name="$baseitemname$" Value="$safeprojectname$"/><br/> <CustomParameter Name="$rootnamespace$" Value="$safeprojectname$"/><br/> </CustomParameters><br/> <Project TargetFileName="AjaxControlExtender.csproj" File="AjaxControlExtender.csproj" ReplaceParameters="true"><br/> <ProjectItem TargetFileName="$safeprojectname$Behavior.js" ReplaceParameters="true">Behavior.js</ProjectItem><br/> <ProjectItem TargetFileName="$safeprojectname$Extender.cs" ReplaceParameters="true">Extender.cs</ProjectItem><br/> <ProjectItem TargetFileName="$safeprojectname$Designer.cs" ReplaceParameters="true">Designer.cs</ProjectItem><br/> <Folder Name="bin" TargetFolderName="bin"><br/> <ProjectItem>AjaxControlToolkit.dll</ProjectItem><br/> </Folder><br/> </Project><br/> </TemplateContent><br/></VSTemplate><br/><br/><VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"><br/> <TemplateData><br/> <Name>MyFirstWebProjectTemplate</Name><br/> <Description>A simple Web template</Description><br/> <Icon>icon.ico</Icon><br/> <ProjectType>Web</ProjectType><br/> <ProjectSubType>CSharp</ProjectSubType><br/> <DefaultName>WebSite</DefaultName><br/> </TemplateData><br/> <TemplateContent><br/> <Project File="MyFirstWebProjectTemplate.webproj" TargetFileName="MyFirstWebProjectTemplate.webproj"><br/> <ProjectItem>web.config</ProjectItem><br/> <ProjectItem OpenInEditor="true">Default.aspx</ProjectItem><br/> <ProjectItem>Default.aspx.cs</ProjectItem><br/> <Folder Name="App_Code" TargetFolderName="App_Code"><br/> <Folder Name="BAL" TargetFolderName="BAL"><br/> </Folder><br/> <Folder Name="DAL" TargetFolderName="DAL"><br/> <ProjectItem>DataAccess.cs</ProjectItem><br/> </Folder><br/> </Folder><br/> <Folder Name="App_Data" TargetFolderName="App_Data"><br/> </Folder><br/> </Project><br/> </TemplateContent><br/></VSTemplate><br/><br/>[/sourcecode]Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com2tag:blogger.com,1999:blog-623348949309491130.post-8118718521985628722010-08-06T22:43:00.000-07:002017-06-01T01:55:05.532-07:00Creating project templates for Visual Studio<span style="color:#ff6600;"><strong>Creating project templates for Visual Studio</strong></span><br/><br/>Reusability though heard thousands of times, ranges from a small code snippet to the entire enterprise level framework. This article will demonstrate the word reusable in terms of – Reusing the company framework or code through a fantastic feature of Visual Studio called Templates.<br/><br/><span style="text-decoration:underline;"><span style="color:#000000;"><strong>Templates</strong></span></span><br/><br/>A group of packaged files that help to accelerate the development process by eliminating the need to start the project from scratch. Templates are divided into two parts<br/><br/><strong>Project Templates :</strong> This category appears into “New Project” dialog box when one is starting a fresh new project. It is further divided into Project Templates and Website Templates.<br/><br/><strong>Item Templates :</strong> This category appears into “Add Item” dialog box when one wants to add a new item to the project.<br/><br/>Ways to create template: There are two ways in which one can create the desired template manually or by using the export template wizard of Visual Studio.<br/><br/>I will stick to the process of manually creating a Website Template.<br/>Steps to create a new website template.<br/>1)Create a new Web site.<br/><br/>2)Prepare the framework (files to be included in your website template)<br/><br/>3)Create a file with .vstemplate as extension in the same directory of your project.<br/><br/>4)Alter the .vstemplate file to provide template metadata as given below.<br/><br/>[sourcecode language="html"]<br/><br/><VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"><br/> <TemplateData><br/> <Name>MyFirstWebProjectTemplate</Name><br/> <Description>A simple Web template</Description><br/> <Icon>icon.ico</Icon><br/> <ProjectType>Web</ProjectType><br/> <ProjectSubType>CSharp</ProjectSubType><br/> <DefaultName>WebSite</DefaultName><br/> </TemplateData><br/> <TemplateContent><br/> <Project File="MyFirstWebProjectTemplate.webproj" TargetFileName="MyFirstWebProjectTemplate.webproj"><br/> <ProjectItem>web.config</ProjectItem><br/> <ProjectItem OpenInEditor="true">Default.aspx</ProjectItem><br/> <ProjectItem>Default.aspx.cs</ProjectItem><br/> <Folder Name="App_Code" TargetFolderName="App_Code"><br/> <Folder Name="BAL" TargetFolderName="BAL"><br/> </Folder><br/> <Folder Name="DAL" TargetFolderName="DAL"><br/> <ProjectItem>DataAccess.cs</ProjectItem><br/> </Folder><br/> </Folder><br/> <Folder Name="App_Data" TargetFolderName="App_Data"><br/> </Folder><br/> </Project><br/> </TemplateContent><br/></VSTemplate><br/><br/>[/sourcecode]<br/><br/>The above vstemplate XML file includes three major sections<br/><br/><strong><span style="text-decoration:underline;">VSTemplate:</span></strong> Identifies the template as a project or item template and provides the template version number<br/><br/><strong><span style="text-decoration:underline;">Template Data:</span></strong> Includes all the metadata that defines the display characteristics related to the Add New Website Screen.<br/><br/><span style="text-decoration:underline;">Name: </span> Name of the template that appear under the My Template section<br/><br/><span style="text-decoration:underline;">Description:</span> Small description that is depicted in the status bar of the New website screen.<br/><br/><span style="text-decoration:underline;">Icon:</span><strong> </strong>Name of the Icon file that is shown as the preview icon for the newly created template.<br/><br/><span style="text-decoration:underline;">Project Type: </span>Type of the project template. This is one of the main attributes as it decides under which section the template will appear. Specifically mention “Web” for creating web site project template.<br/><br/><span style="text-decoration:underline;">Project Sub Type:</span> Type of the language for the template. It can be CSharp, VisualBasic, JSharp etc.<br/><br/><span style="text-decoration:underline;">DefaultName:</span> The default name of the website<br/><br/><strong><span style="text-decoration:underline;">Template Content:</span></strong> Includes the definition for all the files and folder structure that would be created when the template is imported.<br/><br/><span style="text-decoration:underline;">Project File:</span> This is the name of the project file that is used internally by visual studio to refer files while extracting the template. So incase of project template it will be the name of the projet file Eg “MyFirstWebProjectTemplate.csproj”<br/>As website donot produce project files just create a file with .webproj extension Eg MyFirstWebProjectTemplate.webproj<br/><br/><span style="text-decoration:underline;">ProjectItem:</span> This attributes includes all the files that need to be extracted.<br/><br/><span style="text-decoration:underline;">Folder:</span> Used to organize files into specific folder structure just incase. In the above example template will create App_Code foler, BAL and DAL folder under App_Code folder and place DataAccess.cs file into DAL folder.<br/><br/>5)Now navigate to the project folder. Select all the files to be included in your template (including the .vstemplate file) and compress it to prepare a standard zip file. In above case it will produce MyFirstWebProjectTemplate.zip.<br/><br/>6)Now simply move the zip file to My Documents\Visual Studio 2005\Templates\ProjectTemplates folder.<br/><br/>7)To validate Open Visual Studio and goto File >> New >> Website. The newly created template will appear into My Templates section of the “New Website Screen”. That’s it you have created your own first template.<br/><br/><strong>Conclusion</strong><br/>To save time with scratch projects prepare template with a framework including UI aspects like Basic Layout(Login.aspx,DefaultMaster.aspx, etc), Architectural aspects like Authentication,Authorization,Security,Utility classes etc<br/>and save your time and money.<br/><br/>Templates can be used locally as well as can be distributed to others users. To prepare a .vsi deployment package for your template refer<br/><br/><span style="color:#ff6600;"><a href="http://dhavalupadhyaya.wordpress.com/2010/08/07/packing-and-deploying-custom-templates-in-visual-studio/" target="_blank"> Packing and Deploying Custom Templates in Visual Studio.</a></span><br/><br/><strong>Note:</strong> Though the template creation seems to be easy but in reality its not. Above was the simplest type of the template that we have created. Visual Studio has great amount of flexibility to produce different types of templates like, project templates, website templates (the one above), item templates and wizard base templates.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com2tag:blogger.com,1999:blog-623348949309491130.post-68867873114636371312010-04-10T04:58:00.000-07:002017-06-01T01:55:05.526-07:00Document generation in C#<span style="color:#ff6600;"><strong>Document generation in C#</strong></span><br/><br/><strong>Why document?</strong><br/>One of the most famous nightmares among the developers is generating the detailed documentation of the code they have already done. But this notion should be changed as one should always detail each and every aspect of the code they have produced. Proper documentation not only helps others to understand the code but also brings down the maintenance cost of the project if properly utilized.<br/><br/><strong>When to document?</strong><br/>I usually prefer to document things but it depends on the following factors Size of Project, Complexity of Code, Client Need etc. One should not consider the Cost of the project as a factor affecting the decision you know why?<br/><br/><strong>What to document?<br/></strong>No matter whatever the piece of code is you can comment it and latter when needed can produce the required document for that particular section. Namespace, Class, Structure, Interface, Enum, Property, Method, Event and all other stuff can be documented. Always follow the practice of commenting your code as and when you finalize with that particular section.<br/><br/><strong> </strong><strong><span style="text-decoration:underline;">Solution</span></strong><br/><br/>C# has an inbuilt feature than one can take the advantage to generate the document automatically. You just need to be aware of the attributes used for placing and formatting the comments. Some of them are mentioned below<br/><br/>[sourcecode language="csharp"]<br/><c> Use to depict a code into a single line.<br/>E.g.: <c> int i = 0 ; </c><br/><br/><code> Use to depict a code snippet into a multiple lines<br/>E.g.: <code><br/>for (int i = 0; i < 10; i++)<br/> {<br/> //Code<br/> }<br/></code><br/><example><br/>Use to depict a code example of how to utilize particular type or member.<br/><example> This sample shows how to call the GetEmployee method.<br/> <code><br/> class Employee<br/> {<br/> public static int Main()<br/> {<br/> return GetEmployee();<br/> }<br/> }<br/> </code><br/> </example><br/><br/><list><br/>Use to depict a bulleted, numbered, tabled list.<br/><br/><param><br/>Use to depict the parameters of the method, events etc<br/>E.g.: <param name='name'>description</param><br/><br/><paramref><br/>Use to depict the name of the parameter.<br/>E.g.: <paramref name=’name’/><br/><br/><remarks><br/>Use to depict additional information about the type or member.<br/>E.g: <remarks>Additional information goes here</remarks><br/><br/><returns><br/>Use to depict the return value of a method.<br/>E.g: <returns>Returns List<Employee></returns><br/><br/><see><br/>Use to depict links to similar topics from within the text or highlights the text in the page.<br/>E.g: <see href="www.google.com">Google</see><br/><see langword="true | false"/><br/><br/><seealso><br/>Use to depict links to similar topics at the very end of the documented page similar to 'See also' section of the MSDN help.<br/>E.g: <seealso href=" www.google.com">Google</seealso><br/><br/><summary><br/>Use to depict a small description of the type or the member.<br/>E.g: <summary>description</summary><br/><br/><value><br/>Use to describe the value of the property.<br/>E.g: <value> description</value><br/>[/sourcecode]<br/><br/>Taking into consideration that you have beautifully commented each and every piece of your code you can generate the document with just few clicks.<br/><br/><span style="text-decoration:underline;"><strong>Practice Lesson</strong></span><br/><br/>Step 1) Create a class library project named Document<br/>Step 2) Add a class named Employee to the project.<br/>Step 3) Copy past the code below<br/><br/>[sourcecode language="csharp"]<br/><br/>using System;<br/>using System.Collections.Generic;<br/>using System.Web;<br/><br/>namespace Document<br/>{<br/><br/> /// <summary><br/> /// Summary description for Employee<br/> /// </summary><br/> public class Employee<br/> {<br/> /// <summary><br/> /// Employee Class default constructor<br/> /// </summary><br/> public Employee()<br/> {<br/><br/> }<br/><br/> /// <summary><br/> /// Employee Class constructor<br/> /// <c>Employee objEmployee = new Employee('dhaval',25)</c><br/> /// </summary><br/> /// <param name="name">Name of the employee</param><br/> /// <param name="age">Age of the employee</param><br/> public Employee(string name, int age)<br/> {<br/><br/> }<br/><br/> }<br/><br/>}<br/><br/>[/sourcecode]<br/><br/>Step 4) Go to project properties >> build section and check XML Document file section under output group as shown below<br/>Step 5) Build the project and go to bin\debug folder. Document.Xml file would have been generated containing all the details required to generate the document<br/>Step 6) Open NDOC and click on add button<br/>Step 7) Provide path of Document.dll in the assembly file name and Document.XML path in XML Doc Filename and click Ok<br/>Step 8 Finally click Build from the ndoc toolbar or select build from documentation menu<br/><br/>To view the output document click View icon from ndoc toolbar or select view from documentation menu.<br/><br/>That’s It. You’re done<br/><br/><strong><span style="text-decoration:underline;">Note:</span> </strong>Above are the very few sample tags related to the visual aspect of the document generation there are number of tags that can handle various other aspect of the document generation like permission, threading, include, exclude etc.<br/><br/>As the internal architecture of the NDOC is based on XML and XSLT one can also generate the Custom Tags of their own.<br/><br/>To play around more you can take the reference of the below official site of NDOC<br/><br/><a href="http://ndoc.sourceforge.net/usersguide.html">http://ndoc.sourceforge.net/usersguide.html</a>Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-83937461619800200272010-03-04T05:17:00.000-08:002017-06-01T01:55:05.535-07:00How to load latest image uploaded with the file upload control without
hitting refresh button?<span style="color:#ff6600;"><strong>How to load latest image uploaded with the file upload control without hitting refresh button?</strong></span><br/><br/><span style="text-decoration:underline;">Problem Scenario:</span><br/><br/>When we use fixed image url and upload an image file with the same name than the image displayed in the browser remains the same as the old one till we go and refresh the page.<br/><br/>The below depicted code will perform according to the above explained scenario.<br/><br/>[sourcecode language="html"]<br/><%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="FileUpload_Default" %><br/><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br/><html xmlns="http://www.w3.org/1999/xhtml"><br/><head runat="server"><br/> <title>Image Test</title><br/></head><br/><body><br/> <form id="form1" runat="server"><br/> <div><br/> <asp:FileUpload ID="FileUpload1" runat="server" /><br/> <asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" /><br/> <br /><br/> <asp:Image ID="Image1" ImageUrl="~/FileUpload/file1.jpg" runat="server" /><br/> </div><br/> </form><br/></body><br/></html><br/>[/sourcecode]<br/>[sourcecode language="csharp"]<br/>using System;<br/>using System.Configuration;<br/>using System.Collections;<br/>using System.Web;<br/>using System.Web.Security;<br/>using System.Web.UI;<br/>using System.Web.UI.WebControls;<br/>using System.Web.UI.HtmlControls;<br/><br/>public partial class FileUpload_Default : System.Web.UI.Page<br/>{<br/> protected void Page_Load(object sender, EventArgs e)<br/> {<br/><br/> }<br/><br/> protected void btnUpload_Click(object sender, EventArgs e)<br/> {<br/> string filePath = string.Concat(Server.MapPath("file1.jpg"));<br/><br/> if (FileUpload1.HasFile)<br/> {<br/> FileUpload1.SaveAs(filePath);<br/> }<br/> }<br/>}<br/>[/sourcecode]<br/><br/><span style="text-decoration:underline;">Solution:</span><br/><br/>Now to approach this kind of situation their are basically two thing that can be done.<br/><br/>1) Rather than just fixing the image url path of image in .aspx page make the path associated to it in the code behind page as well. Like shown in the below sample code.<br/><br/>[sourcecode language="csharp"]<br/><br/>protected void btnUpload_Click(object sender, EventArgs e)<br/> {<br/> string filePath = string.Concat(Server.MapPath("file1.jpg"));<br/><br/> if (FileUpload1.HasFile)<br/> {<br/> FileUpload1.SaveAs(filePath);<br/> }<br/><br/> Image1.ImageUrl = filePath;<br/> }<br/><br/>[/sourcecode]<br/><br/>OR<br/><br/>2) If you are changing the image url from javascript than just append time or any random number as a part of query string to the image url. Appending the time after the image path will make it treat as a separate request in IIS and the image will be perfectly loaded.<br/><br/>[sourcecode language="html"]<br/><br/><a href="http://localhost/MyArticles/FileUpload/file1.jpg?t=11/7/2009%204:25:23%20PM">http://localhost/MyArticles/FileUpload/file1.jpg?t=11/7/2009%204:25:23%20PM</a><br/><br/>[/sourcecode]<br/><br/>or<br/><br/>[sourcecode language="html"]<br/><br/>http://localhost/MyArticles/FileUpload/file1.jpg?t=63245<br/><br/>[/sourcecode]Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-52140003317536891162009-01-23T09:03:00.000-08:002017-06-01T01:55:05.520-07:00URL Remapping in .Net 2.0<strong><span style="color:#ff6600;">In this article I will walk through a concept for URL Remapping in .Net 2.0</span></strong><br/><br/>The need for url remapping can arise due to several reasons like<br/>Generating SEO friendly urls<br/>Hiding the actual page or other data from web users.<br/>Control over each and every entry and exits for web requests.<br/>Etc.<br/>.Net 2.0 gives flexibility to define and remap urls in web.config file as well as generating your own Custom URL Remapper HTTP Module.<br/>I will explain the first approach i.e remap urls in web.config in this post and will try to wrap up the second one in my next article with a pretty decent code sample for building Custom URL Remapper HTTP Module.<br/><strong>Remapping URL's in web.config file.</strong><br/>To Map urls .Net provides a section named urlMappings in web.config file where one can define the collection for their mapped urls.<br/><br/>[sourcecode language='html']<br/><configuration><br/><system.web><br/> <urlMappings><br/> <add url=”~/Home.aspx” mappedUrl=”~/Default.aspx”/><br/> </urlMappings><br/></system.web><br/></configuration><br/>[/sourcecode]<br/><br/>Here whenever the request for Home.aspx will come the .Net engine will search for urlMappings section in web.config file and server the page that is mapped with it. In the above mention example it will server Default.aspx page.<br/>Limitations: To have more control over the urls, regular expression cannot be used. So it is better to build our own URL Remapper HTTP Module.<br/><strong>Live World Scenario:</strong><br/>In case of shopping cart with thousands of product categories and catalogs it is very important to make this page SEO Friendly. Though SEO includes several criteria depending on different robots basic idea of URL remains the same. So by using URL Remapping we can generate SEO friendly URLS that robots can easily search.<br/>Like say for example we are having three products categories viz<br/>CellPhones<br/>Computers<br/>DigitalCameras<br/>We can map all the three categories to a single page that servers the purpose of displaying these products based on the product name<br/>So we map all the three to Product.aspx page like shown in the below section.<br/><br/>[sourcecode language='html']<br/><configuration><br/><system.web><br/> <urlMappings><br/> <clear/><br/> <add url="~/CellPhones.aspx" mappedUrl="~/Product.aspx"/><br/> <add url="~/Computers.aspx" mappedUrl="~/Product.aspx"/><br/> <add url="~/DigitalCameras.aspx" mappedUrl="~/Product.aspx"/><br/></urlMappings><br/></system.web><br/></configuration><br/>[/sourcecode]<br/><br/>Now whenever the request for CellPhones.aspx, Computers.aspx or DigitalCameras.aspx comes .Net engine will compile Product.aspx page and will server to the requesting client. In Product.aspx page we can extract the name and make calls to database to get all the products related to the given category.<br/><br/> <br/><br/>To Download code sample<span style="color:#ff6600;"><strong> </strong><a title="URL Remapping Code Sample by Dhaval Upadhyaya" href="http://upadhyayadhaval.googlepages.com/URLRemapping.zip" target="_blank">Click Here </a></span>Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com15tag:blogger.com,1999:blog-623348949309491130.post-91781252378409522372008-10-19T02:11:00.000-07:002017-06-01T01:55:05.538-07:00Modify Web Configuration file without restarting asp net worker process
(aspnet_wp).<span style="color:#ff6600;"><strong>Modify Web Configuration file without restarting asp net worker process (aspnet_wp).</strong></span><br/><br/>No one in the world can say that web.config file will remain intact after the deployment. Modifications have to happen to some or the other parameters of the web configuration file like one has to add or remove key value pairs from appsettings section etc…<br/><br/>So what?<br/>As soon as the webs configuration file is saved the aspnet_wp worker process of that particular web application gets restarted and all the current sessions and data are lost.<br/><br/>This can cause tremendous issues to an organization whose application needs to be up for 24*7.<br/><br/>To recover from such kind of scenario Microsoft has already provided a great tweak to handle this.<br/><br/>Following are some steps that need to be followed.<br/>Step 1) Make a separate configuration file lets say for example appsettings.config with the following xml data.<br/><br/>[sourcecode language='html']<br/><br/><?xml version="1.0"?><br/><appSettings><br/> <clear/><br/> <add key="Name" value="Dhaval"/><br/> <add key="Surname" value="Upadhyaya"/><br/></appSettings><br/><br/>[/sourcecode]<br/><br/>Step 2) Now in the original web.config file make your appSettings section look like below<br/><br/>[sourcecode language='html']<br/><br/><appSettings configSource="appsettings.config"><br/></appSettings><br/><br/>[/sourcecode]<br/><br/>You are done.<br/><br/> <br/>Place a debug point on the Application_Start event in global.asax file and check that changing appsettings.config does not restart the worker process.Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com5tag:blogger.com,1999:blog-623348949309491130.post-32851558484835355322008-08-30T02:34:00.000-07:002017-06-01T01:55:05.502-07:00How to create Scheduled Jobs in .net web applications.<strong><span style="color:#ff6600;">How to create Scheduled Jobs in .net web applications.</span></strong><br/><br/>Calling a function at predefined iteration of time has been one of the key requirements of web applications.<br/>Example:<br/>You want to automatically archive the data.<br/>You want to automatically purge the data.<br/>You want to automatically send the News Letters.<br/>You want to take backup of the files or database etc.<br/><br/>Generally this type of functionality can be easily archived by creating and configuring scheduled jobs in SQL Server.<br/><br/>What if you are using the express edition of SQL Server?<br/>You cannot take advantage of this feature because all the editions of SQL Server do not provide this functionality.<br/><br/>In this article I will explain how we can achieve this functionality using purely .Net framework class.<br/><br/>First of all let’s thanks System.Threading class. The main cream lies inside this class shipped in .Net Framework. Many of us usually do not use it but believe me its one of the most beautiful classes of the framework.<br/><br/>Anyways<br/><br/>Following are the steps which you need to perform:<br/><br/><strong>Step 1)</strong> Create a class called Jobs.cs<br/><br/>[sourcecode language='csharp']<br/><br/>namespace myScheduler<br/>{<br/> public sealed class Jobs<br/> {<br/> public Jobs(){}<br/><br/> public static void DailyJob(object state)<br/> {<br/> //Your dream goes here.<br/> }<br/><br/> public static void HourlyJob(object state)<br/> {<br/> //Your dream goes here.<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Jobs class includes the below two functions that will be called by our scheduler which we will create in the second step.<br/>I have created two functions for this purpose.<br/>DailyJob: Will be called daily by the scheduler.<br/>HourlyJob: Will be called hourly by the scheduler.<br/><br/> <br/><br/><strong>Step 2)</strong> Create a class called Scheduler.cs<br/><br/>[sourcecode language='csharp']<br/><br/>using System;<br/>using System.Threading;<br/><br/>namespace myScheduler<br/>{<br/> public sealed class Scheduler<br/> {<br/> public Scheduler() { }<br/><br/> public void Scheduler_Start()<br/> {<br/> TimerCallback callbackDaily = new TimerCallback(Jobs.DailyJob);<br/> Timer dailyTimer = new Timer(callbackDaily, null, TimeSpan.Zero, TimeSpan.FromHours(24.0));<br/><br/> TimerCallback callbackHourly = new TimerCallback(Jobs.HourlyJob);<br/> Timer hourlyTimer = new Timer(callbackHourly, null, TimeSpan.Zero, TimeSpan.FromHours(1.0));<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Scheduler class contains the actual mechanism for running jobs created in Jobs class in Step one.<br/><br/><span style="text-decoration:underline;">Timer:</span> Mechanism for executing method at specified time intervals. This method has 5 overloads which we can use as per our needs. Some of its parameters are<br/><span style="text-decoration:underline;">TimerCallback:</span> Represents the method that you want to actually callback on at a particular interval of time.<br/><span style="text-decoration:underline;">State:</span> Any type of object you want to pass to your callback method.<br/><span style="text-decoration:underline;">Due Time:</span> Amount of delay after which callback will be invoked. TimeSpan.Zero means immediately.<br/><span style="text-decoration:underline;">Period:</span> Time period between invocations of callback function.<br/><br/> <br/><br/><strong>Step 3)</strong> Add Global.asax file to your web project. In Application_Start event instantiate Scheduler object and make a call to Scheduler_Start() method.<br/><br/>[sourcecode language='html']<br/><br/><%@ Application Language="C#" %><br/><%@ Import Namespace="myScheduler" %><br/><br/><script RunAt="server"><br/><br/> void Application_Start(object sender, EventArgs e)<br/> {<br/> // Code that runs on application startup<br/> Scheduler objmyScheduler = new Scheduler();<br/> objmyScheduler.Scheduler_Start();<br/> }<br/><br/> void Application_End(object sender, EventArgs e)<br/> {<br/> // Code that runs on application shutdown<br/> }<br/><br/> void Application_Error(object sender, EventArgs e)<br/> {<br/> // Code that runs when an unhandled error occurs<br/> }<br/><br/> void Session_Start(object sender, EventArgs e)<br/> {<br/> // Code that runs when a new session is started<br/> }<br/><br/> void Session_End(object sender, EventArgs e)<br/> {<br/> // Code that runs when a session ends.<br/> // Note: The Session_End event is raised only when the sessionstate mode<br/> // is set to InProc in the Web.config file. If session mode is set to StateServer<br/> // or SQLServer, the event is not raised.<br/><br/> }<br/> <br/></script><br/><br/>[/sourcecode]<br/><br/> <br/><br/>You are done.<br/><br/>How it works?<br/>Whenever the applications is first started the Application_Start() in Global.asax is called and this calls Scheduler_Start() method which configures all the Jobs that we have created.<br/><br/>I have demonstrated a daily and hourly job in the above examples. In order to debug and test this code you need to wait for an Hour or a Day. Don’t panic I have done this intentionally. So in order to brush up your above learning’s prepare a job in Jobs.cs file that would be called every minute. Configure the callback and timer for your new job in Scheduler.cs file and enjoy the gist of scheduling.<br/><br/><strong>Note:</strong> After running the project once do not forget to restart the IIS because Application_Start() wont be called every time you run your project. You know why?Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com4tag:blogger.com,1999:blog-623348949309491130.post-52296518882184033302008-08-15T06:08:00.000-07:002017-06-01T01:55:05.523-07:00How to Encrypt or Decrypt sections of Configuration file.<span style="color:#ff6600;"><strong>How to Encrypt or Decrypt sections of Configuration file.</strong></span><br/><br/>It is always a good practice to protect sensitive information in configuration files. One should always protect connectionStrings section from being easily readable; also some times it becomes necessary to encrypt appSettings section that may include some sensitive data. You know why…?<br/><br/>So in this Blog I will walkthrough the steps required for encryption\decryption of sections in configuration file.<br/><br/>.Net framework ships two providers for this purpose.<br/>RsaProtectedConfigurationProvider and DpapiProtectedConfigurationProvider.<br/>Here I will use RsaProtectedConfigurationProvider.<br/><br/> <br/><strong>Step 1)</strong> First off all we will add provider to configuration section of web.config file that you want to play with. This provider is required for actual processing done while running commands depicted in step 3 and 4.<br/><br/>[sourcecode language='html']<br/><br/><configuration><br/><configProtectedData defaultProvider="myProvider"><br/><providers><br/> <clear/><br/> <add name="myProvider"<br/> type="System.Configuration.RsaProtectedConfigurationProvider"<br/> keyContainerName="NetFrameworkConfigurationKey"/><br/></providers><br/></configProtectedData><br/></configuration><br/><br/>[/sourcecode]<br/><br/> RsaProtectedConfigurationProvider requires key container for encryption and decryption purpose. This container includes private\public keys that are required during encryption and decryption process by the attached provider.<br/><br/>NetFrameworkConfigurationKey : This is the default key container shipped by Microsoft. You can also create your own key container that includes private\public keys required for encryption\decryption. In order to avoid confusion I will depict these steps in my next article.<br/><br/><span style="text-decoration:underline;">Note</span>: As we are using default key container "NetFrameworkConfigurationKey" you can do away with the first step. This step will be added by machine.config file cause it includes declaration for both providers ("RsaProtectedConfigurationProvider" and "DpapiProtectedConfigurationProvider"). But this will be helpful incase we are creating our own key container.<br/><br/><strong></strong><br/><br/><strong>Step 2)</strong> After adding the provider in Step 1 go to the Visual Studio command prompt. Now In order to access "NetFrameworkConfigurationKey" key container your "ASPNET" account must have permission to access it. Run the below command to give access.<br/><br/>aspnet_regiis -pa "NetFrameworkConfigurationKey" "ASPNET"<br/><br/> <br/><br/><strong>Step 3)</strong> Run below command to encrypt connectionStrings section of your web.config file located in the virtual directory named "MyWebApplication".<br/><br/>aspnet_regiis -pe connectionStrings -app /MyWebApplication<br/><br/> <br/><br/><strong>Step 4)</strong> Run below command to decrypt connectionStrings section of your web.config file located in the virtual directory named "MyWebApplication".<br/><br/>aspnet_regiis -pd connectionStrings -app /MyWebApplication<br/><br/><span style="text-decoration:underline;">Note:</span> You can replace the "connectionStrings" section with the section name you want to encrypt\decrypt.<br/>Eg: aspnet_regiis -pe appSettings -app /MyWebApplication<br/>This will encrypt "appSettings" section of your web.config file located in the virtual directory named "MyWebApplication".<br/><br/>To get more help about aspnet_regiis use the below command<br/>aspnet_regiis helpDhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com1tag:blogger.com,1999:blog-623348949309491130.post-3830110415826812812008-07-19T23:55:00.001-07:002017-06-01T01:55:05.505-07:00Creating Custom Controls in ASP .Net<strong>Creating Custom Controls in ASP .Net</strong><br/><br/>In this article I have simply demonstrated 2 code examples for creating Custom Web Controls.<br/><br/><strong>Why Custom Controls?</strong><br/>To cater through the real world scenarios that may not be supplemented by inbuilt .Net controls, the need for Custom Control arises. Also their are several other reasons for creating custom control like reusability, centralized management over the control, ease of usage etc.<br/><br/><strong>How to approach the requirement for creating Custom Controls?</strong><br/>If any of the inbuilt .Net control meets your requirement than you should always use these controls. If not than ask yourself a question<br/><br/>Would any of the existing control help me?<br/><br/>If yes than<br/>Inherit from the existing control and add the new features to it and extend it further.<br/>If No than<br/>You need to build the control from scratch. In this case inherit from WebControl class.<br/><br/><strong></strong> <br/><br/><strong>How to create Custom Controls?</strong><br/><br/>Their are two ways in which you can create a custom control.<br/>1) You can inherit from existing .net web control to extend its features further. OR<br/>2) You can directly inherit from WebControl class to create a web control from scratch.<br/><br/>Depending upon the approach you choose their will be several properties and methods for you to override. All of them cannot be explained here so I am explaining some important among them that I have used in my code samples.<br/><br/>AddAttributesToRender - Adds HTML or Style attributes for any of your HtmlTextWriterTag. You can also use HtmlTextWriter's "AddAttribute" , "AddStyleAttribute" methods to achieve the same functionality. Make sure that you add this attributes before using "RenderBeginTag" method.<br/><br/>RenderContents - Outputs HTML content of Server Control to HtmlTextWriter object. So override this method to manage the HTML that your custom control renders to the browser.<br/><br/>TagKey - WebControl renders a span <span>TAG by default on the cient browser. But to render any specific TAG you need to override this method.</span><br/><br/><strong>Inheriting from the existing control<br/></strong>This example depicts the creation of a new web control named "myButton" that is derived from the Button class. It has all the features that a normal button control has. But for a twist I have added a simple feature that prompts for a message before submitting the page back to the server. I have added a new property called "AlertMessage" to quench this requirement.<br/><br/>[sourcecode language='csharp']<br/><br/>using System;<br/>using System.Web.UI;<br/>using System.Web.UI.WebControls;<br/><br/>namespace myControlLib<br/>{<br/> public class myButton : Button<br/> {<br/> public myButton() { }<br/> private string _AlertMessage = "Are you sure to process this request!";<br/> public string AlertMessage<br/> {<br/> set { _AlertMessage = value; }<br/> get { return _AlertMessage; }<br/> }<br/> protected override void AddAttributesToRender(HtmlTextWriter writer)<br/> {<br/> writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "return confirm('" + _AlertMessage + "')"); base.AddAttributesToRender(writer);<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Registering the control on the web page<br/><br/>[sourcecode language='html']<br/><br/><%@ Register Assembly="myControlLib" Namespace="myControlLib" TagPrefix="myUcl" %><br/><br/>[/sourcecode]<br/><br/>Using the control<br/><br/>[sourcecode language='html']<br/><br/><myUcl:myButton ID="MyButton1" runat="server" Text="MyButton 1" AlertMessage="Custom Message here!"/><br/><br/><myUcl:myButton ID="MyButton2" runat="server" Text="MyButton 2" /><br/><br/>[/sourcecode]<br/><br/><strong></strong><br/><br/><strong></strong><br/><br/><strong>Inheriting from the WebControl class<br/></strong>This example depicts the creation of a new web control named "myImage" that is directly derived from the WebControl class. This control renders a Picture, Name of the Picture and Description of the Picture. Description of the Picture is displayed when the mouse is moved over the picture.<br/>For this I have created 3 additional properties for this.<br/><br/>ImageUrl - The url of the image to be displayed<br/><br/>ImageName - The name of the image.<br/><br/>ImageDescription - The description for the image.<br/><br/>[sourcecode language='csharp']<br/><br/>using System;<br/>using System.Web.UI;<br/>using System.Web.UI.WebControls;<br/><br/>namespace myControlLib<br/>{<br/> public class myImage : WebControl<br/> {<br/> public myImage() { }<br/><br/> private string _ImageUrl = "";<br/> public string ImageUrl<br/> {<br/> get { return _ImageUrl; }<br/> set { _ImageUrl = value; }<br/> }<br/> private string _ImageName = "";<br/> public string ImageName<br/> {<br/> get { return _ImageName; }<br/> set { _ImageName = value; }<br/> }<br/> private string _ImageDescription = "";<br/> public string ImageDescription<br/> {<br/> get { return _ImageDescription; }<br/> set { _ImageDescription = value; }<br/> }<br/> protected override void RenderContents(HtmlTextWriter writer)<br/> {<br/> writer.AddAttribute("onmousemove", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='';");<br/> writer.AddAttribute("onmouseout", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='none';");<br/> writer.AddAttribute(HtmlTextWriterAttribute.Src, _ImageUrl);<br/> writer.RenderBeginTag(HtmlTextWriterTag.Img);<br/> writer.RenderEndTag();<br/> writer.RenderBeginTag(HtmlTextWriterTag.Div);<br/> writer.Write("Name : " + _ImageName);<br/> writer.RenderEndTag();<br/> writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");<br/> writer.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + "_divDescription");<br/> writer.RenderBeginTag(HtmlTextWriterTag.Div);<br/> writer.Write("Description : " + _ImageDescription);<br/> writer.RenderEndTag();<br/> base.RenderContents(writer);<br/> }<br/> protected override HtmlTextWriterTag TagKey<br/> {<br/> get<br/> {<br/> return HtmlTextWriterTag.Div;<br/> }<br/> }<br/> }<br/>}<br/><br/>[/sourcecode]<br/><br/>Registering the control on the web page<br/><br/>[sourcecode language='html']<br/><br/><%@ Register Assembly="myControlLib" Namespace="myControlLib" TagPrefix="myUcl" %><br/><br/>[/sourcecode]<br/><br/>Using the control<br/><br/>[sourcecode language='html']<br/><br/><myUcl:myImage ID="MyImage1" runat="server" ImageUrl="~/images/myImage1.jpg" ImageName="My Image Name"<br/>ImageDescription="My Image Description........" /><br/><br/>[/sourcecode]<br/><br/><strong>Note:</strong> The above examples are the simplest controls that one can create. Remember that you can create more complex controls using the same approach. Choosing the best control that can serve the purpose of the requirement is our JOB and so make this decision very carefully.<br/><br/><a title="How to make better appearance of your custom control in Visual Studio." href="http://dhavalupadhyaya.wordpress.com/2008/07/20/how-to-make-better-appearance-of-your-custom-control-in-visual-studio/" target="_blank"><span style="color:#ff6600;"><strong>How to make better appearance of your custom control in Visual Studio.</strong></span></a><br/><br/><a title="How to add custom control in Visual Studio Toolbox." href="http://dhavalupadhyaya.wordpress.com/2008/07/20/how-to-add-custom-control-in-visual-studio-toolbox/" target="_blank"><span style="color:#ff6600;"><strong>How to add custom control in Visual Studio Toolbox.</strong></span></a>Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com10tag:blogger.com,1999:blog-623348949309491130.post-15825718761373893152008-07-19T23:55:00.000-07:002013-06-05T08:20:54.940-07:00How to make better appearance of your custom control in Visual Studio.<div dir="ltr" style="text-align: left;" trbidi="on">
<b>How to make better appearance of your custom control in Visual Studio.</b><br />
<br />
In the previous article <a href="http://dhavalupadhyaya.wordpress.com/2008/07/20/creating-custom-controls-in-asp-net/" target="_blank" title="Creating Custom Controls in ASP .Net"><b><span style="color: #ff6600;">Creating Custom Controls in ASP .Net</span></b></a> I have covered the technical approach for creating custom control.<br />
<br />
Here I will explain how to improve the appearance of your custom control<br />
Their are two ways in which this job can be done.<br />
1) By decorating your control and control properties with some design time attributes.<br />
2) By making your own control designer.<br />
<br />
<b>Decorating your control and control properties with some design time attributes:</b><br />
.Net provides various design time attributes that can be applied on control or on property to take control over the design aspects of the control. You can do lots of things with this attributes let’s say:<br />
<br />
One can choose the default event or default property for their controls.<br />
<br />
One can assign the description to the property that is displayed in the last section of the property window when the property is selected.<br />
<br />
One can categorize their additional properties in property window. This would be helpful when the property window is switched to "Categorized" mode.Etc...<br />
<br />
Their are lots of such attributes with which you can playaround.<br />
Some of them I have described below.<br />
<br />
<b>Attributes you can apply to your control class:</b><br />
<br />
DefaultEvent - This attribute specifies the default event for your control. So when a control is double clicked, the event handler is automatically created for this event.<br />
<br />
DefaultProperty - This attribute specifies the default property for your control. So when you open the property window for your control, this property will be focused by default.<br />
<br />
ToolboxData - This attribute allows you to specify any tags that are added to the markup of your control whenever it is added to the page.<br />
<br />
ToolboxItem - This attribute allows you to block the control from appearing in the toolbox.<br />
<br />
TagPrefix - This attribute allows you to manage the html markup for the registration tag of your control.<br />
<br />
<b>Attributes you can apply to your control property:</b><br />
<br />
Bindable - Displays a data binding dialog box for the property.<br />
<br />
Browsable - This attribute allows you to block the property from appearing in Property window.<br />
<br />
Category - This attribute allows you to group properties in a particular stencil. The property will appear under this category in the property window.<br />
<br />
DefaultValue - This attribute allows you to give default value for the property.<br />
<br />
Description - This attribute allows you to specify the description for the property. This description is displayed below in the property window when the property is selected.<br />
<br />
Editor - This attribute allows you to specify the custom editor window for the property. Examples of custom editor are ImageUrlEditor, MailFileEditor, MdbDataFileEditor, UrlEditor etc...<br />
<br />
EditorBrowsable - This attribute allow you to block a property from being display in the Intellisense.<br />
<br />
<br />
Example Source Code<br />
<pre class="brush:csharp">private string _ImageUrl = "";
[Category("My Custom Properties")]
[Description("Specify path of the image to be displayed.")]
[Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
[DefaultValue("")]
[UrlProperty]
[Bindable(true)]
public string ImageUrl
{
get { return _ImageUrl; }
set { _ImageUrl = value; }
}
</pre>
<b>Making your own control designer:</b><br />
Control Designer help to take control over the appearance of the control when they are drag dropped in the page. One can also create a smart tag that can help user to easily configure some properties of your control. Example: Some of the .Net controls like FormView, DetailsView, GridView have smart tags that help users to easily configure some important properties like Datasource, Templates etc. I will try to cover How to make smart tag controller in my next article.<br />
<br />
Example Source Code<br />
<pre class="brush:csharp">using System;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
[assembly: TagPrefix("myControlLib", "myUcl")]
namespace myControlLib
{
public class myImageDesigner : ControlDesigner
{
myImage objmyImage;
public override string GetDesignTimeHtml()
{
if (objmyImage.ImageUrl.Trim().Length == 0)
{
return "Please set Image URL Property!";
}<br />
else<br />
{<br />
return base.GetDesignTimeHtml();<br />
}<br />
}<br />
public override void Initialize(IComponent component)<br />
{<br />
objmyImage = (myImage)component;<br />
base.Initialize(component);<br />
return;<br />
}<br />
}<br />
[Designer("myControlLib.myImageDesigner,myControlLib")]<br />
[ToolboxBitmap(typeof(myImage), "myImageLogo.bmp")]<br />
[ToolboxData(@"<{0}:myImage runat=""server"" ImageUrl="" "" ImageName="" "" ImageDescription="" "" />")]<br />
public class myImage : WebControl<br />
{<br />
public myImage() { }<br />
private string _ImageUrl = "";<br />
[Category("My Custom Properties")]<br />
[Description("Specify path of the image to be displayed.")]<br />
[Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]<br />
[DefaultValue("")]<br />
[UrlProperty]<br />
[Bindable(true)]<br />
public string ImageUrl<br />
{<br />
get { return _ImageUrl; }<br />
set { _ImageUrl = value; }<br />
}<br />
private string _ImageName = "";<br />
[Category("My Custom Properties")]<br />
[Description("Specify name of the image to be displayed.")]<br />
public string ImageName<br />
{<br />
get { return _ImageName; }<br />
set { _ImageName = value; }<br />
}<br />
private string _ImageDescription = "";<br />
[Category("My Custom Properties")]<br />
[Description("Specify description of the image to be displayed.")]<br />
public string ImageDescription<br />
{<br />
get { return _ImageDescription; }<br />
set { _ImageDescription = value; }<br />
}<br />
protected override void RenderContents(HtmlTextWriter writer)<br />
{<br />
writer.AddAttribute("onmousemove", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='';");<br />
writer.AddAttribute("onmouseout", "javascript:document.getElementById('" + this.UniqueID + "_divDescription').style.display='none';");<br />
writer.AddAttribute(HtmlTextWriterAttribute.Src, _ImageUrl);<br />
writer.RenderBeginTag(HtmlTextWriterTag.Img);<br />
writer.RenderEndTag();<br />
writer.RenderBeginTag(HtmlTextWriterTag.Div);<br />
writer.Write("Name : " + _ImageName);<br />
writer.RenderEndTag();<br />
writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");<br />
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + "_divDescription");<br />
writer.RenderBeginTag(HtmlTextWriterTag.Div);<br />
writer.Write("Description : " + _ImageDescription);<br />
writer.RenderEndTag();<br />
base.RenderContents(writer);<br />
}<br />
protected override HtmlTextWriterTag TagKey<br />
{<br />
get<br />
{<br />
return HtmlTextWriterTag.Div;<br />
}<br />
}<br />
}<br />
}
</pre>
<br />
<br />
<b>Note:</b> Do not forget to add a .bmp image named ("myImageLogo.bmp") to this project. This image would be displayed as the icon for your control in the toolbox. You can also create .bmp file using inbuilt .Net design tool. Just click on the added .bmp file to open this editor.<br />
Your bmp should be 16x16 pixels in size.<br />
<br />
<br />
To add custom control to your toolbox refere<br />
<a href="http://dhavalupadhyaya.wordpress.com/2008/07/20/how-to-add-custom-control-in-visual-studio-toolbox/" target="_blank" title="How to add custom control in Visual Studio Toolbox."><span style="color: #ff6600;"><b>How to add custom control in Visual Studio Toolbox.</b></span></a><br />
<br /></div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com1tag:blogger.com,1999:blog-623348949309491130.post-50177184101024046582008-07-19T23:54:00.000-07:002013-06-05T08:13:05.506-07:00How to add custom control in Visual Studio Toolbox.<div dir="ltr" style="text-align: left;" trbidi="on">
<b><a href="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_1.jpg"></a>How to add custom control in Visual Studio Toolbox.</b><br />
<br />
In my previous article <a href="http://dhavalupadhyaya.wordpress.com/category/microsoft-net-20/custom-controls/" target="_blank" title="Creating Custom Controls in ASP .Net"><b><span style="color: #ff6600;">Creating Custom Controls in ASP .Net</span></b> </a> we have seen the technical approach for creating custom control and in <a href="http://dhavalupadhyaya.wordpress.com/2008/07/20/how-to-make-better-appearance-of-your-custom-control-in-visual-studio/" target="_blank" title="How to make better appearance of your custom control in Visual Studio."><b><span style="color: #ff6600;">How to make better appearance of your custom control in Visual Studio</span></b></a> we have gone through the design aspects of custom control.<br />
<br />
Now in this article I will explain how to add your custom control to your Toolbox.<br />
<br />
<br />
<span style="text-decoration: underline;">Making Custom Control Class Library Project.</span><br />
<br />
<b>Step 1</b> - Create a class library project named myControlLib.<br />
<br />
<b>Step 2</b> - Add the following code to a new class named myImage. To download sample code files <a href="http://upadhyayadhaval.googlepages.com/myControlLib.zip" target="_blank" title="Custom Control Class Library by Dhaval Upadhyaya"><span style="color: #ff6600;">click here</span></a>. After downloading add “myImage.cs” and “myImageLogo.bmp” file to your “myControlLib” project. Change the “Build Action” property of “myImageLogo.bmp” to Embedded Resource.<br />
<br />
<b>Step 3</b> - Compile the project.<br />
<br />
<b>Note</b>: Above given steps are specific to the code sample that I have created. If you want to rename any of the file or change any other aspects than make sure that you also change the design time attributes of your control.<br />
<br />
Example: [Designer ("myControlLib.myImageDesigner,myControlLib")] uses the namespace “myControlLib” that is directly related to the name of the class library project you make.<br />
<br />
<br />
<span style="text-decoration: underline;">Adding custom control to toolbox.</span><br />
<br />
<b>Step 1</b> - Switch over to the web project in which you want to use the control.<br />
<br />
<b>Step 2</b> - In toolbox add your own tab or click on general tab.<br />
<br />
<b>Step 3</b> - Right click in the selected tab area and click Chose Items.<br />
<br />
<img alt="" class="alignnone size-full wp-image-44" height="294" src="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_1.jpg" width="510" /><br />
<br />
<b>Step 4</b> - This will open Choose Toolbox Item screen. Click on Browse button and specify the path of dll you created in your myControlLib project.<br />
<br />
<img alt="" class="alignnone size-full wp-image-44" height="294" src="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_2.jpg" width="510" /><br />
<br />
<img alt="" class="alignnone size-full wp-image-44" height="294" src="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_3.jpg" width="510" /><br />
<br />
<b>Step 5</b> - Click Ok and you’re done. Your Custom control will be added to the toolbox as shown below.<br />
<br />
<img alt="" class="alignnone size-full wp-image-44" height="294" src="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_4.jpg" width="510" /><br />
<br />
<img alt="" class="alignnone size-full wp-image-44" height="294" src="http://dhavalupadhyaya.files.wordpress.com/2008/07/step_2_5.jpg" width="510" /></div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com21tag:blogger.com,1999:blog-623348949309491130.post-83814684214129816742008-07-05T04:38:00.000-07:002013-06-05T08:11:39.635-07:00Application Caching in .Net 2.0<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Application Caching in .Net 2.0</b><br />
<br />
<b>What is Application Caching?</b><br />
Application Caching is a technique in .Net 2.0 for caching different type of objects for faster access. As the name itself depicts, the Cache Object can be used from the entire application. A single cache object lies for the entire application and so can be used between various different user sessions and requests.<br />
<br />
<b><span style="color: black;">How Application Caching works and How to use it?</span></b><br />
The main motive for Application Caching is to store cached Objects in memory for faster access. Expensive operation to obtain and persists data or information can lead to application failure or sluggishness at time of heavy traffic. Also the amount of time and resources involved in such operations may not be satisfactionary. So to improve upon the performance and the scalability of your application you can cache the expensive data for faster access.<br />
<br />
You can use either Cache.Add() or Cache.Insert() methods for caching your data. The only difference between the two is, Cache.Add() method returns the object which you want to cache.<br />
So let’s say if you want to use the object and cache it as well. You can do so in a single line of code with the help of Cache.Add().<br />
<br />
Cache.Insert() methods has 4 different types of overloaded methods while Cache.Add() has only one.<br />
<br />
<b></b><br />
<br />
<b>Different Parameters used for the above methods:</b><br />
<br />
<b><span style="color: black;">Key</span></b><br />
It is the name for the cached object by which it will be accessed. You can also use the key to remove the cached object from the memory. Following code will remove the cached object named “customerList” from the memory.<br />
<br />
<pre class="brush:csharp">Cache.Remove("customerList");
</pre>
<br />
<br />
<b>Object to be cached</b><br />
It is the object that you want to cache. This object will be stored in the memory for faster retrieval.<br />
<br />
<br />
<b>Dependency</b><br />
It is the CacheDependency object that can be a file or cache key. So if the file or cache key is changed than the object in the cached will be invalidated and removed from the cache. This can be used to maintain the freshness of the data. This is an optional parameter. You can set it to null. Incase of multiple dependency conditions you can use AggregateCacheDependency object instead of CacheDependency.<br />
<br />
<br />
<b>Absolute Expiration Date</b>It is the time at which the object will be removed from the cache. To remove the object from cache after 10 minutes you can set this parameter to DateTime.Now.AddMinutes(10) as shown in the below code.<br />
<br />
<pre class="brush:csharp">Cache.Insert("customerList", objDataSet, new CacheDependency(Server.MapPath("~/App_Data/customerList.xml")),DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration,CacheItemPriority.Normal, null);
</pre>
<br />
<br />
If you do not want the object to expire forcefully after some time than you may set this parameter to Cache.NoAbsoluteExpiration as shown in below code.<br />
<pre class="brush:csharp">Cache.Insert("customerList", objDataSet,new CacheDependency(Server.MapPath("~/App_Data/customerList.xml")),Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,CacheItemPriority.Normal, null);
</pre>
<br />
<b>Time Span</b><br />
It is the time span after which the object will be removed from the cache if it was not accessed. So lets say if you want to remove the object from cache if it has not been accessed since last 10 minutes than you can use the below code.<br />
<br />
<pre class="brush:csharp">Cache.Insert("customerList", objDataSet,new CacheDependency(Server.MapPath("~/App_Data/customerList.xml")),Cache.NoAbsoluteExpiration,DateTime.Now.AddMinutes(10),CacheItemPriority.Normal, null);
</pre>
<br />
<br />
If you do not want the object to expire forcefully after some time it was last accessed than you may set this parameter to use Cache.NoSlidingExpiration as shown in below code.<br />
<pre class="brush:csharp">Cache.Insert("customerList", objDataSet,new CacheDependency(Server.MapPath("~/App_Data/customerList.xml")),Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,CacheItemPriority.Normal, null);
</pre>
<br />
Note: If you are using this sliding expiration time parameter than Absolute Expiration Date parameter must be Cache.NoAbsoluteExpiration<br />
<br />
<b>Priority</b><br />
It is the priority at which the objects will be purged from the memory incase if the memory runs low. Lower priority objects will be removed first.<br />
<br />
<b>Callback Method</b><br />
It is the event handler that will run when the object is removed from the cache. If you do not want to use this parameter than you can set this to null.<br />
<br />
<span style="color: #ff6600;">To download Application caching code sample </span><a href="http://upadhyayadhaval.googlepages.com/ApplicationCaching.zip" target="_blank" title="Application Caching code sample by Dhaval Upadhyaya"><span style="color: #ff6600;">Click Here</span></a><span style="color: #ff6600;">.</span><br />
<b>Note</b>: To introduce sophisticated caching layer in your application you can always use Microsoft’s Enterprise Library - Caching Application Block.</div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com2tag:blogger.com,1999:blog-623348949309491130.post-53295085507681177652008-06-20T21:36:00.000-07:002013-06-05T08:00:09.550-07:00Understanding Globalization and Localization in .NET<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Understanding Globalization and Localization in .NET</b><br />
<br />
Now days as the audience for web applications has bursted from computers to pda's, cell phones and many other gadgets, Globalization has become must for web application. Globalization allows your web application to be useful for different people in different parts of the world who speaks different languages.
Thanks to Microsoft .Net Globalization feature.
Using this feature one can easily build a web application available to dispersed audience throughout the world.
In this article I will walkthrough the steps that are essential for creating a multi cultured application. This example will include the use of Global and Local resource files that are heart for multi cultured web application.
ASP.Net supports two types of resources
Local Resource and Global Resource.
Both types of Resources are xml based resource files that can contain text translated into particular language<br />
<br />
<b>Local Resources:</b>
Local resource is specific to particular webpage. All the resource files related to particular webpage must be placed in a special .Net folder named App_LocalResources. This folder must be in the same folder of the webpage that you want to localize. So App_LocalResources can be subfolder for any folder of your website.<br />
<br />
<b>Global Resources:</b>
They are the resource files for the entire web application. They are not specific to any page. They can be accessed from the entire web application. Global resource files must be located in a special .Net folder named App_GlobalResources. App_GlobalResources must be at the root of the web application.<br />
<br />
<b>Steps to create local Resource file.</b><br />
1) Switch to design view of the webpage for which you want to create the resource file.<br />
2) Go to Tools menu and click Generate Local Resource.<br />
3) As the result of step 2 .Net generates the .resx file.
Naming conventions that Resource files follow is as explained below:
<PageName>.aspx.<language>.resx
Example
myWebPage.aspx.resx: This is the default resource file of your page. If no culture matches than this resource file is used.
myWebPage.aspx.es.resx: For Neutral Spanish culture it may look like this.
myWebPage.aspx.es-MX.resx: For Specific Spanish Mexican culture it may look like this.
What do you mean by neutral and specific cultures? I leave this small exercise to readers.<br />
<br />
<b>Steps to create global Resource file.</b><br />
1) Their are no specific utilities in .Net to generate Global resource files automatically. But you can create App_GlobalResources folder at root level and add a resource file manually Or you may copy the local resource file and change it at your will.
<b> </b><br />
<br />
<b>Ways in which you can Globalize or localize your application.</b>
Implicit Localization
<br />
<pre class="brush:html"><asp:Label ID="lblLoadLocalResource" runat="server"
Text="Local Resource"
meta:resourcekey="lblLoadLocalResourceResource1">
</asp:Label>
</pre>
Implicit Globalization
<br />
<pre class="brush:html"><asp:Label ID="lblLoadGlobalResource" runat="server"
Text="<%$ Resources:Resource, commonHeader %>"
ToolTip="<%$ Resources:Resource, commonHeader %>">
</asp:Label>
</pre>
Programmatic Localization
<br />
<pre class="brush:csharp">lblLoadLocalResource.Text = GetLocalResourceObject
("lblLoadLocalResourceResource1.Text").ToString();
lblLoadLocalResource.ToolTip = GetLocalResourceObject
("lblLoadLocalResourceResource1.ToolTip").ToString();
</pre>
Programmatic Globalization
<br />
<pre class="brush:csharp">lblLoadGlobalResource.Text = GetGlobalResourceObject
("Resource", "commonHeader").ToString();
lblLoadGlobalResource.ToolTip = GetGlobalResourceObject
("Resource", "commonHeader").ToString();
</pre>
<b>H</b><b>ow to change the UI Culture?</b>
Steps to check and configure the UI Culture of your webpage
1) To change it programmatically you need to override the InitializeCulture() of your web page.
<br />
<pre class="brush:csharp">protected override void InitializeCulture()
{
UICulture = "en";
}
</pre>
2) To change it implicitly from .aspx page Set
<br />
<pre class="brush:html"><%@ Page Language="C#" UICulture="en" %>
</pre>
3)To change it globally from web.config file
<br />
<pre class="brush:html"><system.web>
<globalization uiCulture="es"/>
</system.web></pre>
<pre class="brush:html"> </pre>
<b>Note</b>: If you set UICulture="auto" then .Net runtime will automatically detect the requesting browsers preferred language setting and will compile the related resource file for that culture. In this case you do not have to write a single piece of code for setting UICulture.<br />
<br />
<b>How to check this?</b><br />
1) Open IE and go to Tools > internet Options<br />
2) Click Languages tab.<br />
3) This will open language Preference dialog box window.<br />
4) Add the language by clicking the add button. Make sure to add the language for which you have configured the resource file of your web page.<br />
5) Select the language that you have added and using Move Up button, bring it to the first topmost position in the language list.<br />
6) Press Ok and again Ok to return.
Open your webpage in the browser and enjoy the taste of globalized web application.
I believe that few lines of code can speak thousand words and so I have prepared a small demo that includes both Globalization and Localization.
<span style="color: #f92305;"> </span><br />
<br />
<span style="color: #f92305;">To download the entire source code </span><a href="http://upadhyayadhaval.googlepages.com/Globalization.zip" target="_blank" title="Globalization in .Net Code Sample by Dhaval Upadhyaya"><span style="color: #f92305;">Click Here</span></a><span style="color: #f92305;">.</span>
<b> </b><br />
<br />
<b>Note</b>: Globalizing the web application entirely, requires lots of other things like changing the Culture, formatting dates and currency and lot more. I will try to incorporate all this stuff in my next article.</div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com7tag:blogger.com,1999:blog-623348949309491130.post-72686527480029799402008-06-13T23:33:00.000-07:002013-06-05T08:02:28.930-07:00Implementing ICallbackEventHandler in .Net 2.0<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Implementing ICallbackEventHandler in .Net 2.0 Custom Control.</b><br />
<br />
In this article I depict the use of ICallbackEventHandler with an example that shows random text generated from the server side code. For this purpose I have created a custom control named Show Tip.<br />
<br />
<b>How Show Tip control works.</b><br />
Show Tip control renders the HTML button. Clicking this button initiates AJAX call to the server. The server processes the AJAX call raised from the client browser and returns the result. Lastly a JavaScript registered on the client browser displays the result in a DIV tag. The main motive behind this is to avoid the full page post backs. Show tip Button directly communicates with the server using "Sneaky Post back".<br />
<br />
<b>How callbacks also known as "Sneaky Post back" actually work.</b><br />
The main magic lies in the ICallbackEventHandler interface.By implementing this interface and some lit bit of code one can easily trap the events raised from Client Browser, on the server and can respond to such events.<br />
<br />
<br />
<br />
Steps to use ICallbackEventHandler .<br />
<br />
<b>Step 1)</b>Render the JavaScript on Client Browser that will initiate the AJAX call.<br />
To create the JavaScript that initiates the AJAX call use Page.ClientScript.GetCallbackEventReference() method.<br />
<br />
This method returns a string<br />
WebForm_DoCallback('ShowTip1',null,showResult,null,showError,false).<br />
<br />
This is the JavaScript function that is used to callback to the server.<br />
<br />
The parameters used for GetCallbackEventReference() method are listed below.<br />
1) control - the control that initiates the AJAX call.<br />
<br />
2) argument - the argument that is send to the server. In this example it is null as we are not passing any value back to server. But you can pass any value Example if you want to display price for the selected item from combo.<br />
<br />
3) clientCallback - the name of the JavaScript function that executes after the result is returned from the server.<br />
<br />
4) context - the argument that is passed back to the clientCallback() and clientErrorCallback() methods after the AJAX call completes . In this example it is null as we are not passing any value to client browser.<br />
<br />
5) clientErrorCallback - the name of the JavaScript function that executes on client browser if an error on the server occues during AJAX callback.<br />
<br />
6) useAsync - pass false to perform the AJAX call asynchronously.<br />
<br />
<br />
<br />
<b>Step 2)</b>Implement the methods of ICallbackEventHandler to handle the AJAX call.<br />
ICallbackEventHandler has two methods that need to be implemented on the server side.<br />
1) RaiseCallbackEvent - This method is called first on server by AJAX call from the client.<br />
2) GetCallbackResult - This method Returns the result of the AJAX call to the client.<br />
<br />
<br />
<br />
<b>Step 3)</b>Render the JavaScript on Client Browser that manipulates the result received from the server. To render the JavaScript on Client Browser use Page.ClientScript.RegisterClientScriptInclude("ShowTip", Page.ResolveClientUrl("~/ClientScripts/ShowTip.js")) method.<br />
The parameters used for RegisterClientScriptInclude() method are listed below.<br />
1) key - any string that represents the script instance name.<br />
2) url - the path of the JavaScript file to register on the client browser that is called when results are returned from the server.<br />
<br />
<br />
<br />
<span style="color: #ff6600;">To download the entire example <a href="http://upadhyayadhaval.googlepages.com/ShowTip.zip" target="_blank" title="Show Tip Example"><span style="color: #ff6600;">Click</span> <span style="color: #ff6600;">Here</span></a></span><br />
<br />
<br />
ASP .Net 2.0 bundles some controls like Grid View, Tree View and Details View that use AJAX callbacks to perform some special tasks like<br />
Grid View uses callback to perform AJAX based paging and sorting.<br />
Tree View uses callback to perform AJAX based expansion of nodes.<br />
Details View uses callback to perform AJAX based paging.<br />
You will have to enable some property to do so. I leave this small exercise to the readers.</div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com0tag:blogger.com,1999:blog-623348949309491130.post-14524461445604491002008-06-05T08:44:00.000-07:002013-06-05T08:03:35.536-07:00How to Paste HTML content in blogspot?<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Problem in pasting HTML content in your blog?</b><br />
<br />
This is because all the blogs does not allow to directly use html in their content area due to security reasons.<br />
<br />
The area for writing the content in Blogspot is commonly known as<b> What You See Is What You Get (WYSIWYS) editor</b>.<br />
<br />
This <b>WYSIWYG</b> editor interprets the pasted HTML as true HTML. It will render exactly whatever you paste in it as HTML. This might spoil the look and feel of your blog.<br />
<br />
<b>Why this happens?</b><br />
<br />
Special characters used for HTML language like <,>,",& etc should be treated in special manner.<br />
Example:<br />
< can be treated as <b><</b><br />
> can be treated as <b>></b><br />
" can be treated as <b>"e;</b><br />
& can be treated as <b>&</b><br />
<br />
So writing these special characters in this manner and pasting it in blog can solve your problem. But this may be a tedious task to perform manually.<br />
<br />
<b>So here is the solution for it.</b><br />
<br />
Step 1) After making the below code working in .Net 2.0 copy the HTML you want to put in your blog and paste in the text area.<br />
<br />
Step 2) Click Encode HTML button.<br />
<br />
Step 3) 2nd step will generate the encoded html below the button.<br />
<br />
Step 4) Copy the output from 4th step to your blog content <b>(WYSIWYG)</b> editor.<br />
<br />
<br />
<b>Following sample code converts HTML to Encoded HTML format using Code behind Modal in .Net.</b><br />
<br />
<pre class="brush: html"><%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="false" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>">
<head runat="server">
<title>Encode HTML</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtHTML" runat="server" Columns="75" Rows="10" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btnEncode" runat="server" Text="Encode HTML" OnClick="btnEncode_Click" />
<asp:Literal ID="litEncodedHTML" runat="server" Mode="Encode"></asp:Literal></div>
</form>
</body>
</html>
</pre>
<pre class="brush: csharp">using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnEncode_Click(object sender, EventArgs e)
{
litEncousing System;dedHTML.Text = Server.HtmlEncode(txtHTML.Text.Trim());
}
}
</pre>
<b>Note:</b>
Those who are unaware of .Net they can use the same logic with their know language.
The main crux here is Server.HtmlEncode() method which transforms the HTML to encoded HTML.
</div>
</div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com5tag:blogger.com,1999:blog-623348949309491130.post-61123029353189092482008-06-04T06:33:00.000-07:002013-06-05T08:05:26.939-07:00How to Freeze Webpage while it is being processed in .Net 2.0 usingAJAX?<div dir="ltr" style="text-align: left;" trbidi="on">
<b>How to Freeze Webpage while it is being processed in .Net 2.0 using AJAX?</b><br />
Blocking a webpage seems to be difficult task while the data on the page is being posted back to the server or it is being refreshed. It becomes tricky to track the postback and reloading of the page. Though this can be achieved by using Response.Flush() method but it requires some extra effort.<br />
<br />
But thanks to AJAX Update Progress Panel.<br />
<br />
Using Update Progress Panel its just the mater of putting it on the page. The real magic lies in this panel and the DIV tag inside it. The panel takes care of the events required during the page updation and the DIV blocks the page till the panel is active. The magic that actually blocks the page lies in the DIV tag. I leave this to readers to find the crux of the magic.<br />
<br />
Following is the Code you can use to block the Webpage.<br />
<br />
<br />
<pre class="brush: html"><div style="top: 0px; height: 1000px; background-color: white; opacity: 0.75; filter: alpha(opacity=75); vertical-align: middle; left: 0px; z-index: 999999; width: 1000px; position: absolute; text-align: center;"></div>
</pre>
<br />
<br />
I have used simple DIV tag but it can be enhanced using an animated gif file or other custom JavaScript for showing loading image or processing time.<br />
<br />
<b>Note:</b>If you are using this code on the local server than AJAX might be so fast that the effect of this may not be visible.<br />
So try to use this code where the server requires some time to process the request OR use Thread.Sleep(5000) on your page.<br />
<br />
<b>Sample Code Using Code Behind Modal:</b><br />
<br />
<pre class="brush: html"><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WaitForRequest.aspx.cs"
Inherits="WaitForRequest" %>
<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="ajax" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Wait For Request</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ajax:ScriptManager ID="ScriptManager1" runat="server">
</ajax:ScriptManager>
<ajax:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="btnGetDate" runat="server" Text="Get Date" OnClick="btnGetDate_Click">
</asp:Button>
<asp:Label ID="lblTime" runat="server"></asp:Label>
</ContentTemplate>
</ajax:UpdatePanel>
<ajax:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<div style="top: 0px; height: 1000px; background-color: White; opacity: 0.75; filter: alpha(opacity=75);
vertical-align: middle; left: 0px; z-index: 999999; width: 1000px; position: absolute;
text-align: center;">
</div>
</ProgressTemplate>
</ajax:UpdateProgress>
</div>
</form>
</body>
</html>
</pre>
<pre class="brush: csharp">using System;
using System.Threading;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class WaitForRequest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnGetDate_Click(object sender, EventArgs e)
{
Thread.Sleep(5000);
lblTime.Text = DateTime.Now.ToString();
}
}
</pre>
</div>
Dhaval Upadhyayahttp://www.blogger.com/profile/13567953111420131976noreply@blogger.com5