The non-generic method 'Microsoft.Practices.Unity.IUnityContainer.Resolve cannot be used with type arguments

by Naveen 30. June 2010 18:08

I was working on introducing Unity Framework for Silverlight in one of my older Silverlight applications. I was trying to use Resolve to get hold of singleton instance of one of my objects. I kept getting following compile time error.

error CS0308: The non-generic method 'Microsoft.Practices.Unity.IUnityContainer.Resolve(System.Type, string, params Microsoft.Practices.Unity.ResolverOverride[])' cannot be used with type arguments

There was nothing wrong with the code that I had to call Resolve method. After doing dance for more than an hour with everything I could try, I finally figured out the problem and kicked myself. I never added using declaration for Unity namespace in the class where I was using the code. After adding following line, everything was normal in my world.

using Microsoft.Practices.Unity;
Give your advice to big bosses and make money

Views: 763

Tags:

.Net | C# | Silverlight

How to create splash screen for WinForms application?

by Naveen 21. June 2010 05:01

In development of my Index.dat File Viewer application, one of the thing that I wanted to do was put together a quick splash screen during start up of the application. I was not looking for a very elaborate splash screen with any fancy features. So I came up with a solution that I will share in this post.

Here are steps that you can follow to create a simple spalsh screen for Winforms application.

Setting up Splash Screen Form

  • Add a new form in your application.
  • On this form drop a Picture control.
  • Size this Picture control to size of the image you would like to show as splash screen
  • Add splash screen image to your project.
  • Set source of Image for Picture control to image that you added to your project.
  • Make sure that you set FormBorderStyle property of this form to None because we do not need to show any title bars or things like that for our splash screen. Also give some appropriate name to your form as well because this name will show up in taskbar. You definitely do not want to look naive if name like Form1 is showing up in taskbar.

    c# splash screen

Displaying Splash Screen

Now that you have set up form for your splash screen, you just need few lines of code to display the splash screen when application load and then hide it as soon as loading is complete.

In your constructor or form Load event handler of your main form, you will need to spawn a thread that will invoke display of splash screen form. For example in my application, I did it from constructor of main form as shown below.


public MainForm()
{
 InitializeComponent();
 _splashThread = new Thread(new ThreadStart(DoSplash));
 _splashThread.Start();
 Initialize();
}

void DoSplash()
{
 _splash = new DatViewerSplash();
 _splash.ShowDialog();
}

Hide Splash Screen

Now that your splash screen is showing when application is loading, at some point after load completes you will need to hide this splash screen as well. It will depend on your application to decide when it thinks that load has completed. For example in my application, I had to do some work in OnLoad event handler and right after that I decided to hide the splash screen. The following code snippet shows how I am hiding splash screen.


private void OnLoad(object sender, EventArgs e)
{
LoadTempInternetFiles();
CloseSplashScreen();
_splashThread.Abort();
}

delegate void CloseSplashScreenCallback();

private void CloseSplashScreen()
{
 if (_splash.InvokeRequired)
 {
  var callBack = new CloseSplashScreenCallback(CloseSplashScreen);
  _splash.Invoke(callBack);
 }
 else
 {
  _splash.Close();
 }
}

You may be wondering why didn't I simply called Close method on the splash screen object in OnLoad. If you did that you will get infamous exception telling you that you can not call any method on this windows object because it was created in another thread. If you look at how the window was shown, we spawned a new thread from main thread of the application. So your splash screen object was invoked from another thread. To take care of this thread context you will need to call Invoke method on that object and provide it a call back in the form of a delegate. In that delegate you can call Close method on form object.

Another question that may come in your mind is calling Abort on thread should take care of destroying or closing splash screen. I also thought that way but it did not seem to work that way. After calling Abort, splash screen was still visible. So doing it the right way is the way to go.

Give your advice to big bosses and make money

Views: 663

Tags:

.Net | WinForms

Opensource Index.dat file viewer

by Naveen 11. June 2010 12:09

Download Installation Files

Download Source Code

What is Dat File Viewer?

Simply put, this is a very light weight application that helps you see what all secrets microsoft is hiding in index.dat files in various folders under a user's profile. As per microsoft index.dat files are their cache or index files that they create to speed up access to various web sites, applications etc. But one thing lot of people have to come realize over the time that even after you clean up your Temporary Internet Files, Cookies, History etc. files from your windows machine, these index.dat files still carry all the footprints of your internet and file activities. So analysis of these files is used as one of the forensic tools when you want to recreate a user's internet activities in the past.

I am not going to go into details on format of index.dat files and other related technical details. Following link is an excellent technical resource on inside of index.dat file. This is by FoundStone.com a devision of McAfee.

I have developed this open source application based on the original C code developed by FoundStone.com. This application is built using .Net framework.

Install It

  • Download the insaller package associated with this post.
  • Unzip this file in a folder.
  • Double click on setup.exe to launch the installer.
  • Follow the instructions and you are all set to go.

Pre-requisites

You will need to have Microsoft .Net Framework 4.0 installed on your machine to run this application. You can download the run time from the following location.

Download Microsoft .Net 4.0 Framework

I did not spend much time on the installer package to get automatic install of Microsoft .Net 4.0 framework. May be I will get to that in upcoming release. But for now, my apologies for making you do manual install of the framework if you do not already have it.

Run It

If you chose default installation option, you should have ByteBlocks Dat File Viewer entry in your start menu and you should be able to launch the applicaiton from there. If for some reason you do not see menu item in Start menu, then look under ProgramFiles/ByteBlocks folder the application. From there, you can double click on ByteBlocks.DatFileViewe.exe file to launch the application.

After you launch the application, you will see a splash screen with picture of a turtle in it. Depending on amount of data contained in your index.dat files, the application may require few seconds to load. So be little patient with load screen, the application will eventually load.

Export Results

The application allows you to export list of URLs or Coookies from following locations into a PDF file.

  • Temporary Internet Files
  • Cookies
  • History

In the top menu of the application, click on Export > PDF link to generate PDF file.

Give your advice to big bosses and make money

Views: 675

Tags: , , , , ,

.Net | .Net | C# | C# | IE | IE | Windows | Windows | Application | Application

How to get list of user accounts on machine using .Net?

by Naveen 10. June 2010 06:17

Here is a code snippet that demonstrates how to get list of user accounts on your windows machine using .Net. Since there are no native .Net APIs to accomplish this task, you will need to use Interop to use Win32 APIs related to user management.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace UserEnvironment
{
 class Program
 {
  static void Main(string[] args)
  {
   Console.WriteLine(Environment.OSVersion.VersionString);
   Console.WriteLine("OS: {0}.{1}", 
    Environment.OSVersion.Version.Major, 
    Environment.OSVersion.Version.Minor);
   Console.WriteLine("****************************************");
   var accounts = GetListOfAccounts();
   if (accounts.Count != 0)
   {
    Console.WriteLine("User accounts on " + 
     System.Environment.MachineName + System.Environment.NewLine);
    foreach (var account in accounts)
    {
     Console.WriteLine(account);
    }
   }
   else
   {
    Console.WriteLine("No user account found!");
   }
  }

  static System.Collections.Specialized.StringCollection GetListOfAccounts()
  {
   int resumeHandle;
   int entriesRead;
   int totalEntries;
   IntPtr bufPtr;

   var userAccounts = new System.Collections.Specialized.StringCollection();
   NetUserWin32.NetUserEnum(null, 0, 2, out bufPtr, -1, 
    out entriesRead, out totalEntries, out resumeHandle);
   if (entriesRead > 0)
   {
    var users = new NetUserWin32.USER_INFO_0[entriesRead];
    IntPtr iter = bufPtr;
    for (int i = 0; i < entriesRead; i++)
    {
     users[i] = (NetUserWin32.USER_INFO_0)Marshal.PtrToStructure(iter, 
                           typeof(NetUserWin32.USER_INFO_0));
     iter = (IntPtr)((int)iter + Marshal.SizeOf(typeof(NetUserWin32.USER_INFO_0)));
     userAccounts.Add(users[i].Username);
    }
    NetUserWin32.NetApiBufferFree(bufPtr);
   }
   return userAccounts;
  }
 }
}

namespace UserEnvironment
{
 public class NetUserWin32
 {
  [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
  public struct USER_INFO_0
  {
   public String Username;
  }

  [DllImport("Netapi32.dll")]
  public extern static int NetUserEnum([MarshalAs(UnmanagedType.LPWStr)]string servername, 
    int level, int filter, out IntPtr bufptr, 
    int prefmaxlen, out int entriesread, out int totalentries,
    out int resume_handle);

  [DllImport("Netapi32.dll")]
  public extern static int NetApiBufferFree(IntPtr Buffer);
	}
}

Give your advice to big bosses and make money

Views: 328

Tags: ,

.Net | C# | Win32 | Windows

How to embed YouTube video in ASP.Net page - Server Control

by Naveen 3. June 2010 04:37

Download Source Code (9.09 kb)

Download Binaries (6.28 kb)

Recently I started created some YouTube videos and wanted to embed them in my ASP.Net web site. YouTube provides Embed button next to each video and that helps you create HTML code that you can put on your page. But that would mean that you will have to hard code this HTML on all pages where you want to embed videos. Also if you want to show some random videos on the pages, then this approach is not flexible.

I created this ASP.Net server control that allows to embed YouTube videos on any page. The control allows you to embed videos for which you already have URL or you can configure it to fetch any of the standard YouTube feeds and then display random video from that feed.

How to use it?

  • Download source code of the control and compile it or download pre-compiled binaries of the control.
  • Add reference to ByteBlocks.YouTubeWeb assembly in your project.
  • On the page where you want to embed YouTube video, add the following directive at the top of the page.

    <%@ Register TagPrefix="ByteBlocks" Assembly="ByteBlocks.YouTubeWeb" Namespace="ByteBlocks.Web.Control" %>

  • Now add the control on the page.

    <ByteBlocks:YouTube id="youTubeVideo" runat="server" Width="480" Height="385" VideoUrl="" FeedType="MostRecent" RandomResults="true" />

  • And you are all set to show random video from Most Recent video feed from YouTube.

Configurable Properties

  • VideoUrl: This property allows you to set URL of the video that needs to be embeded.
  • Width: Sets the width of the video player
  • Height: Set the height of the videeo player
  • FeedType: If you do not want to use a pre-defined video URL, you can pick a standard feed type. The control will fetch that feed from YouTube and display it based on value set for RandomResults and IndexToShow. This property is mututally exlcusive with VideoUrl. If you want the control to fetch standard feed, then do not set any URL in VideoUrl.
  • RandomResults: This property indicates to control to pick a random Video Url from the list of videos from standard feed type.
  • IndexToShow: If you set RandomResults to false, then the control will fetch the video at this index value. If this index is out of range, then the control picks the last entry in the feed list.

See it in Action

The following web site uses this control to show videos from most featured standard feed.

YouTube Server Control Demo

Under the covers

When you generate HTML code for a video from YouTube, it looks something like as shown below.


<object width="480" height="385">
<param name="movie" value="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0" 
  type="application/x-shockwave-flash" allowscriptaccess="always" 
  allowfullscreen="true" width="480" height="385"></embed>
</object>

So the control simply renders this HTML on ASP.Net page and uses the control properties to configure the display accordingly. The important components of this HTML is video ID used with the video player. I have shown that in bold in snipper above. A video URL looks like as shown below.

http://www.youtube.com/watch?v=Qp9_6ACSWug

Video ID is provided in v query string parameter. The control parses this ID and replaces it in the URL that is required for URL for video player.

Source Code and Binaries

Attached code is compiled using Visual Studio 2010 and .Net 4.0 framework. If you need code for earlier versions of Visual Studio, feel free to conttact me.

Give your advice to big bosses and make money

Views: 920

Tags: ,

.Net | ASP.Net

MethodAccessException - Upgrading Assemblies to .Net4.0

by Naveen 25. May 2010 05:16

This morning I was upgrading my HtmlParser and YahooFinanceParser libraries to use .Net 4.0 frameowrk. isual Studio 2010 conversion wizard did all the job of conversion. When I launched my test application to make sure everything was working, I was hit by a surprise. No code was changed other than compilation target was changed to .Net 4.0 and I got the following exception.

MethodAccessException

Attempt by method 'Winista.YahooFinanceParser.StockQuoteFetcher.GetStockQuote(System.String
to access method 'Winista.YahooFinanceParser.StockQuoteFetcher.CreateRequestAttributes(System.String)'
failed.

Since all assemblies were recompiled so the error details were not of much help asking to recompile with new referenced assmblies. I started with my usual ways of isolating the problem. Here was the call flow.

Console Application -->Library1 -->Library2

Exception was being thrown from a method in Library1. The exception message was not much of a help because it is complaining that class is having problem calling into its own private method. So I started my usual way of isolating the problem. The problem definitely seems to be code that was in CreateRequestAttributes. So I took the code out of there and directly put in the method GetStockQuote that was calling into CreateRequestAttributes. Now when i ran the test, i got the following exception.

MethodAccessException

Attempt by security transparent method 'Winista.YahooFinanceParser.StockQuoteFetcher.TestIt(System.String)' 
to access security critical method 'Winista.Text.HtmlParser.Http.RequestAttributes..ctor()' failed.

Assembly 'Winista.YahooFinanceParser, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null' 
is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security 
transparency model.  Level 2 transparency causes all methods in AllowPartiallyTrustedCallers 
assemblies to become security transparent by default, which may be the cause of this exception.

Now this exception detail made more sense. So let me explain what this issue is. In .Net4.0 framework, security tranparency rules prevent any security transparent code to call into security critical code. In .Net4.0 default security transpareny of library assemblies is security critical. My assembly Winista.YahooFinanceParser is marked with AllowPartiallyTrustedCallers attributes. This explicitly tells the security framework that this library will accept calls from security transparent callers. But the assembly Winista.HtmlParserPro do not have AllowPartiallyTrustedCallers attribute on it. This means it will not allow partial trusted or untrusted code to call into it. Therefore when method from Winista.YahooFinanceParser tried to create an object from Winista.HtmlParser, it threw MethodAccessException.

My original intention was to allow partially trusted to call into all these assemblies. But somehow AllowPartiallyTrustedCallers attribute slipped through the cracks for one assembly. After I applied AllowPartiallyTrustedCallers on Winista.HtmlParserPro assemnly, everything worked fine.

So if you are upgrading your libraries to .Net4.0 and you are not restricting any partially trusted or security transparent code to call into it, then put AllowPartiallyTrustedCallers attribute on your assemblies.

Give your advice to big bosses and make money

Views: 744

Tags: ,

.Net

WCF Error - Could not find endpoint element with name and contract in the ServiceModel client configuration section

by Naveen 30. March 2010 14:23

This week I had to work on an old Silverlight and WCF application. So I had to make this Silverlight 3.0 application consume a WCF service that is used to perform search in Amazon.com database. This post is about first WCF error I ran into when my silverlight application tried to call into my WCF web service. And I realized this is a very common issue lot of developers run into when developing a Silverlight application that consumes WCF service.


{System.InvalidOperationException: Could not find endpoint element with name 
'BasicEndPoint' and contract 'ProductSearchService.IAmazonSearchService' 
in the ServiceModel client configuration section. This might be because no 
configuration file was found for your application, or because no endpoint 
element matching this name could be found in the client element....

The error provided me some starting point to start my diagnosis. Here are the steps that i followed and approached the solution.

Check WCF Configuration File On Client

When you choose Add Service Reference option in Visual Studio to add a WCF service reference to your Silverlight application, it will add a WCF client configuration file ServiceReferences.ClientConfig in your project. Open that file to check if it does have correct WCF configuration entries. Well, in my case, for some reason Visual Studio choked and added an empty ServiceReferences.ClientConfig file. So I manually added the configuration entried to create a WCF proxy.


<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicEndPoint" maxBufferSize="2147483647" 
           maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
        <binding name="BasicHttpBinding_IAmazonSearchService" 
            maxBufferSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost/ProductsSearch/AmazonSearchService.svc"
        binding="basicHttpBinding" 
        bindingConfiguration="BasicHttpBinding_IAmazonSearchService"
        contract="ProductSearchService.IAmazonSearchService" 
        name="BasicHttpBinding_IAmazonSearchService" />
    </client>
  </system.serviceModel>
</configuration>

After populating configuration, I still kept getting the same when my Silverlight application tried to connect to WCF service. So I moved to next end point of this equation that was server side WCF service.

Silverlight Supports basicHttpBinding and not wsHttpBinding

I quickly checked the service implementation code and did not find anything wrong. There was nothing to check much because my one method in service was returning statically constructed list. So at this point I did not have to worry about diagnosing any issues with Amazon.com web service itself.

Now I opened web.config file to look for configuration entries for my WCF configuration. Oh well, there was something obviously wrong. Notice binding value in endpoint configuration. It is set to wsHttpBinding


<system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="ProductsSearch.AmazonSearchServiceBehavior">
     <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
      </behavior>
     </serviceBehaviors>
    </behaviors>
   <services>
    <service behaviorConfiguration="ProductsSearch.AmazonSearchServiceBehavior" 
     name="ProductsSearch.AmazonSearchService">
      <endpoint address="" binding="wsHttpBinding" 
       contract="ProductsSearch.IAmazonSearchService">
        <identity>
         <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
  </services>
</system.serviceModel>

Change the endpoint configuration to use basicHttpBinding. Recompile the service and go back to Silverlight project. Right click on the service reference and choose the option to update it. And now compile Silverlight project.

It worked!

Yes, that did work. So if you are working with a Silverlight 3.0 application that is going to consume a WCF service, make sure that:

  • Your WCF service is configured to use basicHttpBinding
  • Your client side WCF configuration file has correct information about the binding etc.
  • And if you are calling the client proxy constructor by name, then you do have correct name for your endpoint in client configuration file.
Give your advice to big bosses and make money

Views: 2680

Tags: ,

.Net | Silverlight | WCF

Error adding reference to assembly downloaded from internet

by Naveen 17. March 2010 12:03

If you download a .Net assembly from internet and then add reference to it in your .Net project, you will run into the following compile time error. This happens when you do it in VS2010 and using .Net 4.0 framework. The reason behind this is described in description of <loadFromRemoteSources> in MSDN documentation.


The "ValidateXaml" task failed unexpectedly.
System.IO.FileLoadException: Could not load file or assembly 'file:///C:\Projects\xyz.dll'
or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515
File name: 'file:///C:\Projects\xyz.dll' ---> System.NotSupportedException: An attempt was
made to load an assembly from a network location which would have caused the assembly to be
sandboxed in previous versions of the .NET Framework. This release of the .NET Framework
does not enable CAS policy by default, so this load may be dangerous. If this load is not
intended to sandbox the assembly, please enable the loadFromRemoteSources switch.
See http://go.microsoft.com/fwlink/?LinkId=155569 
for more information.
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName,
 String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, 
StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection,
Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, 
Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, 
 Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, 
Evidence assemblySecurity, StackCrawlMark& stackMark, 
Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, 
Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, 
Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at Microsoft.Silverlight.Build.Tasks.ValidateXaml.XamlValidator.Execute(ITask task)
   at Microsoft.Silverlight.Build.Tasks.ValidateXaml.XamlValidator.Execute(ITask task)
   at Microsoft.Silverlight.Build.Tasks.ValidateXaml.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.
Execute()

Solution

Just right click on that assembly and click on Unblock button in bottom right of the dialog box. That should take care of this error.

Give your advice to big bosses and make money

Views: 1030

Tags:

.Net | Silverlight

How to programatically set meta tags on ASP.Net page

by Viper 5. November 2009 06:19

When we are creating a web site, one of the main goal we all have is that out site should be listed on first page of search engines like Google, Bing, Yahoo, Baidu etc. As we all know that in SEO world, one of the first thing we all look for in the page is meta tags in header of the page. In the past there was no direct way to set the meta tags on a page programatically when developing ASP.Net web site. We all used the work around of adding metaelements in header element of the page. You can read my previous post Adding meta tags to asp.net page dynamically about that technique. With ASP.Net 4.0 microsoft has introduced following two properties on that allow you to set the meta tags on a page.

  • MetaDescription
  • MetaKeywords

Following code snippet shows how it is used in your code.


public partial class _Default : System.Web.UI.Page
{
 protected void Page_Load(object sender, EventArgs e)
 {
  SetMetaTags();
 }
 private void SetMetaTags()
 {
  Title = "Hello Meta";
  MetaDescription = "This is description of my ASP.Net 4.0 page.";
  MetaKeywords = "ASP.Net,.Net4.0,Meta";
 }
}

And it works. You can see from the source of the page as shown below.

<head>
<title>Hello Meta</title>
<meta name="description" content="This is description of my ASP.Net 4.0 page." />
<meta name="keywords" content="ASP.Net,.Net4.0,Meta" />
</head>
Give your advice to big bosses and make money

Views: 1200

Tags:

.Net | ASP.Net

How to use jQuery to make AJAX requests in ASP.Net?

by Viper 20. July 2009 15:06

Download Sample Project

For one of my current project, I have been using ASP.Net AJAX to make async request into my ASP.Net to get some time related data. First, I am not a big fab of ASP.Net AJAX implementation. I will not go into debate on why. There are plenty of discussions on this topic. I will just spare myself from it. Second, the application was already using jQuery for other javascript related implementation. I was like, if we are already using jQuery why have an overhead of introducing Ajax tool kit. So I started porting the implementation to use jQuery. Through this series of posts, I will describe how you can use jQuery to make AJAX calls in ASP.Net applications. Well, the client side javascript can be used in any browser. So other than the server side implementation, there is no nothing specific to ASP.Net per se.

The sample project for these articles is a time synchronization service. The idea is that I want to display clock on the client machine that will display server time. Well you can say there is no big deal with that implementation. On page load, get the server time. Save in some client side variable and run one second timer on it. Well, that works for most part. There are situations where clients are behind really slow connections that can cause of lot latency in request and response. So in those cases, by the time your response gets to the client side, the server time that you returned to client is already behind by few seconds. For applications that has users who depend very heavily on this server time, this latency of few seconds can be very critical. In this first post I am not going to go into details of algorithm that I implemented to reduce this latency adjustment over time. This first sample does a very simple task. It sends asynchronous request to server every 10 seconds. The server returns its time and then client uses that to display clock.

Server Side Implementation

I have a class ClockData that has DataContract attribute set on it. You can pretty much figure out that I am planning on converting this service to WCF service and use the framework facilities to serialize and de-serialize data as well. So I am populating this class with three pieces of data (server time, latency and a cookie) and then using DataContractJsonSerializer class to serialize the data into JSON format and sending it to client.


private void SerializeServerClockData(ClockData data, Stream strm)
{
 var spSer =
   new DataContractJsonSerializer(typeof(ClockData));
 spSer.WriteObject(strm, data);
}

void SendResponse()
{
 long ms = (long)(_serverTime - new DateTime(1970, 1, 1)).TotalMilliseconds;
 var clockData = new ClockData()
  {ServerTime = ms.ToString(), Latency = _latency, ResponseKey = Guid.NewGuid().ToString("N")};
 Response.ContentType = "text/plain";
 Response.Expires = -1;
 Response.CacheControl = "no-cache";
 SerializeServerClockData(clockData, Response.OutputStream);
 Response.End();
}

From the code snippet above, you can see how plain and simple server side implementation is for this first sample. This will get little complicated as I get more into the actual algorithm of calculation of latency reduction.

Client Side Implementation

Since we are going to be using jQuery to make Ajax call, so we will need to include reference to jQuery javascript file. For this sample, I am going to show the AJAX request you can send using jQuery. The library has method named .getJSON that you can call to send the request. You can set the URL where request is to be sent, set the parameters that needs to be passed with request and set the callback function that should be called when request completes. It is that simple. Here is the implementation from the sample.


function getServerTime() {
 cTime = firstRequest ? -1 : curTime.getTime();
 $.getJSON(clockServiceUrl, { clientTime: cTime, requestKey: respKey }, gotServerTime);
}

function gotServerTime(data) {
 firstRequest = false;
 latency = data.Latency;
 curTime = new Date(parseInt(data.ServerTime));
 if (!clockTicking) createClockTimer();
 createServiceTimer(defaultServiceTimer);
}

function clockTick() {
 clockTicking = true;
 curTime.setTime(curTime.getTime() + 1000);
 elClockDisplay.text(curTime.toString());
 if (latency == -1)
 { elLatencyDisplay.text(""); }
 else
 {elLatencyDisplay.text(latency + " ms");}
}

$(function() {
 elClockDisplay = $('#clockDisplay');
 elLatencyDisplay = $('#latencyDisplay');
 getServerTime();
});

In subsequent posts I will discuss how you can control the request little bit more instead of using .getJSON to use default settings.

Give your advice to big bosses and make money

Views: 1069

Tags: , ,

.Net | ASP.Net | JQuery | AJAX

How to format and modify value in data grid row at run time based on previous row values

by Viper 7. July 2009 14:35
grid view row formatting

Download Sample Project

This was a question was asked by one of my site visitors, Mike. Following is the text of the question:

This is a similar question to one you have already answered in formatting Grid Views. However there are 2 main differences. First: I want to change the value of a column (not the format) in any row if the row preceding it has a certain value in the same column.

This question translates to How do you change value of a data grid column based on values of previous row(s). I generalized this question to cover all previous rows and not just the preceding row. Answer to all such questions relies on handling events like RowDataBound or RowCreated events. When a data grid or grid view renders, RowDataBound fires when row is being data bound and then RowCreated is fired after it has been data bound and row has been created. So depending on at what stage of rendering you want to change behavior of a row, you will subscribe either of these events. In the sample project, I am subscribing to RowDataBound event.

Next step is to access values from previous rows. Here you have choice. One, you can keep some local vaiable that stores values from previous row(s) and then use them in current row event handling. Two, you can access the previous GridRow based on index. In this sample i will discuss the approach of accessing previous row based on index and then extracting values from certain cells.

In RowDataBound event handler, GridViewRowEventArgs provides you access to DataItem associated with current row only. You do not have access to DataItem associated with previous rows. But at this point, previous rows have been prepared for rendering. You have access to all the cell values associated with previous row. You can access GridRow object of previous rows and extract text from cells that you are interested in. In the sample project, I am accessing ListPrice from fourth column and then displaying it in current row along with price associated with current row. Well, this does not sound like something that is very interesting or useful. But it serves the purpose of demonstrating you will accomplish the task.

Here is the code snippet from sample project.


protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
 if (e.Row.RowType == DataControlRowType.DataRow)
 {
  double price = -1.0;
  double prevPrice = -1.0 ;
  // Access the previous row.
  if (e.Row.RowIndex != 0)
  {
   GridViewRow prevRow = this.productsGrid.Rows[e.Row.RowIndex - 1];
   if (null != prevRow && 
    prevRow.RowType == DataControlRowType.DataRow)
   {
    double.TryParse(prevRow.Cells[3].Text, out prevPrice);
   }
  }
  var thisRowData = e.Row.DataItem as DataRowView;
  if (!Convert.IsDBNull(thisRowData["ListPrice"]))
  {
   double.TryParse(thisRowData["ListPrice"].ToString(), out price);
  }
  var ctrl = e.Row.FindControl("prevPriceLabel") as Label;
  if (null != ctrl)
  {
   ctrl.Text = string.Format("{0} - {1}", prevPrice, price);
  }
 }
}

The attached sample project is a VS2010 project. There is no VS2010 or .Net4.0 implementation in the project. So if you are using VS2008 or prior, you should be able to copy the implementation files into your own project.

Feel free to send me any request for any other grid view implementation you would like to be answered or implemented.

Give your advice to big bosses and make money

Views: 2163

Tags: , ,

.Net | ASP.Net | C# | DataGrid

Bayesian Spam Filter Trainer

by Viper 20. June 2009 20:11

Download SpamTrainer Binaries

Download SpamTrainer Source

As more and more people are tweeting, spam is growing with it as well. Every time I search for some topic, almost half of the messages seem to fall in one of the following categories:

  • Somebody is trying to sell something
  • Somebody is posting links to get you affiliate web sites to make some money
  • Job agencies are posting jobs
  • .... and more

This week I decided to use Bayesian spam filter, that is used in most email servers to filter spam, on twitter messages. While searching around I found Bayesian Spam Filter for C#. That gave a good starting point. Without making any changes or training with any additional corpus, I was able to get very good filtering results. I observed close to 90% spam detection. I studied the messages that fell through the cracks and also studies false positives. Based on the observations I figured that issue is very limited context of 140 characters in twitter. A lot of good and spam twitter messages look pretty much the same. So the key to improving spam filtering results was to train the filter with twitter messages and not use just rely on corpus taken from emails or things like that. So I decided to build an application that I could use to generate corpus that is classified as spam and good twitter messages.

How does it work

  • Start the application.

  • Enter a search term and click on "More Data" button.
  • Application will do initial classification of messages. All spam messages are displayed in Orange or light blue color.
  • Double on any message to change its classification.

  • Once you are satisfied with the results, click on "Accept" button and results are saved in appropriate good and spam files.
  • You can load the new corpus results by clicking on "Reload Corpus".

Spam Filter Service

I have created a service that you can use to classify your text if you do not want to build one of your own. Following link provides more details about the service.

Spam Filter Service

Give your advice to big bosses and make money

Views: 1223

Tags: , , ,

.Net | Twitter

How to download image from a web site programatically using HttpWebRequest

by Viper 16. June 2009 19:15

I am working on adding new features to Marketweet - Twitter Autofollow application. The new feature will show some details about followers of an account. And one of the details is showing image associated with user's profile. To get that to work, I have developed an image service that downloads the user images in the background. This is done using HttpWebRequest object to send request to image URL that is set as user's profile image. Following code shows you how you can download an image from a web site programatically using HttpWebRequest. Also notice how ContentType property of HttpWebResponse is utilized to make sure that response from the specified URL is of type type/xxxx.


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace ConsoleApplication1
{
 class Program
 {
  static void Main(string[] args)
  {
   DownloadImage(113467, 
   @"http://s3.amazonaws.com/twitter_production/profile_images/214863919/logo_normal.jpg");
  }
  static void DownloadImage(int userId, string url)
  {
   HttpWebRequest webRequest = HttpWebRequest.Create(url) as HttpWebRequest;
   HttpWebResponse resp = webRequest.GetResponse() as HttpWebResponse;
   if(resp.StatusCode == HttpStatusCode.OK)
   {
    if (resp.ContentType.Contains("image/"))
    {
     int idx = resp.ContentType.IndexOf("/");
     string fileName = string.Format("{0}.{1}", 
        userId, resp.ContentType.Substring(idx + 1));
     byte[] imageContent = ProcessImageStream(resp);
     FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
     fs.Write(imageContent, 0, imageContent.Length);
     fs.Close();
    }
   }
 }
private static byte[] ProcessImageStream(HttpWebResponse resp)
{
 Int64 iContentLength = resp.ContentLength;
 byte[] streamContent;
 MemoryStream memStream = new MemoryStream();
 const int BUFFER_SIZE = 4096;
 int iRead = 0;
 int idx = 0;
 Int64 iSize = 0;
 memStream.SetLength(BUFFER_SIZE);
 try
 {
  using (memStream)
  {
   while (true)
   {
    iRead = 0;
    byte[] respBuffer = new byte[BUFFER_SIZE];
    iRead = resp.GetResponseStream().Read(respBuffer, 0, BUFFER_SIZE);
    if (iRead == 0)
    {break;}
    iSize += iRead;
    memStream.SetLength(iSize);
    memStream.Write(respBuffer, 0, iRead);
    idx += iRead;
   }
   streamContent = memStream.ToArray();
  }
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.Message);
  throw;
 }
 return streamContent;
 }
}
}

Discussion

After this entry was posted, Mark pointed out in his comment that it could be achieved in 2 lines of code. I will post those two lines of code here.


Dim r As New System.Net.WebClient  
r.DownloadFile("http://http://aspnetlibrary.com/images/logo.png", 
 "c:\aspnetlibrary.png")

This approach works perfectly fine if both variables in this method signature are very well known. What this means is that you know that target URL is what it says (that I am an image file of type PNG). Here are some issues that you have to think about when you are building a solution that involves downloading of files (image, multimedia or any kind).

  • Lets start with evil that is lurking around these days called Tiny URLs. These started with some good intent but now these have become medium to disguise spam, tricking people into clicking on links that are click advertising, redirecting to questionable sites, key loggers. So if the image URL is like http://tinyurl.com/45fghty, you don't even know what it is. So you really don't know what to save this file as.
  • If you don't know what mime type actually is associated with file that is being downloaded.

What you have to rely on is headers that are associated with response. You can see from code snippet how header information is utilized to establish file type and create file name on the fly.

Give your advice to big bosses and make money

Views: 3294

Tags:

.Net | C#

Amazon Web Service Secure Request

by Viper 15. June 2009 13:41

Some time back I wrote a post on C# API for Amazon Product Advertising Web Service. If you are one of amazon associates who is using their web service to advertise their products to earn some money, then you must be getting emails with following message from Amazon.com.

We wanted to remind you that all Product Advertising API developers will be required to authenticate all calls to the Product Advertising API by August 15, 2009. We noticed that requests with your AWS Access Key ID are not being signed and, while you have more than 60 days until the date on which authentication is required, we are, as a courtesy, sending you this email to remind you of the new authentication requirement. Please remember that calls to the Product Advertising API that are not signed will not be processed after August 15, 2009.

There is nothing to worry about this. It is a very simple change that you will need to make on your end. Amazon has given two options to digitally sign the requests. Either encrypt all requests with HMAC-SHA encryption or use X509Certificate. If you don't have X509Certificate, don't worry about it. Amazon.com is creating one for you if you ask it to. I found this option to use X509Certificate to be the easiest to comply with Amazon.com policy. Here are the steps you will need to use.

  • Login into your AWS account.
  • Click on Access Identifiers link on Your Account page.
  • At the end of the page you will find section for X509.Certificate. Click on Create New option to create your certificate.
  • Make sure that you follow the instructions and save the private key and certificate file as the process asks you to.

Now time to make code change. It is simple. Just add one line to your implementation and you are all set.


m_obAmazonService.ClientCertificates.Add(X509Certificate.CreateFromCertFile(X509CertFile));

X509CertFile is full path to where this file is stored. If you are using the API in web application, make sure you specify fully qualified path and your application has read permissions on this file as well. You can this in action here - Winazon.Net

Give your advice to big bosses and make money

Views: 18384

Tags: ,

.Net

How to round off number to 0 or next 0.5

by Viper 12. June 2009 08:31

While working on a clock synchronization service, I had to dig up an old piece of code that I used to round off numbers. For this application I need to round the number to 0 or next 0.5 depending on it proximity to edge. For example if number is 8.001, it gets rounded off to 8.0 and if it is 8.6123 it will be rounded to 8.5. You can argue why not 9 instead of 8.5. Well the logic of the application demands that number is to be rounded down. Here is simple piece of code that will do the trick.


double roundDownNumber = Math.Round(actualNumber * 2.0, 0) / 2.0;

Just simple idea that multiply the number by 2 and round it to ZERO decimal places and then divide by 2.

Give your advice to big bosses and make money

Views: 1143

Tags: , ,

.Net | C#

How to group records using LINQ

by Viper 9. June 2009 04:58

While developing Twitter applications, one of the common patterns that used to emerge is that some particular users will post lot of messages in a short time span. And when searching records, I used to end up with multiple messages from one particular user. So for some user interface, I always had to group messages by user posting the message.

Following code shows how easy it is to group records using LINQ. Just to explain the code a little bit, when search is performed for a certain query term using twitter rest api with Tweetsharp, results are returned as list of TwitterSearchStatus objects. The user who posted the message is indicated by FromScreenName property. So this property becomes the key on which grouping is to be performed. Following group statement shows how grouping is done in LINQ statement.

 var resultsGrpByUser = from searchResult in searchResults
   group searchResult by searchResult.FromUserScreenName
   into userMessages
 select new { FromUser = userMessages.Key, Messages = userMessages };

Above code uses group statement to create group on user name, and the grouping results are returned as Dictionary of anonymous objects that have properties named FromUser and Messages. Following code snippet shows the whole implementation of grouping using LINQ.


static Dictionary<string, List<TwitterSearchStatus>> GetPopularTweets()
{
 List<TwitterSearchTrend> trends = GetDailyTrends();
 if (null == trends ||
     trends.Count == 0)
 {
  return null;
 }
 // For now only process first trend term.
 List<TwitterSearchStatus> searchResults = SearchForTerm(trends[0].Query);
 if (searchResults.Count == 0)
 {
  return null;
 }
 var resultsGrpByUser = from searchResult in searchResults
   group searchResult by searchResult.FromUserScreenName
   into userMessages
 select new { FromUser = userMessages.Key, Messages = userMessages };
 Dictionary<string, List<TwitterSearchStatus>> dict = 
  new Dictionary<string, List<TwitterSearchStatus>>();
 foreach(var userMessage in resultsGrpByUser)
 {
  Console.WriteLine(userMessage.FromUser);
  foreach(var twitterStatus in userMessage.Messages)
  {
   Console.WriteLine("\t{0}", twitterStatus.Text);
  }
  dict[userMessage.FromUser] = userMessage.Messages.ToList();
  Console.WriteLine("*************");
 }
 return dict;
}

Give your advice to big bosses and make money

Views: 2171

Tags:

.Net | C# | LINQ

How to get popular tweets from twitter

by Viper 9. June 2009 04:34

In my earlier posts Daily twitter trends and Weekly twitter trends I showed how you can get daily and weekly twitter trends. That api gets you to queries that are being searched for. Next step in the process is to take those queries and get the messages posted related to those queries. Here is a simple method that combines results of trend api with search api to get popular messages on twitter.


static Dictionary<string, List<TwitterSearchStatus>> GetPopularTweets()
{
 List<TwitterSearchTrend> trends = GetDailyTrends();
 if (null == trends ||
     trends.Count == 0)
 {
  return null;
 }
 // For now only process first trend term.
 List<TwitterSearchStatus> searchResults = SearchForTerm(trends[0].Query);
 if (searchResults.Count == 0)
 {
  return null;
 }
 var resultsGrpByUser = from searchResult in searchResults
   group searchResult by searchResult.FromUserScreenName
   into userMessages
 select new { FromUser = userMessages.Key, Messages = userMessages };
 Dictionary<string, List<TwitterSearchStatus>> dict = 
  new Dictionary<string, List<TwitterSearchStatus>>();
 foreach(var userMessage in resultsGrpByUser)
 {
  Console.WriteLine(userMessage.FromUser);
  foreach(var twitterStatus in userMessage.Messages)
  {
   Console.WriteLine("\t{0}", twitterStatus.Text);
  }
  dict[userMessage.FromUser] = userMessage.Messages.ToList();
  Console.WriteLine("*************");
 }
 return dict;
}

Give your advice to big bosses and make money

Views: 1644

Tags: ,

.Net | Twitter

How to verify twitter login credentials

by Viper 5. June 2009 04:53

As more and more have started to integrate Twitter API into the applications and allowing user to post messages and do other twitter related tasks, one of the essential step in the work flow is to verify a user's twitter credentials. There are certain tasks you can perform without logging into API. But when it comes to posting messages or pulling a user's data etc., Twitter API wants the user to be authenticated. Here is a code snippet that shows how you can use Twitter API to verify a user's credentials or verify user's login information.


static TwitterUser VerifyTwitterCredentials(string login, string password)
{
 IFluentTwitter ft = FluentTwitter.CreateRequest();
 ft.AuthenticateAs(login, password);
 ft.Accounts().VerifyCredentials().AsJson();
 var resp = ft.Request();
 TwitterUser tUser = resp.AsUser();
 if (null == tUser)
 {
  var err = resp.AsError();
  Console.WriteLine("Twiiter Error: " + err.ErrorMessage);
 }
 return tUser;
}

When verification fails, you will get a response that will not get converted to TwitterUser object and method will return null object.

Give your advice to big bosses and make money

Views: 3280

Tags: , ,

C# | .Net | C# | VB.Net | VB.Net

How to decode tinyurl

by Viper 3. June 2009 14:34

These days Twitter is the thing to do for lot of people. And lot of folks have found ways to leverage this microbloging site to promote things like product sales, real estate etc. Since twitter only allows 140 characters to post a message, pasting a regular URL could take pretty much all the characters and some times the URLs are so big that even 140 characters are not enough. This has made use of TinuUrl and services like this very popular. When you click on one of these tiny urls, you land on real URL behind it. While working on Backyard Tweets application, I had the requirement to actually translate these compressed or shortened URLs into real long urls. The concept behind these tiny urls is very simple. When you submit your actual long url to one of these services, they encode the url and create a compressed version of url and return it to you. When user clicks on this url, the request goes to this url service. Then this service decodes this encoded url back to actual url and send a HTTP status code of 301 to the caller. This code means that the requested resource has been permanently moved to some other location. And this so called other location is the actual url. The value of this other url is set in Location header of HTTP response. You can see all this in following C# code snippet that I used to write a tiny console application.


namespace ConsoleApplication1
{
 class Program
 {
  static void Main(string[] args)
  {
   string tinyUrl = "http://ow.ly/atLJ";
   var longUrl = DecodeShortUrl(tinyUrl);
   Console.WriteLine("{0} -> {1}", tinyUrl, longUrl);
  }

  static string DecodeShortUrl(string shortUrl)
  {
   HttpWebRequest webReq = HttpWebRequest.Create(shortUrl) as HttpWebRequest;
   webReq.AllowAutoRedirect = false;
   HttpWebResponse webResponse = webReq.GetResponse() as HttpWebResponse;
   if (webResponse.StatusCode == HttpStatusCode.MovedPermanently)
   {
    return webResponse.Headers["Location"];
   }
   return shortUrl;
}
	}
}

Now only thing you need in your real application is a regular expression to extract these compressed urls and feed it to this tiny method and get back your actual url behind it. The most important part of this code is setting of AllowAutoRedirect property of HttpWebRequest. If you do not set it, the request will get redirected to actual url.

Give your advice to big bosses and make money

Views: 3156

Tags:

.Net

Convert IP Address To Location and Address to Geo Location Using C# VB.Net

by Viper 1. June 2009 19:10

Recently I implemented BackYardTweets. Big part of the site is geo targeting. What that means is that to figure out location of the user visiting the site and getting longitude and latitude of that location. The implementation uses the following work flow:

  • When user visits the site, only information that is available is IP adress assigned to your network connection by user's internet service provider. The implementation translates that IP address to location including coordinates (longitude and latitude).
  • After user has logged in, application allows user to change location. User can pick country, region and city. From these three (some time only 2), application determines geolocation.

Now I will explain how these two steps are performed.

Convert IP Address To Geo Location

Application uses IP to geo location service provided by IP Location tools. A simple HTTP request to this site's target URL sends xml response that containss all the data that you will need to get location of site's visitor. Following is sample response.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
 <Ip>74.125.45.100</Ip>
 <Status>OK</Status>
 <CountryCode>US</CountryCode>
 <CountryName>United States</CountryName>
 <RegionCode>06</RegionCode>
 <RegionName>California</RegionName>
 <City>Mountain View</City>
 <ZipPostalCode>94043</ZipPostalCode>
 <Latitude>37.4192</Latitude>
 <Longitude>-122.057</Longitude>
</Response>

Following code snippet shows the implementation that was done in the application to get geo location based on IP address of site visitor.


public class UserGeoLocator
{
 private const string ApiUrl = "http://ipinfodb.com/ip_query.php?ip={0}";
 public SiteUser GetUserLocation(string ipAddress)
 {
 if (string.IsNullOrEmpty(ipAddress))
 {
  return null;
 }
 string reqUrl = string.Format(ApiUrl, ipAddress);
 HttpWebRequest httpReq = HttpWebRequest.Create(reqUrl) as HttpWebRequest;
 try
 {
  string result = string.Empty;
  HttpWebResponse response = httpReq.GetResponse() as HttpWebResponse;
  using (var reader = new StreamReader(response.GetResponseStream()))
  {
   result = reader.ReadToEnd();
  }
  return ProcessResponse(result);
 }
 catch (Exception ex)
 {
  throw;
 }
}

private SiteUser ProcessResponse(string strResp)
{
 StringReader sr = new StringReader(strResp);
 XElement respElement = XElement.Load(sr);
 string callStatus = (string)respElement.Element("Status");
 if (string.Compare(callStatus, "OK", true) != 0)
 {
  return null;
 }
 SiteUser user = new SiteUser() {IP = (string) respElement.Element("Ip"), 
 City = (string) respElement.Element("City"),
 Country =  (string)respElement.Element("CountryName"),
 CountryCode = (string)respElement.Element("CountryCode"),
 RegionCode =  (string)respElement.Element("RegionCode"),
 RegionName = (string)respElement.Element("RegionName"),
 PostalCode =  (string)respElement.Element("ZipPostalCode"),
 Latitude = (decimal)respElement.Element("Latitude"),
 Longitude = (decimal)respElement.Element("Longitude")};
 return user;
 }
}

Geo Location From Address

Application allows user to select Country, Region and City. This needs to be translated to geo location. Application uses Google's Map API to accomplish the task. For this you will need to apply for key from Google. Following code snippet is from the application. It takes address of user as input and translates it to latitude and latitude. Following code snippet is from class implemented in the application.


public static bool GetGeoLocationFromGoogle(string nearLocation, 
                      out double longitude, out double latitude)
{
 bool ret = false;
 longitude = latitude = 0d;
 string apiKey = ConfigHelper.GooleMapKey;
 string reqUrl = string.Format("http://maps.google.com/maps/geo?q={0}&output={1}&key={2}",
			  HttpUtility.UrlEncode(nearLocation), "csv", apiKey);
 WebClient httpClient = new WebClient();
 try
 {
  string response = httpClient.DownloadString(reqUrl);
  string[] values = response.Split(",".ToCharArray());
  if (values.Length == 4)
  {
   if (values[0] == "200")
   {
    latitude = double.Parse(values[2]);
    longitude = double.Parse(values[3]);
    ret = true;
   }
  }
}
catch (Exception ex)
{
 Trace.WriteLine(ex.Message);
}
return ret;
}

See how it works

Use see all this in action at following link


Give your advice to big bosses and make money

Views: 14553

Tags: ,

.Net | Google | Twitter

Powered by BlogEngine.NET 1.5.1.7
Theme by Naveen Kohli

By Categories