<$BlogRSDUrl$>

Tuesday, March 22, 2005

business links 

http://www.clpgh.org/locations/business/smallbusiness/bplansindex.html
http://happiness.hit.bg/bear/bear.htm

Thursday, March 17, 2005

Red Line Reviews: A method to gauge real project progress 

Definition and Purpose
The purpose of a red line review is as follows:
  1. To determine the true degree of project completion

  2. To insure the project is being done to spec

  3. To find spec lines that are implied by but not cover by the spec or places where the spec could be in error or not understood, these are called SPEC GAPS

  4. To make sure all parts of the spec are assigned or at least verify what has yet to be assigned

  5. To identify areas of scope reduction or scope creep

  6. To allow estimate of person power actual vs estimated effort

In short to insure the project is on track and on time.

Steps
  1. The spec should be numbered.

  2. As spec lines are added to the spec the numbering should not be modified, instead the spec lines should receive new numbers. Numbering in the spec is designed to make the requirements traceable, the sequential order is not important

  3. If spec lines are "deleted" they should instead be stricken and be counted as being done for the purposes of calculation

  4. If an item is modified, it should receive a new number, the old number should be treated as deleted above this has the effect of increasing the number of spec spec lines with modification and is desired

  5. Using the actual product as it is delivered at the time of the review e.g. do not accept a statement of completion, verify it visually, go thought the spec scoring each requirement and counting the number of requirements

  6. Compute the doneness statistics as below

Scoring Criteria



Degree of DonenessScoreNote
Not Done At All0
Partially done and looks to match spec1/2Any degree of doneness less the 100% done
Done to Spec1
Done (all or partial) not to Spec-1Anything wrong is 100% wrong


Formulas for calculating project progress
Computed by person leading the Red Line


Total Spec Lines: The count of all lines in the spec Total Score: The sum of all the scores for the criteria

% Done = Total Score / Total Spec Lines

Total Undelivered spec lines: Sum of all spec lines with a 0 score
Total Under Delivered spec lines: Sum of all spec lines with a 1/2 score
Total Mis-Delivered spec lines: Sum of all spec lines with a -1 score
Total Delivered spec lines: Sum of all spec lines with a 1 score

Scope Creep %: (Total Spec Lines) / (Spec Lines at last review) * 100

Computed by the schedule keeper

Effort


Estimated Project Hours: From COCOMO or other LOE estimate at project start
Actual Project Hours: The number of hours expended on the project from the effort system
Revised Project Hours: (100 * Actual Project Hours) / ( % Done)
Project Drift (Effort) %: (Revised Project Hours) / (Projected Estimated Hours) * 100

Schedule

Estimated Project Finish Date: The date the project was supposed to finish
Estimated Number of Project Days: The estimated duration of the project
Revised Project Days: (100 * Estimated Number of Project Days) / ( % Done)
Revised Finish Date: Estimated Project Finish Date + (Revised Project Days - Estimated Number of Project Days), Adjusted for work days (best done by MS project)


Results Processing

This section addresses what the results are and who should receive them

Result Types




Result Type Contains
Initial Red Line StatisticsTotal Spec Lines
Total Score% Done
Total Undelivered spec lines
Total Under Delivered spec lines
Total Mis-Delivered spec lines
Total Delivered spec lines
List of Spec GapsList of Lines Added/Modified Since Last Red LineScope Creep %
Schedule UpdateEstimated Project Hours
Actual Project Hours
Revised Project Hours
Project Drift (Effort) %Estimated Project Finish Date
Estimated Number of Project Days
Revised Project Days
Revised Finish Date
Spec Document RevisionsNew Spec Lines
Changed Spec Lines
Deleted Spec Lines


Bold: Minimum required items

Recipients



Result TypeRecipients
Initial Red Line StatisticsDevelopers
Manager of Development Team
Scheduling Team
Product Management
Schedule UpdateManager of Development Machine
Scheduling Team
Product Management
Scheduling Subscribers
Spec Document RevisionsDevelopers
Product Management

COCOMO Notes 

COCOMO Notes

I have gotten a fair amount of interest lately in the Micro-COCOMO model available for download on this site, condensing many of the questions and feedback, I have the following advise.
If you have not COCOMO'd before you should read the book first. The co-efficients and scalars used in the micro-COCOMO spreadsheet are obtained by doing projects of varying size and using analysis of variance and his techniques to "fine tune" the constants used.
Comment: a first pass accuracy with the tool of +/- 10% is VERY GOOD.
Comment: This assumes a requirements doc + an ERD + a site map.
The current Micro-COCOMO is for ASP (classic). We are building a worksheet and co-efficients for ASP.NET and .NET rich client UIs but do not have enough data points yet. (If you have some, then share, please!)
Worksheet columns and what they mean

  • Pages/Reports are the number of ASP Pages or Reporting Tool Reports needed by the component you are estimating

  • Tables: SQL Server tables assuming proper 3rd normal form (this can be estimated from the ERD)

  • Controls: The number of individual controls used on the form/page

  • SP: SQL Stored Procedures (as estimated from the requirements)

  • Code: An estimate of the number of lines of code (outside of the other things) you estimate (using function point or some other estimating mechanism).

  • Comment: COCOMO is driven off of lines of code. This may sound daft, but assigning a scalar quantity to other things (like pages and reports) allows us to estimate using a worksheet that is more directly connected to the requirements, ERD and Wire frames.

    COCOMO Notes 

    COCOMO Notes

    I have gotten a fair amount of interest lately in the Micro-COCOMO model available for download on this site, condensing many of the questions and feedback, I have the following advise.
    If you have not COCOMO'd before you should read the book first. The co-efficients and scalars used in the micro-COCOMO spreadsheet are obtained by doing projects of varying size and using analysis of variance and his techniques to "fine tune" the constants used.
    Comment: a first pass accuracy with the tool of +/- 10% is VERY GOOD.
    Comment: This assumes a requirements doc + an ERD + a site map.
    The current Micro-COCOMO is for ASP (classic). We are building a worksheet and co-efficients for ASP.NET and .NET rich client UIs but do not have enough data points yet. (If you have some, then share, please!)
    Worksheet columns and what they mean

  • Pages/Reports are the number of ASP Pages or Reporting Tool Reports needed by the component you are estimating

  • Tables: SQL Server tables assuming proper 3rd normal form (this can be estimated from the ERD)

  • Controls: The number of individual controls used on the form/page

  • SP: SQL Stored Procedures (as estimated from the requirements)

  • Code: An estimate of the number of lines of code (outside of the other things) you estimate (using function point or some other estimating mechanism).

  • Comment: COCOMO is driven off of lines of code. This may sound daft, but assigning a scalar quantity to other things (like pages and reports) allows us to estimate using a worksheet that is more directly connected to the requirements, ERD and Wire frames.

    COCOMO Notes 

    COCOMO Notes

    I have gotten a fair amount of interest lately in the Micro-COCOMO model available for download on this site, condensing many of the questions and feedback, I have the following advise.
    If you have not COCOMO'd before you should read the book first. The co-efficients and scalars used in the micro-COCOMO spreadsheet are obtained by doing projects of varying size and using analysis of variance and his techniques to "fine tune" the constants used.
    Comment: a first pass accuracy with the tool of +/- 10% is VERY GOOD.
    Comment: This assumes a requirements doc + an ERD + a site map.
    The current Micro-COCOMO is for ASP (classic). We are building a worksheet and co-efficients for ASP.NET and .NET rich client UIs but do not have enough data points yet. (If you have some, then share, please!)
    Worksheet columns and what they mean

  • Pages/Reports are the number of ASP Pages or Reporting Tool Reports needed by the component you are estimating

  • Tables: SQL Server tables assuming proper 3rd normal form (this can be estimated from the ERD)

  • Controls: The number of individual controls used on the form/page

  • SP: SQL Stored Procedures (as estimated from the requirements)

  • Code: An estimate of the number of lines of code (outside of the other things) you estimate (using function point or some other estimating mechanism).

  • Comment: COCOMO is driven off of lines of code. This may sound daft, but assigning a scalar quantity to other things (like pages and reports) allows us to estimate using a worksheet that is more directly connected to the requirements, ERD and Wire frames.

    Tuesday, March 15, 2005

    A Love Letter - .NET Way 

    I have a managed heap of memories regarding you - none of which are IDisposable. Therefore I am compiling my references, and persisting them to you in this file, which is ISerializable and will last for generations (at most 3).
    I remember how I met you... heartbroken over java (how slow that old relationship was). When I first heard of you, I heard you were COOL. Then I found out how diverse you were in so many languages. You marshalled right over to my world. How easy it was for you to communicate over so many platforms! You understood my profile, and now I could see sharp-ly into your IIdentity.
    You took me to your visual studio - it was RAD. So many views and hidden regions! You were so organized with your task list. I love how everything was color coded. It was in that environment when I broke down and stated: "You auto-complete me..."
    We had our bugs to work out - we were not the exception. One time you thought we had a break-point. But we would continue to try. Nothing went unhanlded. We caught everything, and finally we come to this moment.
    How do you do it? You stay true to so many standards, yet manifest so much. You have such class! There is no other type like you. As I reflect about you, I see that you have many methods - some very internal, some private, and some very protected. Some of your ways are too abstract to know. But what is public about you, anyone can see why you encapsulate so much inside. From what I derive, we can override anything (unless we sealed it).
    Let's not box ourselves into the typical cast. We should look to the future - is it generic? I don't know - I may be partial. I will have to iterate over this until I yield.
    How long will we survive?
    while (this!=null){ continue; }

    I can't get this sample to compile - I believe you forgot the using System.RomanceModel; namespace declaration.
    I wish I was the .NET framework, so you could live me just as much.
    That wanton floozy .NET - I never knew I was in a many-to-one relationship. I was even planning on a decorator. But it was just a facade all along. I would have been better off remaining a singleton. And to think of all those times I was unsafe...! As he mindlessly gazed into the now-empty INamingContainer, Michael groggily climbed back to the ragged precipice of sobriety and realized just how IEnumerable the TimeSpan he spent JITting his ode to .NET was... :)

    Wednesday, March 09, 2005

    .NET Web Services using WSE 

    .NET Web Services using WSE
    .NET makes creating or using a web service easy, but it's not always exactly as described in the documentation.

    This article covers using the Microsoft Web Services Enhancements (WSE) in Visual C# .NET. I'm assuming you're relatively "au fait" with C# and the .NET framework, and are interested in writing web services.
    There are several ways of writing web services available to programmers using Microsoft's Visual Studio .NET environment, and several programming languages to choose from. Whilst variety may be the spice of life, it does also make it a little difficult to know where best to begin. To compound such problems, the web services scene is changing fast. No sooner have you got your head around using the .NET framework and the web service support available, than yet another set of libraries comes out which purports to "make life easier" in one way or another. I am, of course, referring to the latest
    Web Services Enhancements library shipped by Microsoft.
    Whenever a new class library comes out, I always ask myself whether it's really worth the effort of learning it, or will the library either (a) just add a layer of unnecessary complication to the current development project, or (b) be superseded by another "later and greater" class library in the not too distant future. In order to answer such questions you are immediately landed in a Catch-22 situation, since you have to learn something about the class library before you can decide whether to "go the whole hog" and learn it fully. The purpose of this article is to make you familiar enough with the WSE library that you can answer such questions for yourself.

    Looking at requirements
    One of my current architectural tasks is to look at turning a classic n-tier web-based application that is driven by a browser GUI front-end into a programmatically distributed system. That is, one instance of a server (I like to think of it as a "server atom") can programmatically talk to another server atom somewhere on the Internet (that's correct: not intranet but Internet). I could design our own, private and proprietary data exchange mechanism, operating (probably, but not necessarily) over HTTP. I'm inherently suspicious of anything that's private and proprietary, on the basis that it's almost guaranteed that someone, somewhere will have been confronted with the same task. In any case, it looks like distributed web services are a good bet for a first look at meeting the requirements, but how to communicate between the distributed web services? I could use a fully proprietary design but I dismissed that idea straight away. How about XML RPC after all, I'm looking primarily at an RPC-type environment? Seems fine for connectivity but... the XML documents that I send and receive are once again a proprietary format for XML RPC. The Simple Object Access Protocol (SOAP) addresses this proprietary XML RPC format quite nicely by providing a standard XML format for the messages. So it looks like SOAP is the way to go, at least for the moment. Let's explore this path a little further.
    The kinds of operations I need to support are synchronous and asynchronous calls of remote services, with either type of call possibly returning data either immediately as a result of the call or at some future point.
    I conclude that I need to use SOAP for exposing web services. As the data I return potentially contains sensitive information, I need to look at security of the data transfer. I need to look at the possibility of sending binary data back (e.g. a bcp bulk copy utility query result from a database in native database format).
    This brings me to the heart of this article: Microsoft recently released the WSE library to extend the web service support already provided in .NET. WSE provides me with an implementation of three recently released web service specifications: WS-Security, WS-Attachments and WS-Routing. The question facing me now was whether using WSE would help me in reaching my goal.

    What WSE provides
    Web Services Enhancements, as the "Enhancements" part of the name implies, are extensions to the SOAP specification. That always makes me nervous. The word "extension" implies "non-standard", and non-standard is something I definitely want to avoid. However, the facilities provided by WSE use the SOAP extension model and are also based in some cases on existing Internet draft documents (e.g. WS-Attachments is based on work on the DIME Internet draft). There are other standards out there too. For example, the XACML security specification drafted under the good auspices of OASIS provides a standard for applying a security policy in a web services environment. The parallel to XACML in the Microsoft world is the WS-Policy specification.
    The three WS facilities provided by WSE come under the general auspices of Microsoft's Global XML Web Services Architecture, commonly abbreviated to GXA. It is intended that GXA is an umbrella concept that will use one or more of the WS facilities plugged together by an architect to achieve a final design goal. For example, WS-Routing provides the fundamental services that WS-Security can use to ensure privacy of information. Both WS-Routing and WS-Security are component services of the GXA. WSE is an implementation of the WS-Security, WS-Routing and WS-Attachments specifications. I won't look at how WSE achieves what it does, but will simply focus on how you can use WSE.
    The outline development plan for this article is as follows:
    Write a web service using WSE to expose, say, a factorial calculation
    Write a client to consume that web service
    Re-work (1) and (2) to use security
    Re-work (1) and (2) to send an arbitrary binary attachment, both to and from the web service
    Re-work (1) and (2) to send a binary attachment that is encrypted.

    Getting started
    This section will look at providing a simple web service to expose a factorial calculation and how to configure the server-side web service to use WSE. Once that is done, I will generate a client program to call the web service. The client program will be generated in part by using a proxy-generating tool in Visual Studio .NET. The generated code will need slight modification to use WSE and I'll detail what needs to be done there for the client to use WSE. By the end of this section you should be up and running with a web service and client that use WSE but don't do much with WSE at all. After all that, you'll see in the next section how to start getting WSE involved in helping meet the requirements of a secure web service that can transmit and receive arbitrary length binary data.
    First of all, you'll need to ensure you have IIS up and running. Secondly, you'll need to
    install WSE.
    The particular version of WSE I'm using is WSE 1.0 SP1. While you're at it, you may as well get hold of the
    WSE Settings Tool for Visual Studio .NET.
    Start Visual Studio .NET and create a new Visual C# ASP.NET Web Service project. The name I've given the web service in this article is

    http://localhost/FactorialService
    A short pause ensues while Visual Studio .NET creates a virtual directory called FactorialService on IIS and marks it as an application. The source files are then placed within this virtual directory. Whilst this is fine for development, you may wish to exclude the source files when deploying the web service to your production web server!
    From Solution Explorer, select the Service1.asmx file and rename it to something a little more meaningful. I chose to rename this service to FactorialService by right clicking on the Service1.asmx file and choosing "Properties". In the property inspector, I changed the file name from "Service1.asmx" to "FactorialService.asmx". Now switch to the Class View window in Visual Studio and expand the tree until you can see Service1. Right-click on this and rename it to Factorial.

    Server-Side
    Browsing the C# source, you should find that a commented-out "HelloWorld" method has been provided, prefixed with the [WebMethod] attribute. To modify the web service to provide a factorial function:
    Add two constants for max and min factorial range somewhere in the class

    private const int minFact = 0;
    private const int maxFact = 12;

    Replace the HelloWorld commented-out method with the following method (leaving the [WebMethod] attribute in place)
    public int Calc(int n)
    {
    int factVal = -1;
    // use -1 as out-of-range indicator
    if(n >= minFact && n <= maxFact)
    {
    // factorial by iteration
    factVal = 1;
    // 0! and 1! are both 1 by
    // definition
    for(int factCnt = 2; factCnt
    <= n; ++factCnt)
    {
    factVal *= factCnt;
    }
    }
    return factVal;
    }

    As far as programming goes, that's it! You now have a web service. To hook into WSE, however, you will need to change the application's Web.config file.
    In order for your web service to hook into WSE, you need to add some XML to the Web.config file to tell IIS how to invoke WSE. Select the Web.config file in Solution Explorer and add the required XML entries. This is shown in Figure 1.
    Figure 1
    The element is used with the "type" attribute, which is set to point to WSE by its assembly name. For display purposes, I have had to wrap the "type" attribute so you can see what the value should be. In the actual Web.config file, of course, the type attribute should be one line with no newlines in it. I have omitted the rest of the Web.config file in Figure 1 as it remains as-is.
    You should be able to build the web service now.

    The client
    I'll create a real basic console application in C# to talk to the web service in order to demonstrate that you don't need any heavyweight client code to use a web service. First of all I'll generate a basic client and use Visual Studio .NET tools to generate the required proxy class to talk to the web service. I'll then show how you need to modify the generated proxy file to use WSE. That will complete the basic web service and client configuration.
    In Visual Studio .NET generate a new Visual C# Console Application. I called mine FacClient. You can place the client in the same solution as the web service if you wish, but I chose to keep my client completely separate from the web service project in its own "solution" space. Skeleton code will be generated for you. The first thing you'll need to do is a reference to WSE for your client program. You do this by going to the Solution Explorer and right-clicking over References. From the context menu that opens, select "Add Reference". The resulting dialog is shown in Figure 2, which also shows Microsoft.Web.Services in the list of .NET assemblies.
    Figure 2
    If the assembly does not appear in the list, you will have to use the "Browse" button on the dialog. By default, the DLL is located at:

    %Program Files%\Microsoft
    WSE\v1.0.2312\Microsoft.Web.
    Services.dll

    Once you have located the assembly, click on "Select" then on "OK". In order to use the assembly in your client code you will need to either explicitly reference each instance using the full path name or place the following using directive at the top of your client program: using Microsoft.Web.Services;. You can change the class and file name (as detailed in the section "Server-Side Coding") if you wish, but I chose to leave the class name as Class1 (and filename as Class1.cs) for this simple client.
    Next we need to generate the proxy class to talk to the web service. You do this by right clicking over References in Solution Explorer again - but this time selecting "Add Web Reference" from the context menu, which results in a dialog being displayed. You need to enter the URL that points to the FactorialService.asmx file. Figure 3 shows the URL typed in at the top and the resultant output.
    Figure 3
    Click on the "Add Reference" button at the bottom of the dialog. This adds a proxy class to your project and some more references. Figure 4 shows the "Class View" panel indicating that two proxy classes have been generated in the localhost namespace.
    Figure 4
    The proxy class Factorial is the standard SOAP HTTP proxy class. The other proxy class, and the one we're more interested in, is FactorialWse. The Wse is appended to the name to show that it is using WSE. The difference between the two comes down to the fact that the basic SOAP proxy class derives from the SoapHttpClientProtocol class and the WSE proxy derives from WebServicesClientProtocol, which provides the hooks into WSE.
    Note: the WSE documentation talks about editing the generated proxy class file and changing the inheritance. This documentation point is out of date and you do not need to do this any more. Simply use the "Wse" version of the proxy class.
    In order to use the proxy class add the using directive using FacClient.localhost; somewhere near the top of your client program source and implement Main as follows:

    static void Main(string[] args)
    {
    try
    {
    FactorialWse fs =
    new FactorialWse();
    int val = 6;
    int fac = fs.Calc(val);
    Console.WriteLine(
    "Web service called
    successfully!");
    Console.WriteLine(
    "Factorial of {0} is {1}",
    val, fac);
    }
    catch(Exception e)
    {
    Console.WriteLine(
    "Error with web service: "
    + e.Message);
    }
    }

    You should be able to build and run the client and, all being well, you should find out that the factorial of 6 is 720. Nothing too earth-shattering about that, I agree but what you have done is successfully implemented a web service and client that use WSE albeit at a very basic level. On this foundation, I'm now going to look at using the facilities provided by WSE to see if it can meet my original requirements, which, after all, is the point of the exercise.
    Web services enhancements and WS-specifications
    The WSE .NET library provides an implementation of the WS-Security, WS-Attachments. I'm going to look at WS-Security and WS-Attachments.
    There is no point pursuing the use of WSE if a reasonable degree of data privacy is not achievable using WS-Security. The security mechanism that WS-Security can use is not fixed. For demonstration purposes I will use a simple "shared secret" symmetric encryption process. The major advantage of WS-Security over other security implementations is that WS-Security is implemented on the SOAP packet, whereas other security mechanisms take place at the transport layer (e.g. HTTPS, SSH) and provide a point-to-point encoding. With a distributed web service you don't necessarily know the route a SOAP packet will take, so WS-Security applies security measures at the SOAP packet level rather than the transport level. The WSE documentation contains instructions for building a WSE WS-Security web service that can decrypt a SOAP message and a WSE WS-Security client that can encrypt a SOAP message. I'm going to use the instructions provided in the WSE documentation as a starting point in part because it fulfils one-half of my encryption requirement and in part because the documentation is incorrect in several places and I will show you the correct version in this article. Let's go for building the web service first, then writing the client and generating the proxy class using Visual Studio.NET.
    I'm going to modify the FactorialService and client so that the client can send an encrypted request to the web service to generate the factorial of the encrypted value. Add a reference to Microsoft.Web.Services and System.Security by choosing Add Reference from the context menu on the References node in the Solution Explorer window. You can add both references in one hit in the Add Reference dialog by first choosing "Microsoft.Web.Services" and clicking "Select", followed by choosing "System.Security" and clicking "Select" again. Click on "OK" to complete adding the references. Add the following using directives somewhere near the top of your C# source file:

    using Microsoft.Web.Services;
    using Microsoft.Web.Services.Security;
    using System.Security.Cryptography;
    using System.Security.
    Cryptography.Xml;
    using System.Security.Permissions;

    Notice that the WSE documentation in Point 9.b is missing the using System.Security.Permissions; directive.
    In order to decrypt the incoming message, you need to provide a DecryptionKeyProvider in the form of a class. WSE will use your class to decrypt the SOAP message at the point of reception and then pass the decrypted message to your web service. As far as your main web service is concerned, it knows nothing about the encryption of the call it is all handled by WSE and your own custom class. Point 10 in the WSE documentation describes the method of adding a class to be used for DecryptionKeyProvider, but it's unfortunately out-of-date in stating that your class needs to implement the IDecryptionKeyProvider interface. This is no longer true your class should inherit from a WSE base class called DecryptionKeyProvider. Given that the example in the WSE documentation calls its own class DecryptionKeyProvider, if you also inherit from a class called DecryptionKeyProvider then you have a circular inheritance loop and the code will no longer compile. In summary, you need to change the inheritance and also call the class something different to the one in the WSE documentation. I called my class DecKeyProv and declared it as:

    public class DecKeyProv :
    DecryptionKeyProvider

    The security attributes for this class are the same as in the WSE documentation, although the WSE documentation version will not compile due, firstly, to the missing using directive (dealt with above), and secondly in part due to the fact that the method as given does not compile!
    If you do try to compile the method GetDecryptionKey as given in the WSE documentation you will get an error to the effect of "not all control paths return a value". The easiest way of fixing this is to add return null; just after the close of the foreach loop as the last statement in the method that will fix the error. Now on to the warning: a warning is issued about your GetDecryptionKey method hiding the base class GetDecryptionKey method. What you need is to override the base class implementation so the declaration for your GetDecryptionKey method becomes:

    public override DecryptionKey
    GetDecryptionKey(...).

    This is what an outline of the class and method should look like:
    public class DecKeyProv :
    DecryptionKeyProvider
    {
    public override
    DecryptionKey
    GetDecryptionKey(
    string algorithmUri,
    KeyInfo keyInfo)
    {
    // body as per WSE document
    // (plus corrections)
    // or exactly as in the code
    // sample for this article
    }
    }

    The DecKeyProv class can be added to the FactorialService namespace. For ease of writing, I placed the class in the same source file as the main web service, although you could place it in a separate file if you wish.
    XML web service life just wouldn't be the same without editing an XML file somewhere or other, so I'll look next at what you need to do to the Web.Config file to get the WS-Security functionality up and running.
    The first thing you need to configure is the server-side to use the WS-Security implementation in WSE, so it's back to the Web.config file. I'm working on the basis that you've already added the standard WSE blurb as detailed in "Server-Side Configuration" above. A couple of things need to be in place in the Web.config file to cater for security. The first is to add a that gives a name to the WSE library (we'll call it microsoft.web.services as per the WSE documentation). The second step involves using the microsoft.web.services section you've just defined to pull in your security class for decryption. You can add this directly beneath (not inside!) the element. Both these steps are shown in Figure 5.
    Figure 5
    The "type" attribute of the section tag (in ) is exactly the same as the "type" attribute as shown in Figure 1. I didn't re-format it here for display purposes to emphasise the fact that the type attribute should be on one line in the Web.config file.
    All the pieces are now in place and you should be able to build the web service successfully.

    Client Security
    Using the earlier client, add a reference to System.Security via Solution Explorer. Add the following using directives to the top of the source file:
    using Microsoft.Web.Services.Security;
    using System.Web.Services.Protocols;
    using System.Security.Cryptography;
    using System.Security.
    Cryptography.Xml;

    The procedure for encrypting your request follows a simple pattern:
    Generate an EncryptionKey object
    Modify the SOAP proxy class's requestContext to use the EncryptionKey
    Call the service
    The WSE documentation for "Encrypting a SOAP message Using a Shared Secret" gives an implementation of a method called GetEncryptionKey, which uses TripleDES as the encryption algorithm. We'll run with this version, so all you need do is add the GetEncryptionKey method to your client code. I made a slight modification to the visibility of the GetEncryptionKey that is made private in the WSE documentation. I turned it into a public static method to facilitate ease of use from my console application's Main method.
    The complete procedure for the client console app is reproduced here to show how the above three steps are executed. The code forms the body of Main.

    // proxy class
    FactorialWse fs = new FactorialWse();

    // encryption key
    EncryptionKey key =
    Class1.GetEncryptionKey();

    // modifying requestContext to encrypt
    SoapContext requestContext =
    fs.RequestSoapContext;
    EncryptedData enc =
    new EncryptedData(key);
    requestContext.Security.Elements.Add(
    enc);
    requestContext.Timestamp.Ttl = 30000;
    //30 secs, avoid replay hacks

    // actually calling the web service
    int val = 6;
    int fac = fs.Calc(val);
    Console.WriteLine("Factorial of {0}
    is {1}", val, fac);

    WS-Attachments
    I need to send arbitrary binary data, and I may need to send it encrypted too, as it may contain personal or commercially sensitive information. WSE supports arbitrary transfer of binary attachments using DIME.
    To enable the web service to send an attachment using DIME, add the following using directive to FactorialService.asmx: using Microsoft.Web.Services.Dime;
    To actually send a binary attachment all you need do is add a DimeAttachment object to the Attachments collection of the SOAP response context. The DimeAttachment object wraps the binary data you wish to send. A code sample illustrates sending a GIF image file (roughly taken from the WSE documentation):

    // 1. Get response context
    SoapContext ctx =
    HttpSoapContext.ResponseContext;

    // 2. Create the dime attachment
    // object, wrapping the image file
    DimeAttachment att =
    new DimeAttachment(
    "image/gif", // MIME type
    TypeFormatEnum.MediaType,
    // media type enum
    @"c:\myimage.gif");
    // filename of image

    // 3. Add the DimeAttachment object
    // to the response
    ctx.Attachments.Add(att);

    That's it. In terms of our factorial web service, you can add a method that will return some binary data, call it, say, GetBinData. For the sake of consistency with the WSE documentation, let's stick to sending a binary image file for now. Add a public web services method to the factorial service like so:
    [WebMethod]
    public void GetBinData()
    {
    // body as above for sending GIF
    // image via DIME
    }

    To obtain some test data, just copy any GIF image you have locally to the root directory of the C drive and rename it to myimage.gif so that the web service can locate it. The client needs to be able to get the binary attachment from the SOAP message, a process that turns out to be relatively simple. The client looks at the Attachments collection of the ResponseSoapContext object exposed from the client's WSE proxy class. The WSE documentation shows a simple C# client application displaying the image in a picture window. The WSE sample application meets all the requirements of proving that WSE's WS-Attachments is working fine, so I won't produce a separate client for this article.
    Summary
    This article has looked at a readily available implementation of the two web services standards (WS-Security and WS-Attachments), and has hopefully given you a starting point from which you can expand your web service implementations on the .NET platform using WSE.

    This page is powered by Blogger. Isn't yours?