Tuesday, July 8, 2014

Create WCF Service in class project - Part 2

Once the service is hosted service can be called using Ajax call.

 function RedirectHyperlink(link) {  
   var base_url = "http://" + window.location.host + "/RedirectService.svc/RedirectHyperlink";  
   var NewLink = "http://" + window.location.host + link;  
   var value = $('#hfVal').val();  
   var data = '{"url":"' + link + '","id":"' + value + '"}';  
   $.ajax({  
     cache: false,  
     url: base_url,  
     type: "POST",  
     async: false,  
     data: data,  
     success: function (data, textStatus, jqXHR) {  
       window.location.href = NewLink;  
     },  
     error: function (xhr, status, error) {  
     }  
   });  
 }  

In here I created base_url for service call. this will always create correct path for service. (other wise if your page is located inside a folder then url can be differ.


In service return type is System.ServiceModel.Channels.Message then it need to change as follows:

   [ServiceContract(SessionMode = SessionMode.Allowed)]  
   public interface IBusinessLogicService   
   {  
     [OperationContract]  
     [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "{CurrentURL}/{stateId}/RenderBusinessLogic")]  
     System.ServiceModel.Channels.Message RenderBusinessLogic(string CurrentURL, string Id);  
   }  

Class implementation as follows:

   [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
   [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
   public class BusinessLogicService : IBusinessLogicService , IStateContext  
   {  
     public System.ServiceModel.Channels.Message RenderBusinessLogic(string CurrentURL, string Id)  
     {  
       try  
       {  
         if (HttpContext.Current.User.Identity.IsAuthenticated)  
         {  
           //Get state ID  
           string datasetInJsonString = // Add what ever you want  
           return H2JSONServiceHelper.JsonStringToMessage(datasetInJsonString);  
         }  
       }  
       catch (Exception ex)  
       {  
         LogManagerOnServer.HandleException(new H2ServerException(ex.Message) { ClientMessage = "Error in RenderBusinessLogic.", PageName = "H2ReactBusinessLogicService.cs" });  
       }  
       return null;  
     }  
     public static System.ServiceModel.Channels.Message JsonStringToMessage(string jsonString)  
     {  
       //transform the string to stream  
       MemoryStream memoryStream = new MemoryStream(new UTF8Encoding().GetBytes(jsonString));  
       //Set position to 0  
       memoryStream.Position = 0;  
       //return Message  
       return WebOperationContext.Current.CreateStreamResponse(memoryStream, "application/json");  
     }  
   }  

If we browse this service in browser we can't see publish version and it display error. To avoid that it needs to add
 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
to class coding.

even though you can call service as follows:


     var ID =GetStateID();   
     var url = GetUrl();  
     var obj = {};  
     // Call the service method to get the json based business logic  
     var base_url = 'BusinessLogicService.svc/' + url + "/" + ID + "/RenderBusinessLogic";  
     debugger;  
     $.ajax({  
       cache: false,  
       url: base_url,  
       type: "GET",  
       async: false,        
       data: obj,  
       contentType: "application/json",  
       success: function (data, textStatus, jqXHR) {   
         // debugger;  
           },  
       error: function (xhr, status, error) {  
         debugger;  
       }  
     });  




Monday, June 2, 2014

Create WCF Service in class project - Part 1

In normal scenario when we need to host service we add separate WCF project to the solution. My Solution architecture is as follows:

In this scenario I need to add WCF service to the Business Layer and I need to host that service when web application is hosted (self hosted).

So I used following steps to implement above scenario.
  • Added Interface to Business Layer.
  [ServiceContract]  
   public interface IRedirectService  
   {   
     [OperationContract]  
     [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "RedirectHyperlink")]  
     void RedirectHyperlink(System.IO.Stream jsonString);       
   }  

  • Added Class to Business Layer  as follows and write the implementation.
   [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
   public class RedirectService : IRedirectService  
   {  
     public void RedirectHyperlink(System.IO.Stream jsonString)  
     {  
       string val = JsonSteamToString(jsonString);  
       string JsonVal = val.Replace("\"", "'");  
       var json_serializer = new JavaScriptSerializer();  
       TestJsonStateObject myobj = json_serializer.Deserialize<H2JsonStateObject>(JsonVal);  
      
     }  
     public string JsonSteamToString(Stream jsonStream)  
     {  
       StreamReader reader = new StreamReader(jsonStream);  
       return reader.ReadToEnd();  
     }     
   }  
In this method jsonString contain string value of object. In order to deserialize the object I have used JavaScriptSerializer class. It can be found in System.Web.Script.Serialization namespace.

 using System.Web.Script.Serialization;  
after deserialize it can be conver into object which you have declared.

  public class TestJsonStateObject  
   {  
     public string url { get; set; }  
     public string Id { get; set; }  
   }  

  • Modify Web application Web.config file in order to communicate with wcf service.
  <system.serviceModel>  
   <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">  
    <serviceActivations>  
     <add factory="System.ServiceModel.Activation.ServiceHostFactory" relativeAddress="./RedirectService.svc" service="BusinessLayerProjectName.RedirectService" />  
    </serviceActivations>     
   </serviceHostingEnvironment>  
   <services>  
    <service behaviorConfiguration="ServiceBehaviour" name="BusinessLayerProjectName.RedirectService">  
     <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="BusinessLayerProjectName.IRedirectService" />  
    </service>  
   </services>  
   <behaviors>  
    <endpointBehaviors>  
     <behavior name="web">  
      <webHttp />  
     </behavior>  
    </endpointBehaviors>  
    <serviceBehaviors>  
     <behavior name="ServiceBehaviour">  
      <serviceMetadata httpGetEnabled="true" />  
      <serviceDebug includeExceptionDetailInFaults="true" />  
     </behavior>  
    </serviceBehaviors>  
   </behaviors>  
  </system.serviceModel>  

then once you hosted your site you can see hosted wcf service by providing correct URL.

 http://localhost:50594/RedirectService.svc  



Friday, September 13, 2013

Create Wix installer for Windows Service

In this article I'm going to discuss create wix installer for windows service. in this scenario i considered about following situation.
  • Attach Exe with App.config
  • Attach external dll
  • Modify App.config values based on installed location.
for this you can use either visual studio editor or Wix Editor. 
 <?xml version="1.0" encoding="utf-8"?>  
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">  
   <Product Id="5AC767F2-4F21-45DF-9DAB-C013C62B2B67" Name="Installer" Language="1033" Version="1.0.0.0" Manufacturer="TRT " UpgradeCode="3fd83540-23f6-45f4-bb1c-e77c12725680">  
     <Package InstallerVersion="200" Compressed="yes" />  
     <Media Id="1" Cabinet="SampleApp.cab" EmbedCab="yes" />  
     <Directory Id="TARGETDIR" Name="SourceDir">  
       <Directory Id="ProgramFilesFolder">  
         <Directory Id="INSTALLFOLDER" Name="Installer">  
           <Directory Id="TestService" Name="TestService">  
             <Component Id="MainExecutable" Guid="CE30D5D8-3211-4890-A9DC-0C315C15B39E">  
               <File Id="testServiceexe" Name="TestInstallerProject.exe" DiskId="1" KeyPath="yes" Source="..\TestInstallerProject\bin\Debug\TestInstallerProject.exe" />  
               <File Id="TestInstallerProject.exe.config" Name="TestInstallerProject.exe.config" Source="..\TestInstallerProject\App.config" Vital="yes" DiskId="1" />  
               <File Id="GOOGLE.GDATA.ANALYTICS.DLL" Name="Google.GData.Analytics.dll" Source="..\TestInstallerProject\bin\Debug\Google.GData.Analytics.dll" />  
               <File Id="GOOGLE.GDATA.CLIENT.DLL" Name="Google.GData.Client.dll" Source="..\TestInstallerProject\bin\Debug\Google.GData.Client.dll" />  
               <ServiceInstall Name="ScheduledService" Type="ownProcess" Start="auto" ErrorControl="ignore" Id="ServiceInstaller" DisplayName="ScheduledService" Account="[SERVICEACCOUNT]" Password="[SERVICEACCOUNTPASSWORD]">  
                 <util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" ResetPeriodInDays="1" RestartServiceDelayInSeconds="1" />  
               </ServiceInstall>  
               <ServiceControl Id="StartService" Name="ScheduledService" Start="install" Stop="both" Remove="uninstall" Wait="no" />  
               <RemoveFolder Id="INSTALLDIR" On="uninstall" />  
               <util:XmlFile Id="ModifyServiceLocation" ElementPath="//configuration/appSettings/add[\[]@key='TextLocation'[\]]/@value" File="[TestService]\TestInstallerProject.exe.config" Action="setValue" Value="[TestService]ScheduledServiceNew.txt" PreserveModifiedDate="yes" SelectionLanguage="XPath" Sequence="1" />  
             </Component>  
           </Directory>  
         </Directory>  
       </Directory>  
     </Directory>  
     <Feature Id="Complete" Title="Installer" Level="1">  
       <ComponentRef Id="MainExecutable" />  
     </Feature>  
     <UI>  
     </UI>  
   </Product>  
 </Wix>  

when attache app.config, you have to consider about name and the id of the config. it should be the name of the exe.

 <File Id="TestInstallerProject.exe.config" Name="TestInstallerProject.exe.config" Source="..\TestInstallerProject\App.config" Vital="yes" DiskId="1" />  

for modify the App.config have to use util:XmlFile tag. in here my app.config file is something like this.

 <?xml version="1.0" encoding="utf-8" ?>  
 <configuration>  
  <appSettings>  
   <add key="TextLocation" value="d:\ScheduledServiceNew.txt"/>  
  </appSettings>  
 </configuration>  
I want to update it into something like this:

 <?xml version="1.0" encoding="utf-8"?>  
 <configuration>  
  <appSettings>  
   <add key="TextLocation" value="C:\Program Files (x86)\Installer\TestService\ScheduledServiceNew.txt"/>  
  </appSettings>  
 </configuration>  

for that i have to use  util:XmlFile tag as follows:
 <util:XmlFile Id="ModifyServiceLocation" ElementPath="//configuration/appSettings/add[\[]@key='TextLocation'[\]]/@value" File="[TestService]\TestInstallerProject.exe.config" Action="setValue" Value="[TestService]ScheduledServiceNew.txt" PreserveModifiedDate="yes" SelectionLanguage="XPath" Sequence="1" />  

once you compile the project you can create installer using wix for windows service

Sunday, April 28, 2013

Read And Write data in MVC using n tier architecture

In this scenario we discuss how we can do CRUD operations in MVC using n tier architecture. in this lesson i'm going to assume that reader must have basic knowledge of MVC framework and how it works.

 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>  
 <!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></title>  
    <script type="text/javascript" src="../../Scripts/jquery-1.5.1.min.js"></script>  
 </head>  
 <body>  
   <div>  
     <%: Html.ActionLink("Create full time student", "CreatefullStudent")%><br>  
     <%: Html.ActionLink("Create part time student", "CreatepartStudent")%>  
     <br />  
     <input type="button" value="Get student" id="btnstudent" />  
     <div id="studentlist"></div>  
   </div>  
 </body>  
 </html>  
 <script type="text/javascript">  
   $(document).ready(function () {  
     $("#btnstudent").click(function () { GetStudent(); });  
     GetStudent();  
   });  
   function GetStudent() {  
     $.ajax({  
       url: "Home/GetStudentList",  
       type: 'GET',  
       contentType: 'application/json; charset=utf-8',  
       dataType: 'json',  
       success: function (result) {  
         alert("test");  
         if (result.length == 0) {  
           $("#studentlist").html("No details available");  
         } else {  
           var str = "<table><thead><tr><td>Id</td><td>Name</td></tr></thead><tbody>"  
           for (var i = 0; i < result.length; i++) {  
             str += "<tr>";  
             str += "<td>" + result[i].Id + "</td>";  
             str += "<td>" + result[i].Name + "</td>";  
             str += "</tr>";  
           }  
           str += "</tbody></table>"  
           $("#studentlist").html(str);  
         }  
       }  
     });  
   }  
 </script>  



Sunday, February 17, 2013

Read data from Google data API

When you send data to Google analytics, you might need access those data. so then first you need to create Google API console project. follow the instructions in here-
https://developers.google.com/analytics/resources/articles/gdata-migration-guide
in API access tab you can get the API key which is needed for getting data from Analytics. In addition to that you need following dll.
  • Google.GData.Analytics.dll
  • Google.GData.Client.dll
you can download those dll from following link-
http://code.google.com/p/google-gdata/downloads/list 

once you install this you can get the dll's from 
C:\Users\xyz\Documents\Google Data API SDK\Sources\Library\analytics\bin\Debug folder

 private void RefreshFeed()   
   {   
    string userName = "abc@gmail.com";   
    string passWord = "pwdabc";   
    string gkey = "?key=AIzaSyACrV2kbnPl9ybZZh8-sla_sPnLIKYKbxA";   
    string dataFeedUrl = "https://www.google.com/analytics/feeds/data" + gkey;   
    AnalyticsService service = new AnalyticsService("WebAppTest");   
    service.setUserCredentials(userName, passWord);   
    DataQuery query2 = new DataQuery(dataFeedUrl);   
    query2.Ids = "ga:12345678";   
    query2.Metrics = "ga:pageviews";   
    query2.Sort = "ga:pageviews";   
    query2.GAStartDate = new DateTime(2012, 1, 2).ToString("yyyy-MM-dd");   
    query2.GAEndDate = DateTime.Now.ToString("yyyy-MM-dd");   
    query2.StartIndex = 1;   
    DataFeed data = service.Query(query2);   
    foreach (DataEntry entry in data.Entries)   
    {   
       string st = entry.Title.Text;   
       string ss = entry.Metrics[0].Value;   
    }   
  }   

You can get Id as shown in following photo

Wednesday, November 28, 2012

Google Analytics Reports 

Google analytics provide standard reporting and custom reporting features.

General Method 

Export Directly from Google Analytics Account using standard reporting. 



This TSV File can be generated as follows:
Export à TSV for Excel à save File
By using TSV for Excel option we can create TSV file for available data. This TSV file can be open In Microsoft Excel.
This can be done as follows:
Open Excel à File à Open à Select generated TSV File à Open


Problem Identified

TSV file generate according to the selected no rows. User can select maximum 500 records. Even there are 1000 records in given criteria it export first 500 records only.


To overcome this problem we identified following solutions.

  Option 1 – Change Show Rows

First select show rows value other than the default value and refresh report. Then URL is changed according to that and end of the URL displayed no of selected rows.


To increase no of rows user must manually change this value.After that user can export into TSV file using Export option.


  Option 2 – Use Google analytics Query Explorer



Use below link to get query explorer.

Log with your Google Account. Then it will take Account, Web Property, Profile and ids automatically. Then add dimensions metrics, date range and max result according to reporting format.  



Details about query parameters:

Dimensions: Columns that you need to show in report
Metrics: Rows
If need to add filters then it should write in following format:
ga:source=~^testing.*

Sort: sorting can be done ascending or descending.
For an example if you want to sort data according to page views then it must write as follows,
Ascending:  ga:pageviews
Descending: -ga:pageviews (Add (-) mark before ga variable)

start-date and end-date: Date range for the report. This date can be picked from date time picker.
max-results: Maximum number of results to retrieve from the API. The default is 1,000 but can be set up to 10,000.


Saturday, October 13, 2012

Use Google Analytics in Non- web based application in .Net


Google analytics is contain valuable information that can be used to analyzing purposes. most of the time analytics used in web based applications. but analytics can be used in non web based applications too.

  Send request to Google Analytics

as a first point u have to create Google analytics account. so first create Google analytics account and then login to it.


then agree to terms and conditions and create account.

after that in your application you need to you need to create URL as it calls in normal site. in here i use c#. 
 private void analyticsmethod4(string trackingId, string pagename) 
 { 
   Random rnd = new Random(); 
   long timestampFirstRun,timestampLastRun,timestampCurrentRun,numberOfRuns;  
   // Get the first run time 
   timestampFirstRun = DateTime.Now.Ticks; 
   timestampLastRun = DateTime.Now.Ticks-5; 
   timestampCurrentRun = 45; 
   numberOfRuns = 2;  
   // Some values we need  
   // This can be calcualted for your domain online  
   string domainHash = "123456789";  
   int uniqueVisitorId = rnd.Next(100000000, 999999999); // Random 
   string source = "Sourcetesting"; 
   string medium = "mediumTesting"; 
   string sessionNumber = "1"; 
   string campaignNumber = "1"; 
   string culture = Thread.CurrentThread.CurrentCulture.Name;  
   string statsRequest = "http://www.google-analytics.com/__utm.gif" + 
          "?utmwv=4.6.5" + 
          "&utmn=" + rnd.Next(100000000, 999999999) + 
          "&utmcs=-" + 
          "&utmsc=-" + 
          "&utmul=" + culture + 
          "&utmje=-" + 
          "&utmfl=-" + 
          "&utmdt=" + pagename + 
          "&utmhid=1943799692" + 
          "&utmr=0" + 
          "&utmp=" + pagename + 
          "&utmac=" +trackingId+ // Account number 
          "&utmcc=" + 
          "__utma%3D" + domainHash + "." + uniqueVisitorId + "." +  
              timestampFirstRun + "." + timestampLastRun + "." +  
              timestampCurrentRun + "." + numberOfRuns + 
          "%3B%2B__utmz%3D" + domainHash + "." + timestampCurrentRun + "."  
              + sessionNumber + "." + campaignNumber + ".utmcsr%3D" +  
              source + "%7Cutmccn%3D(" + medium + ")%7Cutmcmd%3D" + medium +  
         "%7Cutmcct%3D%2Fd31AaOM%3B";  
    using (var client = new WebClient()) 
    { 
      client.DownloadData(statsRequest);       
    } 
   }