.Net Framework

...now browsing by category

 

Create and consume WCF Service from scratch

Wednesday, September 1st, 2010

Today, I read an article on Codeproject.com by Mike Liu and he gave a very detail illustration on how to create and consume a WCF service from scratch, without using any of those pre-existing WCF templates in VS2010. It was very refreshing and no wonder the article ended up in last month’s new author winner list

These were the steps I went through to create and consume a HelloWorld WCF service following Mike’s instruction:

  1. Selected a Blank solution from VS2010 -> C#/Other Project Types/Visual Studio Solutions
  2. Added a Class library (named HelloWorldService) to the solution (Solution file resided in the root folder and named HelloWorld. When the class lib was created, it automatically created a folder called HelloWorldService)
  3. added a reference to System.ServiceModel.dll to the class lib
  4. Added an Interface class called IHelloWorld.cs to the project and defined ServiceContract and OperationContract, like this:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    namespace Yangsoft.Training.WCF
    { [ServiceContract]
    public interface IHelloWorldService
    {
    [OperationContract]
    String GetMessage(String name); 

    }
    }

     

  5. renamed the class1.cs to HelloWorldService.cs and implemented the interface, like this:class HelloWorldService : IHelloWorldService

    public String GetMessage(String name)
    {

    return “Hello World from ” + name;

    }
    }

  6. Service was created and now it needed to be hosted on a website. To accomplish that, added a new website, named HostDevServer to the HelloWorld solution and made this website use static port: 8080. The website was added as blank website, did not have any string attached and no need to change default web location, File System.
  7. Added a reference to the website project to pick up HelloWorldService class library
  8. Then I opened the web.config; before I added any WCF related stuff, the web.config only had a <system.web> entry. Followed the instruction given in the article, added system.webserver and system.serviceModel sections, now the web.config looks like this:<configuration>
    <system.web>
    <compilation debug=”false” targetFramework=”4.0″ />
    </system.web>
    <system.webServer>
    <modules runAllManagedModulesForAllRequests=”true”></modules>
    </system.webServer>
    <system.serviceModel>
    <behaviors>
    <serviceBehaviors>
    <behavior name=”MyServiceTypeBehaviors”>
    <serviceMetadata httpGetEnabled=”true”/>
    <serviceDebug includeExceptionDetailInFaults=”false”/>
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service name=”Yangsoft.Training.WCF.HelloWorldService” behaviorConfiguration=”MyServiceTypeBehaviors”>
    <endpoint address=”” binding=”wsHttpBinding” contract=”Yangsoft.Training.WCF.IHelloWorldService” ></endpoint>
    <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” ></endpoint>
    </service>
    </services>
    </system.serviceModel>
    </configuration>
  9. Now added a .svc file the hardcore way: just added a plain text file called HelloWorldService.svc and added the entry and the only entry to the text file:<%@ ServiceHost Service=”Yangsoft.Training.WCF.HelloWorldService” %>This basically created a website to host the HelloWorlService that a client consume.
  10. Added a Console project, named HelloWorldClient to the solution, no app.config, no other class except the default Program.cs class in the project at this point.
  11. The final piece of major work was to run svcutil.exe to generate the service proxy on this client. This was accomplished all in command line mode:
    • backed out to DOS mode, navigated to the folder where HelloWorldClient console app resided
    • run this command from the folder:“c:\program files\microsoft sdks\windows\v6.0a\bin\svcutil.exe” http://localhost:8080/HostDevServer/HelloWorldService.svc?wsdl after this was run, it generated two files in the HelloWorldClient folder: HelloWorldService.svc and output.config (here I did not follow exactly the instruction given by the Author). Before this was run, I had run the HostDevServer without debuging and checked and made sure the service was created correctly.
    • Returned to the VS2010 solution explorer and go to Project/Show All Files and included the two files created by the svcutil.exe tool in the Console project. Renamed the output.config to app.config and made sure added a reference to the project for System.ServiceModel.
    • Open the Program.cs and added these lines in the Main static method:{
      HelloWorldServiceClient client = new HelloWorldServiceClient();
      Console.WriteLine(client.GetMessage(“Steve Yang”));
      }
    • set the start up project to be the console and hit Ctrl+F5 to run the program in non-debug mode, and the output of the program should be a line saying “Hello World from Steve Yang” or whatevever I programmed in the GetMessage(String name) method in the HelloWorldService.cs in the HelloWorldService class library.
    •  

      In real world of VS2010, I did not have to do all these as there are pre-written WCF templates that I could just drag-and-drop into the solution and automatically populate the web.config and app.config. But I agreed with the author, going through these tedious steps had helped me understand WCF service dearly.

 

Install a Window Service

Sunday, August 1st, 2010

Here were the steps I went through to install a Window service called “Yangsoft Greeting” that will simply say a greeting when user first logs in to a PC:

  1. Create a Windows service project using the service template from VS2010
  2. Right click on the service.cs designer surface and add a service installer (ProjectInstaller.cs)
  3. Once I added the ProjectInstaller, there were two installer components needed to be configured properly, one is for service installer and one for service process installer. ServiceInstaller is where you define the name, description, and display name of the service; ServiceProcessInstaller is where you define which account will be used to run the service. The account to choose is LocalService, LocalSystem, networkService and User. The User account requires a user name and password when the service is installed.
  4. After compiling the solution, next step is to install the service so that it will show up in the Windows service list. There are two ways to install a service, one is manually running InstallUtil.exe from command line, for example : C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe    F:\Development\GreetingWinSvc\VoiceGreeting\bin\Release\Yangsoft.VoiceGreeting.exe
  5. The other way is to create a Setup and deployment project and package everything into a MSI file.

 

Playing with sapi.dll

Tuesday, July 27th, 2010

With Microsoft’s Speech Library, it is extremely easy to add voice to your .Net application.

I created a small Console app in VS2010 and here were the steps I took:

  1. Add reference to sapi.dll, which was found in my computer’s C:\Program Files\Common Files\Microsoft Shared\Speech (Windows XP SP2)
  2. Import the Speech type library namespace
  3. Instantiated a SpVoice and called the Speak method; that was all.
Sample codes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpeechLib;
namespace ComInterop
{
class Speech
{
public static void SayThis(string words)
{
SpVoice voice = new SpVoice();
voice.Speak(words, SpeechVoiceSpeakFlags.SVSFDefault);
}
}
static void Main(string[] args)
{
////speech library
Console.WriteLine(“Type a few words to speak”);
string words = Console.ReadLine();
Speech.SayThis(words);
Console.ReadKey();
}
}

 

Directory Access Control

Sunday, July 25th, 2010

The other day I was playing with ACL and got myself locked out of a directory that I tried to access. Then I tried to add a new FileSystemAccessRule with FullControl right and Allow type, hoping to regain the access to the folder; but it turned out that was not the way to do it. I had to call RemoveAccessRule from the DirectorySecurity object in order to re-grant myself access to the folder. So I figured I would make a note here so that myself and others can use as reference when things about ACL get murky again in the future.

To grant a Windows user access to a specific directory, use the following codes (need using these namespaces : System.Security.Principal,System.Security.AccessControl,System.IO)

 

public static void GrantDirectoryAccess(string dir, string userName)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.AddAccessRule(new FileSystemAccessRule(userName,FileSystemRights.FullControl, AccessControlType.Allow));

Directory.SetAccessControl(dir,ds);

 

}

To deny user Read access to the folder, use the following:

public static void DenyDirectoryAccess(string dir, string username)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.AddAccessRule(new FileSystemAccessRule(username,FileSystemRights.Read, AccessControlType.Deny));

Directory.SetAccessControl(dir,ds);

}

 

If you want to give user back the access right, you would think that by running GrantDirectoryAccess() method again you can achieve that, correct? Wrong! The ACL rule is if there are Deny and Allow access types both tied to a user or a user group, then the Deny will take precedence.

So, in order to give the access right back, you’ll need to remove the access rule by running the codes below instead:

public static void RemoveDirectoryDeny(string dir, string userName)

{

DirectorySecurity ds = Directory.GetAccessControl(dir);

ds.RemoveAccessRule(new FileSystemAccessRule(userName, FileSystemRights.Read, AccessControlType.Deny));

Directory.SetAccessControl(dir, ds);

}

Here is the sample of how to grant user “steve” access to “c:\test” folder, then deny it, thn re-grant it:

static void Main(string[] args)

{

Console.WriteLine(“Messing around with C:\test”);

//first grant fullcontrol access

GrantDirectoryAccess(@”c:\test”,”steve);

//then deny the Read access

DenyDirectoryAccess(@”c:\test”, “Steve”);

//Tried to run GrantDirectoryAccess() again and see if it worked;, it didn’t

//Had to remove the Deny rule

UserSecurity.RemoveDirectoryDeny(@”c:\test”, “Steve”);

Console.WriteLine(“Access to c:\test has been regained. Press any key to exit”);

Console.ReadKey(true);

 

}