Wednesday, May 30, 2012

Scheduled Tasks in ASP.NET Web Applications using Timers

I'm just found a article that I found on the MSDN blog. And I've just decieded to share on my blog with more explantation.

Before I found this, I honestly had known that the scheduled tasks can be only running on window scheduler tasks.

I had even tried to use Threading with looping to avoid window scheduler tasks on my web application.

Finally, I just found this article .

Scenario: A Web app calls wcf services every one minute. As I'm MVC web developer, my web app is always MVC application. System timer In global.asax, you need to create a Timers method. In below example, I give timer method name to ServiceTimers.

   1:  private void ServiceTimers()
   2:  {
   3:       System.Timers.Timer serivceTimer = new System.Timers.Timer();
   4:       serivceTimer.Enabled = true;
   5:       serivceTimer.Interval = (60000); // one minute
   6:   
   7:       serivceTimer.Elapsed += new
   8:       System.Timers.ElapsedEventHandler(ServiceTimer_Elaspsed);
   9:  }

Within the method, the last line is obviously event handler which call to a event which contains Web service called.

   1:  protected void ServiceTimer_Elaspsed(object sender, System.Timers.ElapsedEventArgs e)
   2:  {
   3:       WorkLoadClient workLoadClient = new WorkLoadClient();
   4:       workLoadClient.DoWork();
   5:  }

All together will be as below in Global.asax

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.Mvc;
   6:  using System.Web.Routing;
   7:  using NotificationService.Web.ServiceReference2;
   8:   
   9:  namespace NotificationService.Web
  10:  {
  11:      // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
  12:      // visit http://go.microsoft.com/?LinkId=9394801
  13:   
  14:      public class MvcApplication : System.Web.HttpApplication
  15:      {
  16:          public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  17:          {
  18:              filters.Add(new HandleErrorAttribute());
  19:          }
  20:   
  21:          public static void RegisterRoutes(RouteCollection routes)
  22:          {
  23:              routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  24:   
  25:              routes.MapRoute(
  26:                  "Default", // Route name
  27:                  "{controller}/{action}/{id}", // URL with parameters
  28:                  new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
  29:              );
  30:   
  31:          }
  32:   
  33:          protected void Application_Start()
  34:          {
  35:              AreaRegistration.RegisterAllAreas();
  36:   
  37:              RegisterGlobalFilters(GlobalFilters.Filters);
  38:              RegisterRoutes(RouteTable.Routes);
  39:   
  40:              ServiceTimers();
  41:          }
  42:   
  43:          private void ServiceTimers()
  44:          {
  45:              System.Timers.Timer serivceTimer = new System.Timers.Timer();
  46:              serivceTimer.Enabled = true;
  47:              serivceTimer.Interval = (60000); // one minute
  48:   
  49:              serivceTimer.Elapsed += new
  50:                  System.Timers.ElapsedEventHandler(ServiceTimer_Elaspsed);
  51:          }
  52:   
  53:          protected void ServiceTimer_Elaspsed(object sender, System.Timers.ElapsedEventArgs e)
  54:          {
  55:              WorkLoadClient workLoadClient = new WorkLoadClient();
  56:              workLoadClient.DoWork();
  57:          }
  58:      }
  59:  }

And I have a WCF service project which referenced by Web app.

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Runtime.Serialization;
   5:  using System.ServiceModel;
   6:  using System.Text;
   7:  using System.Threading;
   8:  using System.Net.Mail;
   9:  using System.Net;
  10:   
  11:  namespace NotificationService.Wcf
  12:  {
  13:     
  14:      public class WorkLoad : IWorkLoad
  15:      {       
  16:          public void DoWork()
  17:          {            
  18:              var client = new SmtpClient("smtp.gmail.com", 587)
  19:              {
  20:                  Credentials = new NetworkCredential("xxxx@gmail.com", "xxxxxx"),
  21:                  EnableSsl = true
  22:              };
  23:   
  24:              client.Send("xxx@gmail.com", "xxxx@email.com", "test", "testbody");
  25:            
  26:          }
  27:          
  28:      }
  29:  }
reference:http://weblogs.asp.net/samirgeorge/archive/2009/05/09/scheduled-task-in-asp-net-web-application-using-timers.aspx

Tuesday, May 29, 2012

C#Asp.net MVC Export CSV ActionResult

Exporting Csv format at MVC is extremely easy. In fact, with clean codes. My scenario: Lead data stores in a database. From the one click event which named download will pop out csv file to download.

The following code I found on develoq.net blog which is very useful. Literally, just drop that in and call it in actionresult from controller page.

   1:   public sealed class CsvActionResult : FileResult
   2:      {
   3:          private readonly DataTable dataTable;
   4:          public CsvActionResult(DataTable dataTable)
   5:              : base("text/csv")
   6:          {
   7:              this.dataTable = dataTable;
   8:          }
   9:   
  10:          protected override void WriteFile(HttpResponseBase response)
  11:          {
  12:              var outputStream = response.OutputStream;
  13:              using (var memoryStream = new MemoryStream())
  14:              {
  15:                  WriteDataTable(memoryStream);
  16:                  outputStream.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
  17:              }
  18:          }
  19:   
  20:          private void WriteDataTable(Stream stream)
  21:          {
  22:              var streamWriter = new StreamWriter(stream, Encoding.Default);
  23:   
  24:              WriteHeaderLine(streamWriter);
  25:              streamWriter.WriteLine();
  26:              WriteDataLines(streamWriter);
  27:   
  28:              streamWriter.Flush();
  29:          }
  30:          
  31:          private void WriteHeaderLine(StreamWriter streamWriter)
  32:          {
  33:              foreach (DataColumn dataColumn in dataTable.Columns)
  34:              {
  35:                  WriteValue(streamWriter, dataColumn.ColumnName);
  36:              }
  37:          }
  38:   
  39:          private void WriteDataLines(StreamWriter streamWriter)
  40:          {
  41:              foreach (DataRow dataRow in dataTable.Rows)
  42:              {
  43:                  foreach (DataColumn dataColumn in dataTable.Columns)
  44:                  {
  45:                      WriteValue(streamWriter, dataRow[dataColumn.ColumnName].ToString());
  46:                  }
  47:                  streamWriter.WriteLine();
  48:              }
  49:          }
  50:   
  51:          private static void WriteValue(StreamWriter writer, String value)
  52:          {
  53:              writer.Write("\"");
  54:              writer.Write(value.Replace("\"", "\"\""));
  55:              writer.Write("\",");
  56:          }
  57:   
  58:      }

Using by Datatable to manipulate data to display in Excel sheet. The following actionresult to fire when the download button clicked. And you can see how to read the model to datatable dynamically.

You can see the first loop is for table column name to display. And I use another loop to populate the data to right column.

   1:   [HttpPost]
   2:          public ActionResult Report(int formId)
   3:          {
   4:              DataTable table = new DataTable();
   5:              var formFieldList = formFieldRepo.Where(m => m.FormId == formId);
   6:              var formEntries = formEntryRepo.Where(m => m.FormId == formId);
   7:   
   8:              foreach (var item in formFieldList)
   9:              {
  10:                  table.Columns.Add(item.Title, typeof(string));
  11:                  //string[] rows = item.valu
  12:              }
  13:   
  14:              foreach (var item in formEntries)
  15:              {
  16:                  string[] rows = item.Value.Split(',');
  17:   
  18:                  DataRow dataRow = table.NewRow();
  19:                  foreach (var rowItem in rows)
  20:                  {
  21:                      if (!string.IsNullOrEmpty(rowItem))
  22:                      {
  23:                          dataRow[rowItem.Split('/').First().ToString()] = rowItem.Split('/').Last().ToString();
  24:                      }
  25:                  }
  26:                  table.Rows.Add(dataRow);
  27:              }
  28:   
  29:              return new CsvActionResult(table) { FileDownloadName = "ExportedFile.csv" };
  30:          }

Any questions and different opnions are warmly welcomed.

Sunday, May 27, 2012

MVC Webapi


Today, I'm posting about WebApi. Recently, I've looked some example of Webapi on other blogs. Recently, found some of other people's conversation from other sites.

1.Introduction to HttpClient HttpClient provides a flexible and extensible API for accessing all things exposed through HTTP. We used to use it for a while as part of WCF Web API. It is now part of ASP.NET Web API and in .NET 4.5 which is make developer to easier to develop.
System.Net.Http: it provides the basic HttpClient and related classes System.Net.Http.Formatting: Adds support for serialization, deserialization as well as for many additional features building on top of System.Net.Http System.Json: it is for JsonVaue which is a mechanism for reading and manipulating JSON documents
Please see below the sample code which I found it on msdn blog (http://code.msdn.microsoft.com/Introduction-to-HttpClient-4a2d9cee)

   1:  static void Main(string[] args) 
   2:          { 
   3:              // Create an HttpClient instance 
   4:              HttpClient client = new HttpClient(); 
   5:   
   6:              // Send a request asynchronously continue when complete 
   7:              client.GetAsync(_address).ContinueWith( 
   8:                  (requestTask) => 
   9:                  { 
  10:                      // Get HTTP response from completed task. 
  11:                      HttpResponseMessage response = requestTask.Result; 
  12:   
  13:                      // Check that response was successful or throw exception 
  14:                      response.EnsureSuccessStatusCode(); 
  15:   
  16:                      // Read response asynchronously as JsonValue and write out top facts for each country 
  17:                      response.Content.ReadAsAsync<JsonArray>().ContinueWith( 
  18:                          (readTask) => 
  19:                          { 
  20:                              Console.WriteLine("First 50 countries listed by The World Bank..."); 
  21:                              foreach (var country in readTask.Result[1]) 
  22:                              { 
  23:                                  Console.WriteLine("   {0}, Country Code: {1}, Capital: {2}, Latitude: {3}, Longitude: {4}", 
  24:                                      country.Value["name"], 
  25:                                      country.Value["iso2Code"], 
  26:                                      country.Value["capitalCity"], 
  27:                                      country.Value["latitude"], 
  28:                                      country.Value["longitude"]); 
  29:                              } 
  30:                          }); 
  31:                  }); 
  32:   
  33:              Console.WriteLine("Hit ENTER to exit..."); 
  34:              Console.ReadLine(); 
  35:          }

Just a little defination for HttpClient: Itis the main class for sending and receiving HttpRequestMessages and HttpResponseMessages. If you are used to using WebClient or HttpWebRequest.

An HttpClient instance is the place to configure extensions, set default headers, cancel outstanding requests and more.

  1. You can issue as many requests as you like through a single HttpClient instance.
  2. HttpClients are not tied to particular HTTP server or host; you can submit any HTTP request using the same HttpClient instance.
  3. You can derive from HttpClient to create specialized clients for particular sites or patterns
  4. HttpClient uses the new Task-oriented pattern for handling asynchronous requests making it dramatically easier to manage and coordinate multiple outstanding requests.

As you know HttpResponseMessage contains information about the response including the status code, headers, and any content body.

The content body is encapsulated in HttpContent which captures content headers such as Content-Type, Content-Encoding. we can read the content as JsonArray as well as any number of ReadAs* methods.

please see the more deail here http://blogs.msdn.com/b/henrikn/archive/2012/02/11/httpclient-is-here.aspx
public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
}
   1:  var url = "http://localhost:9000/api/contacts";
   2:  using (var client = new WebClient())
   3:  using (var reader = XmlReader.Create(client.OpenRead(url)))
   4:  {
   5:      var serializer = new XmlSerializer(typeof(Contact[]));
   6:      var contacts = (Contact[])serializer.Deserialize(reader);
   7:      // TODO: Do something with the contacts
   8:  }