Strongly type properties with NHibernate

Written by Alexander. Posted in Uncategorized

I like NHIbernate and use it in all my projects. Now I am working on Atomic CMS – its a content management system project. I am working on sorting, but I don’t like to use strings for names of properties. I tried to find solution how to use strongly typed properties with NHibernate, but did not. So I created my own solution.

Instead of the code like this

session.CreateCriteria(typeof(IEntry)).AddOrder(Order.Desc("Alias"))

I prefer to have something like this

session.CreateCriteria(typeof(IEntry)).AddOrder(Order.Desc(x=>x.Alias))

But unfortunately it’s not possible with NHibernate. So I created simple solution which is fine for me and my project. I created class to return name of the method or property. The code using this class looks like this

session.CreateCriteria(typeof(IEntry)).AddOrder(Order.Desc(Strong<IEntry>.Name(x=>x.Alias)))

And the code for Strong class is.

namespace AtomicCms.Common.Utils
{
    using System;
    using System.Linq.Expressions;

    public static class Strong<T>
    {
        public static string Name(Expression<Func<T, object>> action)
        {
            if (null == action || null == action.Body)
            {
                throw new NullReferenceException("action or action.body is null");
            }

            UnaryExpression unary = action.Body as UnaryExpression;
            if (null != unary && null != unary.Operand as MemberExpression)
            {
                return PropertyName(unary.Operand);
            }

            MemberExpression memberCall = action.Body as MemberExpression;
            if (memberCall != null)
            {
                return PropertyName(action.Body);
            }

            MethodCallExpression methodCall = action.Body as MethodCallExpression;
            if (null != methodCall)
            {
                return MethodName(action.Body);
            }

            throw new Exception("Not supported action " + action);
        }

        private static string PropertyName(Expression operand)
        {
            MemberExpression member = operand as MemberExpression;
            if (member != null) return member.Member.Name;

            throw new NullReferenceException("Unxexpected null reference");
        }

        private static string MethodName(Expression operand)
        {
            MethodCallExpression member = operand as MethodCallExpression;
            if (member != null) return member.Method.Name;

            throw new NullReferenceException("Unxexpected null reference");
        }
    }
}

 

How to call WCF services from JavaScript jQuery and ASP.NET AJAX

Written by Alexander. Posted in Uncategorized

First we have to create a webapplication and add to it Ajax enabled WCF service.

Change default DoWork method to accept parameter

        [OperationContract]
        public string DoWork(string userName)
        {
            // Add your operation implementation here
            return "Hello " + userName;
        }

First add on the page input text control and two buttons.

        <input type="text" name="txtName" id="txtName" />
        <input type="button" value="jQuery call" onclick="cityClickJQuery();" />
        <input type="button" value="ASP.NET AJAX Call" onclick="cityClick();" />

First we will call this method with jQuery. So reference jQuery library and add this javascript function for calling WCF service

        function cityClickJQuery()
        {
            $.ajax({
                type: "POST",
                url: "http://localhost:65424/CityService.svc/DoWork",
                data: '{"userName":"'+$get("txtName").value+'"}',
                processData:false,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(data)
                {
                    alert(data.d);
                }
            });
        }

It’s very easy, you have to pass url with method, parameter (value from textbox) specify data type and callback function.

Now you can run webapplication, put some text in input box and press button “jQuery call”

image

 

Calling WCF service with Microsoft Ajax is much more easy. You do not to provide most of the properties like jQuery call.

        function cityClick()
        {
            CityService.DoWork($get("txtName").value, onSuccess);
        }

        function onSuccess(data)
        {
            if (data)
                alert(data);
        }

After pressing button, you will have the same result.

image

 

 

All source code can bi found below. I did not change web.config, so you can use default data generated by VisualStudio.

ASPX page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
    Inherits="WebApplication1._Default" %>

<!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 src="jquery-1.3.2.js" type="text/javascript"></script>
    <script src="jquery-1.3.2-vsdoc.js" type="text/javascript"></script>

    <script type="text/javascript">
        function cityClickJQuery()
        {
            $.ajax({
                type: "POST",
                url: "http://localhost:65424/CityService.svc/DoWork",
                data: '{"userName":"'+$get("txtName").value+'"}',
                processData:false,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(data)
                {
                    alert(data.d);
                }
            });
        }
        function cityClick()
        {
            CityService.DoWork($get("txtName").value, onSuccess);
        }

        function onSuccess(data)
        {
            if (data)
                alert(data);
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager runat="server">
            <Services>
                <asp:ServiceReference Path="~/CityService.svc" />
            </Services>
        </asp:ScriptManager>

        <div style="background-color:#eee;">

        <input type="text" name="txtName" id="txtName" />
        <input type="button" value="jQuery call" onclick="cityClickJQuery();" />
        <input type="button" value="ASP.NET AJAX Call" onclick="cityClick();" />
        </div>

    </div>
    </form>
</body>
</html>

 

C# code:

namespace WebApplication1
{
    using System.ServiceModel;
    using System.ServiceModel.Activation;

    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class CityService
    {
        // Add [WebGet] attribute to use HTTP GET
        [OperationContract]
        public string DoWork(string userName)
        {
            // Add your operation implementation here
            return "Hello " + userName;
        }

        // Add more operations here and mark them with [OperationContract]
    }
}

Migrate to new version Nhibernate 2.1.0 with Oracle database

Written by Alexander. Posted in Uncategorized

A couple of days ago new version of Nhibernate was released. You can download new version here

And if you migrate to this version and using Oracle database,
You will get this exception

Could not load type NHibernate.Dialect.OracleDialect. Possible cause: no assembly name specified

The reason is, you need specify not OracleDialect, but Oracle8iDialect, Oracle9iDialect, Oracle10gDialect, or OracleLiteDialect instead.
For example for oracle 10.x version you have to change dialect line in your hibernate.cfg.xml to this line

<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>

How to read data from app.config?

Written by Alexander. Posted in Uncategorized

It's simple, Just use ConfigurationManager class

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
      <add key="ApplicationPath" value="C:\MyProjects\TestProject\"/>
    </appSettings>
</configuration>

And to read data use this code

public static string AppPath()
{
return ConfigurationManager.AppSettings["ApplicationPath"];
}

Do not forget add reference to the System.Configuration

Eval vs Bind for ASP.NET

Written by Alexander. Posted in Uncategorized

When you start working with ASP.NET sometimes it’s difficult to understand what is the difference between Eval and Bind for data binding controls in ASP.NET.

If you just need to display data on the screen from DataSource it’s enough to use Eval. It’s something like read-only method from DataSource.

But if you need to edit data inside of Grid you have to use Bind method. Because it provides two way binding you can read data from DataSource and you can write data back.

Usually you have to use this methods if you need to quickly develop some WebPages and display and edit data from one table or simple view.

If you try to edit some row in Data Grid and want to make some changes in code behind class in OnUdpdating event, data with Eval method will not be available instead of Bind method.

<asp:GridView ID="GridView1" runat="server" CssClass="dataGrid"
   DataSourceID="SqlDataSource1" AllowPaging="True" AutoGenerateColumns="false"
  OnRowDeleting="grid_onRowDeleting" OnRowUpdating="GridView1_OnRowUpdating"
    AutoGenerateEditButton="true" AutoGenerateDeleteButton="true"
  PageSize="20" GridLines="None" Width="99%">
   <AlternatingRowStyle CssClass="odd" />
   <Columns>

       <asp:TemplateField HeaderText="App Id">
           <ItemTemplate>
               <asp:Label ID="lbl" runat="server" Text='<%#Bind("APP_ID") %>'></asp:Label>
           </ItemTemplate>
       </asp:TemplateField>

      <asp:TemplateField HeaderText="App name">
           <ItemTemplate>
               <%#Eval("APPLICATION_NAME")%>
           </ItemTemplate>
       </asp:TemplateField>
   </Columns>
</asp:GridView>
protected void GridView1_OnRowUpdating(object sender, GridViewUpdateEventArgs e)
{
   // if APP_ID in the grid bind with Eval method, it will be exception below
   // But if you use Bind instead of Eval it will be ok.
   rowToUpdate = e.NewValues["APP_ID"];
}
Technorati Tags: ,

How to use curly brackets inside of String.Format

Written by Alexander. Posted in Uncategorized

String.Format provides inserting variables inside of the string, indicated with curly brackets and index, for example

String s = string.Format"Hello {0}", name)

But if you need to use curly brackets inside of string format you will get exception, because compiler does not know if you trying to insert curly bracket or replacing string. So you can get exception

String s = string.Format("{name} = {0}", name); // exception

But there is a simple solution to avoid exception, you need to use double curly brackets.

String s = string.Format("{{name}} = {0}", name); // ok

ASP.NET Health Monitor with ASP.NET 3.5

Written by Alexander. Posted in Uncategorized

Health monitor is a system to monitor health of the application. It’s easy to add to your website and easy to use.

You can subscribe to some events occurred in the application, for example, “Error” and log it, or sent per email.

To add it you have to modify your web.config file, just add this lines of code in system.web section

<healthMonitoring enabled="true">
            <eventMappings>
                <clear/>
                <add
                    name="All Errors"
                    type="System.Web.Management.WebBaseErrorEvent,
                    System.Web, Version=2.0.0.0, Culture=neutral,
                    PublicKeyToken=b03f5f7f11d50a3a"
                    startEventCode="0"
                    endEventCode="2147483647"/>
            </eventMappings>
            <providers>
                <clear/>
                <add
                    name="mailWebEventProvider"
                    type="System.Web.Management.SimpleMailWebEventProvider"
                    from="name@test.com"
                    to="name@test.com"
                    buffer="false"
                    subjectPrefix="An error occurred: "/>
            </providers>
            <rules>
                <clear/>
                <add
                    name="Testing mail event provider"
                    eventName="All Errors"
                    provider="mailWebEventProvider"
                    profile="Default"
                    minInstances="1"
                    maxLimit="Infinite"
                    minInterval="00:01:00"
                    custom=""/>
            </rules>

        </healthMonitoring>

And add in your system.net section this code

<mailSettings>
            <smtp
                deliveryMethod="Network"
                from="name@test.com">
                <network
                    host="mailhost"
                    port="25"
                    defaultCredentials="true"/>
            </smtp>
        </mailSettings>

The explanation what this code does is very simple, firstly, in eventMapping section you subscribes to some event occurred in the application. There are a great deal of event which you can subscribe, you can find info about they in MSDN documentation.

Than in providers section you need to define provider, it can be email, database or some other provider. In my example I am using email provider, so all messages will be sent per email.

And than in rules section you have to bind events to providers.

Because I am using email provider, I have to define mailSettings settings in system.net section.

And it’s all. Now after error messages you will get the text like this:

** Application Information **
—————
Application domain: 8487b6cb-4-128819412246400827 Trust level: Full Application Virtual Path: /WebSite Application Path: C:\ProjectLocker\Trunk\LightCMS\WebSite\
Machine name: xxx

** Events **
—————
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 3/19/2009 4:00:29 PM
Event time (UTC): 3/19/2009 1:00:29 PM
Event ID: f6146a7781d34b9698cc5741b2aa75bd Event sequence: 15 Event occurrence: 1 Event detail code: 0

Process information:
    Process ID: 2420
    Process name: WebDev.WebServer.EXE
    Account name: xxx\xxx

Exception information:
    Exception type: System.DivideByZeroException
    Exception message: Attempted to divide by zero.

Request information:
    Request URL: http://localhost:7323/WebSite/CssVariables.aspx
    Request path: /WebSite/CssVariables.aspx
    User host address: 127.0.0.1
    User:
    Is authenticated: False
    Authentication Type:
    Thread account name: xxx\xxx

Thread information:
    Thread ID: 4
    Thread account name: xxx\xxx
    Is impersonating: False
    Stack trace:    at CssVariables.Button1_Click(Object sender, EventArgs e) in c:\ProjectLocker\Trunk\LightCMS\WebSite\CssVariables.aspx.cs:line 18
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Calling Oracle stored procedures from SQLDataSource

Written by Alexander. Posted in Uncategorized

For some simple pages in my application I prefer to use declarative manner of programming. To display some data on the page you can use this lines of code.

<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ProviderName="System.Data.OracleClient"
    SelectCommand="pac_dwh.Revew_item_info.GetAppPermissionInfoExt"
    SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:QueryStringParameter Name="p_line_id"
                  QueryStringField="lineId" />
        <asp:Parameter Name="p_res" Direction="Output" />
    </SelectParameters>
</asp:SqlDataSource>
<asp:FormView ID="FormViewContent" runat="server"
          DataSourceID="SqlDataSource1" >
        <ItemTemplate>
            <%# Eval("profile") %>
            <%# Eval("application_description") %>
        </ItemTemplate>
</asp:FormView>

But if you are using Oracle database you will get the error

System.Exception: Parameter 'p_res': No size set for variable length data type: String.

It’s because you can’t define type of parameter in DataSource, because it’s a Cursor, and Direction has no this type of data.

The solution is very simple, you just need to set datatype for the output parameter in OnSelecting event, like this:

<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ProviderName="System.Data.OracleClient"
SelectCommand="pac_dwh.Revew_item_info.GetAppPermissionInfoExt"
SelectCommandType="StoredProcedure"
OnSelecting="FixOracleRefCursorProblem_SqlDataSource1_Selecting">
    <SelectParameters>
        <asp:QueryStringParameter Name="p_line_id"
                  QueryStringField="lineId" />
        <asp:Parameter Name="p_res" Direction="Output" />
    </SelectParameters>
</asp:SqlDataSource>

and in cs file:

protected void FixOracleRefCursorProblem_SqlDataSource1_Selecting(object sender,
   SqlDataSourceSelectingEventArgs e)
{
    ((System.Data.OracleClient.OracleParameter)
    e.Command.Parameters[1]).OracleType = OracleType.Cursor;
}

And now it works :)

ASP.NET Charting Control

Written by Alexander. Posted in Uncategorized

Not a long time ago Microsoft charting controls was announced. It's a great controls. I used Syncfusion to make graphics, but it was too expensive. But now anybody can create graphics for free.

After installation this files there are new item in Data page in Visual studio toolbox.

image 
You need drag and drop it on the web page.

image

<asp:Chart ID="Chart1" runat="server">
            <series>
                <asp:Series Name="NumberOfEmployees" XValueMember="Year" YValueMembers="NumberOfPeople">
                </asp:Series>
            </series>
            <chartareas>
                <asp:ChartArea Name="ChartArea1">
                <AxisX LineColor = "Blue"></AxisX>
                <AxisY LineColor = "Purple"></AxisY>
                </asp:ChartArea>
            </chartareas>
        </asp:Chart>

As a DataSource it was used DataTable. Just add this code to Page_Load

                var table = new DataTable();
                table.Columns.Add("Year", typeof(int));
                table.Columns.Add("NumberOfPeople", typeof(long));
                table.Columns.Add("Lbl");
                var row = table.NewRow();
                row["Year"] = 2000;
                row["NumberOfPeople"] = 15;
                table.Rows.Add(row);
                row = table.NewRow();
                row["Year"] = 2001;
                row["NumberOfPeople"] = 35;
                table.Rows.Add(row);
               .......
                row = table.NewRow();
                row["Year"] = 2008;
                row["NumberOfPeople"] = 1390;
                table.Rows.Add(row);
                Chart1.DataSource = table;
                Chart1.DataBind(); 

After run the page you get this graphic.

image

To change the style you can add this code to the page load method

Chart1.Series["NumberOfEmployees"]["DrawingStyle"] = cbCilinder.Checked ? "Cylinder" : "Default"; 

And appearance for the graphic will be much more better.

image

Dependency injection design pattern

Written by Alexander. Posted in Uncategorized

Normally when designing some parts of the application, one classes is always depends on the other classes. For example, business logic classes (BL) are depend on data access classes (DAL). This dependence can be in very different ways, for example, BL can call static methods of DAL, or create instance of DAL every time it needs it… But in this case it’s can be difficulties to test business logic with Unit tests because it’s difficult or even impossible to create mocks to the database. To solve this problem you can use Dependency injection pattern. Here is example of how I am using it. Firstly create our classes for DAL:

public class ProductDAL
    {
        public virtual List<Product> GetProducts()
        {
            // connect to DB and get products
            return new List<Product>();
        }
    }

And for BL:

public class ProductBL
    {
        private readonly ProductDAL dal;

        public ProductBL(ProductDAL dal)
        {
            this.dal = dal;
        }

        public List<Product> GetProducts()
        {
            // Get products, make some manipulation with the products,
            // e.g. sorting, filtering...
            return dal.GetProducts();
        }
    }

For parameter in constructor in BL I passed instance of DAL, it’s Constructor injection. And it’s very easy to test this calls with Rhino mocks.

[TestFixture]
    public class ProductBLTests
    {
        [Test]
        public void GetProductsTest()
        {
            MockRepository mocks = new MockRepository();
            ProductDAL dal = (ProductDAL)mocks.StrictMock(typeof(ProductDAL));
            using (mocks.Record())
            {
                List<Product> expectedProducts = new List<Product>();
                Product p = new Product();
                p.Name = "Dell Pc";
                p.Id = 333;
                expectedProducts.Add(p);

                Expect.Call(dal.GetProducts()).Return(expectedProducts);
            }

            using (mocks.Playback())
            {
                ProductBL bl = new ProductBL(dal);
                List<Product> products = bl.GetProducts();
                Assert.AreEqual(1, products.Count);
            }

        }
    }

Some developers can say than Dependency Injection is a not good pattern for database layer and there are some another patterns for this purpose, but I like this solution, and successfully using it.