How to automatically generate SQL Stored procedure wrapper to deploy CLR Stored procedure?

Thursday, 12 February 2009 13:58 by harry

How to easily deploy CLR Stored Procedures without manually writting the SQL Script?

The answer is: You can do it all from Visual Studio 2008. 


Follow the following instructions:

1.    You need to open the server explorer window which has the database connections in it. Then you can right click on the database, and select "Publish To Provider".  A wizard will be displayed.



2.    Select the database you want.
3.    DESELECT the script all objects in selected database checkbox since you only want an SP script (this option is at bottom of window)



4.    Click next to continue
5.    Select "stored procedures" and then click next.



6.    Select All. Click next.
7.    Specify the file name that you want to write the output to. Click next.
8.    Click next few more times and finally click finish.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Creating a Workflow Custom Activity Validator that displays a red exclamation during error

Monday, 5 January 2009 12:53 by harry

I was just like you, trying to figure out why a red exclaimation or smart tag is not displayed for my custom activity validator. After searching in every corner of google, i found only one answer to this. We were all wrong by using

ValidationErrorCollection errorCollection = base.Validate(manager, obj);

The correct way is:

ValidationErrorCollection errorCollection = base.ValidateProperties(manager, obj);


If you are a starter, here is how you create a custom activity validator.

1. Create the validator class (Not a Activity). The class must inherit from the System.Workflow.ComponentModel.Compiler.ActivityValidator class. For example


namespace Unemployment.Workflow.Activities.Validators
{
   
public class ClaimantValidator : ActivityValidator
   
{
       
/// <summary>
       
/// Validate the claimant ssn and claimant guid
       
/// </summary>
       
/// <param name="manager"></param>
       
/// <param name="obj"></param>
       
/// <returns></returns>

        public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
       
{
           
CreateAnEmptyClaimantActivity activity = obj as CreateAnEmptyClaimantActivity
           
ValidationErrorCollection errorCollection = base.ValidateProperties(manager, obj); 

            if (activity.Parent != null)
            {
               
if(!activity.IsBindingSet(CreateAnEmptyClaimantActivity.ClaimantSsnProperty))
               
{
                   
if (String.IsNullOrEmpty(activity.ClaimantSsn))
                   
{
                       
errorCollection.Add(
                       
ValidationError.GetNotSetValidationError("ClaimantSsn"));
                   
}
               
}

               
if(!activity.IsBindingSet(CreateAnEmptyClaimantActivity.ClaimantGuidProperty))
               
{
                   
if (activity.ClaimantGuid == Guid.Empty)
                   
{
                       
errorCollection.Add(
                       
ValidationError.GetNotSetValidationError("ClaimantGuid"));
                   
}
               
}   
           

            return errorCollection;
        }
   
}

}
 

The CreateAnEmptyClaimantActivity is a custom activity.

2. Add the attribute. In the activity class of  CreateAnEmptyClaimantActivity add an ActivityValidator attribute, specifying the type name for the ActivityValidator class (ClaimantValidator). This connects the activity and its validator

namespace Unemployment.Workflow.Activities.Shared
{
   
  [ActivityValidator(typeof(ClaimantValidator))]
     
public partial class CreateAnEmptyClaimantActivity: Activity

     
{
      ....
      //your code for the custom activity belongs here
     
}
}
 

That's pretty much it. Now, if property is not set, you'll see the compilation error in the error window as well as a red exclamation / smart tag on your custom activity.

It helped me and I hope that it will help you as well. Good luck.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

TypedDataSet DBNULL as default value in DAL together with GridView and Labels

Tuesday, 30 December 2008 05:06 by harry

The Story:

My TypedDataSet are following the standard pattern where all of the columns will have the value of <DBNULL>, and the NullValue is set to (Throw exception).



This pattern applies for all DataType, no exceptions!

The Persistence Layer

1. Saving to the Database

For each of the column in every row, except the primary key, I check if row.IscreatedateNull(). if null the I set the SqlParam to DBNull.Value, otherwise I pass the value from row.createdate. 

2. Reading from the Database

Instead of checking if the column is null, I check if the DataReader for the current index is null or not.

if (!reader.IsDBNull(++idx)) row.createdate = reader.GetString(idx);

 

The Presentation Layer

I have a simple GridView, and label to test the Dataset null behavior. Here is the code that i used

protected void Page_Load(object sender, EventArgs e)
{
   
NullDs ds = new NullDs();
   
NullDs.DataTable1Row row = ds.DataTable1.NewDataTable1Row();
   
row.sequence = 1;

    //notice that the create date is set to dataset DBNULL
   
row.SetcreatedateNull();

    row.description = "some string"

    ds.DataTable1.AddDataTable1Row(row);

    //The result of the dataset will nulll works fine in GridView without
   
// making any code changes at all in GridView, it smart enough to not read the null column

    GridView1.DataSource = ds;
   
GridView1.DataBind(); 

    try
   
{
       
//This throw exceptions since we literaly call the CreateDate column which null
       
Label1.Text = row.createdate.ToShortTimeString();
   
}
   
catch (Exception)
   
{
   
}   

    //The correct way is the following, where we always check if create date is null
    // if not then read the column.
   
Label1.Text = row.IscreatedateNull() ? "" : row.createdate.ToShortTimeString();

}
 

Sample

DataSetDBNull.zip (4.95 kb) is the sample website application that tests the dataset null behavior in GridView and Labels. It contains the above code.

Conclusion

Now, you have a standard pattern to you with your TypedDataSet without any exceptions for any datatype. You no longer need to set it to DateTime.MinValue, Int.MinValue, Double.MinValue anymore. Using the auto generated functions of typed dataset save me from troubles. I hope that the next version of TypeDataSet will allow nullable for all of the datatypes.

Until then, Good luck and I hope this will help you.

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   .Net 3.5
Actions:   E-mail | Permalink | Comments (131) | Comment RSSRSS comment feed

Generate WCF Client using svcutil with nettcpbinding

Monday, 17 November 2008 09:13 by harry

The following is the example of the service configuration that exposing the metadata. I’ve bold the new configurations.

<?xml version="1.0"?>

<configuration>

  <system.serviceModel>

    <services>

      <service behaviorConfiguration="WcfBehavior" name="WCF.Overpayment.OverpaymentPersistenceService">

        <endpoint address="net.tcp://localhost:5000/OverpaymentService"

          binding="netTcpBinding" bindingConfiguration="netTcpBindingConf"

          contract="WCF.Overpayment.IOverpaymentPersistenceService" />

        <endpoint address="mex" binding="mexTcpBinding" name="MEX" contract="IMetadataExchange" />

        <host>

          <baseAddresses>

            <add baseAddress="net.tcp://localhost:5000/OverpaymentService" />

          </baseAddresses>

          <timeouts closeTimeout="00:00:10" />

        </host>

      </service>

    </services>

    <bindings>

      <netTcpBinding>

        <binding name="netTcpBindingConf" transactionFlow="true" maxReceivedMessageSize="10000000">

          <security mode="None" />

        </binding>

      </netTcpBinding>

    </bindings>

    <behaviors>

      <serviceBehaviors>

        <behavior name="WcfBehavior">

          <serviceDebug includeExceptionDetailInFaults="true" />

          <serviceMetadata />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Once you've set up this configuration, you'll be able to use the Visual Studio Command Prompt and type

svcutil net.tcp://localhost:5000/OverpaymentService

 

You should see the following

C:\temp\OverpaymentPersistenceService.cs
C:\temp\output.config

C:\temp>svcutil net.tcp://localhost:5000/OverpaymentService
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.648]
Copyright (c) Microsoft Corporation.  All rights reserved.

Attempting to download metadata from 'net.tcp://localhost:5000/OverpaymentServic
e' using WS-Metadata Exchange. This URL does not support DISCO.
Generating files...
C:\temp\OverpaymentPersistenceService.cs
C:\temp\output.config

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   WCF
Actions:   E-mail | Permalink | Comments (327) | Comment RSSRSS comment feed

How to optimize the disk I/O of SVN (TSVNChace.exe) from being too slow

Monday, 15 September 2008 04:05 by harry

I've been working with SVN for few years, and today one of my coworkers complained to me related to the slow performance of his SVN. My answer was simple; "SET the include and exclude folder locations of your SVN".
After he followed my suggestion, the disk performance improved a lot. I've decided to share this with you.

The problem is related to the SVN that tries to overlay the SVN icons on every file in your computer.

Here is the screenshot from my SVN (version 1.5.3)



Here is the step by step

1. Right click on your desktop and select "TortoiseSVN -> Settings"
2. In the left side, click on the "Icon Overlays"
3. Specify the exclude paths: if you have multiple drive then you can enter all of them. In my case, I specify "C:\*". Make sure you add the * to exclude the sub directories.
4. Specify the include paths. This should be your SVN working directories. if you have multiple then you can enter all of them in a new line. In my case, since my SVN working folders are in C:\hyperion and my desktop, then I enter all of them.
5. Click OK to apply the changes
6. Kill the TSVNChace.exe from your Taskmanager to restart the SVN.

Thanks to SVN developer that allow us to configure this :)

I hope this will improve your performances at work.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   SVN
Actions:   E-mail | Permalink | Comments (73) | Comment RSSRSS comment feed

Model View Controller (MVC) and SOA Architecture Diagram

Thursday, 5 June 2008 10:48 by harry

As you can see, below is the architecture diagram of my projects. Using the MVC (Model View Controller) architecture pattern and Service Oriented Architecture (SOA) for the services, it allows my team to build very robust and highly scalable enterprise applications.

 

Currently rated 2.8 by 4 people

  • Currently 2.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   , ,
Categories:   MVC | SOA
Actions:   E-mail | Permalink | Comments (492) | Comment RSSRSS comment feed

How to: Build System.AddIns using Pipeline Builder

Friday, 4 April 2008 11:56 by harry

I'm creating a requirement specifications for 1 of my components, and I've found that people might be struggling with the new System.AddIns from .Net Framework 3.5. Here is a step by step walkthrough that I created to help to get you start with System.AddIns. There are several problems that I faced earlier, so please read it carefully, play around with the sample file and have fun. 

1         Creating the Addin Contract

1.1         Add reference to System.AddIn.Contract

1.2         Add reference to the pipeline hint

Mine can be located at

C:\WINDOWS\assembly\GAC_MSIL\PipelineHints\1.0.0.0__3546f02f48709321\PipelineHints.dll

1.3         Add reference to for other assembly (TopCoder.Services.WCF.GenericNotes.dll)

1.4         Set the output project of your contract to the output\Contracts 

using System;
using
System.AddIn.Contract;
using
System.AddIn.Pipeline;
using
System.Web;
using
System.Collections.Generic;
using
TopCoder.Services.WCF.GenericNotes.Entities;
 

//These attributes indicate the assembly name we want to use for each of our components
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.HostView, "Hyperion.AspNet.Narratives.AddIns.HostView")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.AddInView, "Hyperion.AspNet.Narratives.AddIns.AddInView")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.HostSideAdapter, "Hyperion.AspNet.Narratives.AddIns.HostSideAdapters")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.AddInSideAdapter, "Hyperion.AspNet.Narratives.AddIns.AddInSideAdapters")] 
namespace
Hyperion.AspNet.Narratives.AddIns.Contracts
{
    /// <summary>
   
/// This interface defines the contract between the host and the add-in, and
   
/// therefore cannot be versioned.
   
/// </summary>
   
[AddInContract]
    public interface INarrativesContract : IContract
    {
        IList<GenericNote> GetNarratives(Guid uniqueId);
        void SaveNarrative(GenericNote note, Guid uniqueId);
   
}
}

Note: make sure you can build the solution and project successfully before running the pipeline builder

2         Running the pipeline builder

Go to Tool -> PipelineBuilder

Once you have successfully run the pipeline builder, you should see 4 new projects created in your solution explorer

3         Set up the build location.

This example, I put the output folder as a sibling folder to the project folder.

4         AddInView

Since I’m using the 3rd party dll (GenericNote.dll), I have to set the local copy = true. Both host project and AddInView projects are the only projects where you have to set the local copy = true. You don’t need to change any thing on the local copy of auto generated projects for addins.

If you get any errors, make sure that all of the dependent components that GenericNote used are also copied in the AddInView. I notice that generic note needs configuration manage, exception manager, logging wrapper, object factory, self documenting exception and wcf service. Therefore all of these dlls needs to go to the AddInView folder as well.

5         References for GenericNote for other projects

Add references for other addins projects that needed. However set the Local Copy = false

Make sure that the reference to the GenericNote of the Contract project is set to Local Copy = false

6         Implementing the AddIn

Create a new project, and add reference to your AddInView project. Make sure the local copy is set to false. Also add a reference to GenericNote and also set the local copy = false. Finally, add the reference to System.AddIn in order to make it work

The output of this project must be placed under a AddIns folder under output folder, and then you create another folder that descripe your addIns implementation. The folder name of “ClaimantNarrative” don’t have to match as long as the parent folders are correct

Don’t forget to mark the AddIn with AddIn attribute.

And here is my code

using System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.AddIn;
using
TopCoder.Services.WCF.GenericNotes.Entities;

namespace Hyperion.AspNet.Narratives.Claimant{

    [AddIn("ClaimantNarrative Addin", Description = "ClaimantNarrative Addin Description",
           Publisher = "Harry Soetardjo", Version = "1.0.0.0")]

    public class ClaimantNarrative : Hyperion.AspNet.Narratives.INarratives
   
{
        public IList<GenericNote> GetNarratives(Guid uniqueId)
        {
            throw new NotImplementedException();
        }
        public void SaveNarrative(GenericNote note, Guid uniqueId)
        {
            throw new NotImplementedException();
        }
    }
}

7         Host

Reference Settings:

Only need to reference to HostView project. And set local copy = false

Set the reference of local copy = true for the 3rd party dll (in this example, The TopCoder.WCF.GenericNotes is being used as 3rd party dll)

The output of the Host project must be pointed to the output folder specified for the AddIns, therefore it needs to go to the “output folder”

 
The final set is to add the referece to System.AddIn

Test the host by using this following code (done in the console application). You can also use the web application to be the host or even WCF service to be the host of the AddIns

 
using
System;
using
System.AddIn.Hosting;
using
System.Collections.ObjectModel;

 
namespace
Host
{
    class Program
   
{
        static void Main(string[] args)
        {

            // Set the add-ins discovery root directory to be the current directory
          
string addinRoot = Environment.CurrentDirectory;

             // Rebuild the add-ins cache and pipeline components cache.
           
string[] results = AddInStore.Rebuild(addinRoot);
            foreach (string s in results)
            {
                Console.WriteLine(s);
           

            // Get registerd add-ins of type SimpleAddInHostView
           
Collection<AddInToken> addins = AddInStore.FindAddIns(typeof(Hyperion.AspNet.Narratives.INarratives), addinRoot); 

            foreach (AddInToken addinToken in addins)
            {
                // Activate the add-in
              
Hyperion.AspNet.Narratives.INarratives addinInstance = addinToken.Activate<Hyperion.AspNet.Narratives.INarratives>(AddInSecurityLevel.Internet);

                 // Use the add-in
               
Console.WriteLine(String.Format("Add-in {0} Version {1}", addinToken.Name, addinToken.Version));
                addinInstance.SaveNarrative(null, Guid.NewGuid());

           

            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();

        }
    }
}

Why my AddIns does not work, check these following items

1.      If you use any other dll, the class /entity must be marked as Serializable

2.      For Host project make sure you set the output of your project to the root of output folder.

3.      Make sure that the Addins attributes are added correctly on the AddIns, AddInSideAdapter, HostSiteAdapter

4.      Make sure all of the dependent component dll are available in the AddInViews as well as root of output folder. For example all of the dependent components that generic note used are also copied there.

References

  1. Pipeline Builder - Download the latest one
    http://www.codeplex.com/clraddins


  2. Different Approaches to Add-In Discovery [Jesse Kaplan]
    http://blogs.msdn.com/clraddins/archive/2007/01/26/different-approaches-to-add-in-discovery.aspx

  3. Reflection Problem - Dependent Component
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2327543&SiteID=1

Download the project file

This download file is used for educational purpose only and provided as-is. I hope it helps you to get started with System.AddIns and enjoy it as much as I do.

System.AddIns.zip (515.21 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

How to: Build an N-Tier application with WCF and DataSets in Visual Studio 2008

Thursday, 27 March 2008 04:16 by harry

Read this following blog if you want to use DataSet with WCF. This also allow show you on how to separate the DataSet Entity and Table Adapter in separate projects.

I love TypeDataSet!!! and of course WCF :)

 

His post is very detail, step by step including the source code for building a blog application 

How to: Build an N-Tier application with WCF and DataSets in Visual Studio 2008

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories:   .Net 3.5 | SOA | WCF | Blog
Actions:   E-mail | Permalink | Comments (162) | Comment RSSRSS comment feed

ASP.NET 2.0's URL Mapping Rewriting Extension-less

Wednesday, 26 March 2008 03:18 by harry

URL Mapping

The URL Mapping allow you to map one set of URLs to another. The default URL Mapping of ASP.Net 2.0 up to 3.5 Framework allow you to set the URL Mapping easily in the web.config. The real world example is a web application needs to display all of their product cell phone brands and needs to be able to tell the customer that the url to their website for a particular catefory is http://www.yoursite.com/nokia.aspx; as you expected that this store sells more than just one brands. this store also sells htc, samsung, lg and etc. and we all know that behind the scene everything is only one page with the query string to display a specific brand ~/ProductsByBrands.aspx?categoryname=nokia.

Let's get start it modifying the web.config

<?xml version="1.0"?>
<configuration>
    <system.web>
    <urlMappings enabled="true">
      <add
         url="~/nokia.aspx"
         mappedUrl="~/ProductsByBrands.aspx?categoryname=nokia" />
      <add
         url="~/lg.aspx"
         mappedUrl="ProductsByBrands.aspx?categoryname=lg" />
    </urlMappings>
    </system.web>
</configuration>

That's it, try to run it and trust me it will work; However, one thing that i found out was after the post back, the URL on the browser will be changed to the actual page. But don't worry, I have the solution. Just keep reading

Extention-less

It's also easy, on you web.config remove the extention from the "url" node. You still have the keep the extention for the "mappedUrl"

Keep the same URL address during postback

I've warned you before that the user posting back to the page, the address url will display the mappedUrl address. it's not cool, but again we have the solution. So what we need to do is to override the form's action.

1. Add a App_Browser folder

After you add the folder, you need to create a browser file. you can name it as Form.Browser. and paste the following code

<browsers>

  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
               adapterType="FormRewriterControlAdapter" />
    </controlAdapters>
  </browser>

</browsers>

2. Add a App_Code folder

Most likely, you've this folder. You need to add new file FormRewritter.cs

using System.Web;
using System.Web.UI;

public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        base.Render(new RewriteFormHtmlTextWriter(writer));
    }
}

public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
    public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
        : base(writer)
    {
        this.InnerWriter = writer.InnerWriter;
    }

    public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
        : base(writer)
    {
        base.InnerWriter = writer;
    }

    public override void WriteAttribute(string name, string value, bool fEncode)
    {
        if ((name == "action"))
        {
            HttpContext Context;
            Context = HttpContext.Current;

            if (Context.Items["ActionAlreadyWritten"] == null)
            {
                value = Context.Request.RawUrl;
                Context.Items["ActionAlreadyWritten"] = true;
            }
        }

        base.WriteAttribute(name, value, fEncode);
    }
}

3. That's it

Now, you'll have a working URL Rewritting. It's SIMPLE, CLEAN and bottom line it does its jobs.

4. Regex and Credits

Rather than do it yourself, I'd recommend using one of the already built HttpModules available on the web for free to perform this work for you.  Here a few free ones that you can download and use today:

As always, the Scott Gu has more options available on his blog.

 

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Microsoft ASP.NET 3.5 MVC Source Code Now Available

Monday, 24 March 2008 13:26 by harry

Click here to read the article by Scott Guthrie, source code is available here.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   , ,
Categories:   .Net 3.5 | MVC
Actions:   E-mail | Permalink | Comments (31) | Comment RSSRSS comment feed