European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European SQL 2012 Hosting - Amsterdam :: SQL Server 2012 Integration Services with HostForLIFE.eu

clock December 24, 2012 05:57 by author Scott

SQL Server 2012 Integration Services introduces an innovative approach to deploying SSIS projects, known as Project Deployment Model. This is the default and recommended deployment technique, due to a number of benefits it delivers (such as, the ability to centralize management of package properties across deployed projects, as well as monitor and log package execution performance and progress). However, even though the new model has become the recommended and default configuration for new packages created using SQL Server Data Tools, the traditional, package-based methodology remains available and supported. More importantly, in some scenarios, it might be considered a more viable option, since it allows for separation of SQL Server Database Engine and SQL Server Integration Services roles, yielding performance benefits and facilitating a distributed extraction, transformation, and loading (ETL) activities. Project Deployment Model, on the other hand, requires SSIS to be collocated on a SQL Server 2012 instance, due to its dependency on SSIS catalog. We will discuss its characteristics and walk through its implementation in this post.

Reporting Services 2008 for Internet deployment

The deployment method available from a SQL Server Data Tools-based project is directly dependent on the model employed during its creation (it is also possible to switch between two models after a project is created by applying a conversion process, which is invoked from the Project menu in SQL Server Data Tools). Effectively, in order to use the traditional package deployment mechanism, you will need to first ensure that your project is based on the package deployment model, which you can easily identify by checking its label in the Solution Explorer window.

In addition, you will also have to modify default project properties. To access them, right-click on the node representing the project in the Solution Explorer window and select the Properties entry from its context sensitive menu. In the resulting dialog box, switch to the Deployment section, where you will find three settings displayed in the grid on the right hand side:

AllowConfigurationChanges – a Boolean value (i.e. True, which is the default, or False) that determines whether it will be possible to choose package configurations during its deployment and assign values of properties or variables they reference.

CreateDeploymentUtility – a Boolean value (True or False, which is the default) that indicates whether initiating the project build will result in the creation of its Deployment Utility.

DeploymentOutputPath – a path that points to the file system folder where the Deployment Utility will be created. The path is relative to the location where project files reside (and set, by default, to bin\Deployment).

Set the value of the CreateDeploymentUtility property to True and modify AllowConfigurationChanges according to your requirements (e.g. set it to False if your project does not contain any package configurations or you want to prevent their modifications during deployment). Next, start the build process (using the Build item in the top level main menu of SQL Server Data Tools), which will populate the output folder (designated by DeploymentOutputPath parameter) with the .dtsx package file (or files, depending on the number of packages in your project), an XML-formatted Deployment Manifest file (whose name is constructed by concatenating the project name and .SSISDeploymentManifestsuffix) and, potentially, a number of other, project related files (representing, for example, custom components or package configurations).

The subsequent step in the deployment process involves copying the entire content of the Deployment Output folder to a target server and double-clicking on the Deployment Manifest file at its destination. This action will automatically launch the Package Installation Wizard. After its first, informational page, you will be prompted to choose between File system and SQL Server deployments.

The first of these options creates an XML-formatted file (with extension .dtsx) in an arbitrarily chosen folder. If the project contains configuration files (and the AllowConfigurationChanges project property was set to True when you generated the build), then you will be given an option to modify values of properties included in their content. At the end of this procedure, the corresponding .dtsConfigfiles will be added to the target folder.

The second option, labeled SQL Server deployment in the Package Installation Wizard relies on a SQL Server instance as the package store. Once you select it, you will be prompted for the name of the server hosting the SQL Server Database Engine, an appropriate authentication method, and a path where the package should be stored. If you want to organize your packages into a custom folder hierarchy, you will need to pre-create it by connecting to the Integration Services component using SQL Server Management Studio. In case your package contains additional files (such as package configurations), you will also be given an opportunity to designate their location (by default, the wizard points to Program Files\Microsoft SQL Server\110\DTS\Packagesfolder).

In either case, you can decide whether you want to validate packages following their installation (which will append the Packages Validation page to the Package Installation Wizard, allowing you to identify any issues encountered during deployment). In addition, when using SQL Server deployment, you have an option to set a package protection level (resulting in assignment of ServerStorage value to the ProtectionLevel package property). When deploying to file system, this capability is not available, forcing you to resort (depending on the deployment target) to either NTFS permissions or SQL Server database roles for securing access to your packages and sensitive information they might contain.

Just as in earlier versions of SQL Server, local SQL Service Integration Services 11.0 instance (implemented as the MSDTSServer110 service) offers the ability to manage packages stored in the MSDB database and file system, providing you with additional benefits (such as monitoring functionality), which we will discuss in more detail in our upcoming articles. In the case of MSDB storage, this is accomplished by following the SQL Server deployment process we just described and is reflected by entries appearing under the MSDB subfolder of the Stored Packages folder of Integration Services node when viewed in SQL Server 2012 Management Studio. In the same Storage Packages folder, you will also find the File System subfolder containing file system-based packages that have been identified by the SSIS service in the local file system. By default, the service automatically enumerates packages located in Program Files\Microsoft SQL Server\110\DTS\Packages directory, however, it is possible to alter this location by editing the Program Files\Microsoft SQL Server\110\DTS\Binn\MsDtsSrvr.ini.xml file and modifying the content of its StoragePath XML element. Incidentally, the same file controls other characteristics of MSDTSServer110 service, such as, package execution behavior in scenarios where the service fails or stops (by default, the execution is halted) or location of target SSIS instances (defined using the ServerName XMLelement).

While the Package Installation Wizard is straightforward to use, it is not well suited for deploying multiple packages. This shortcoming can be remedied by taking advantage of the DTUtil.exe command line utility, which in addition to its versatility (including support for package deployment and encryption), can also be conveniently incorporated into batch files. Its syntax takes the form DTUtil /option [value] [/option [value]] …, pairing option names with the values associated with them. For example, /SQL, /FILE, or /DTS options designating the package storage type (SSIS Package Store, File System, and MSDB database, respectively) can be combined with a value that specifies package location (as a relative or absolute path). By including COPY, MOVE, DELETE, or EXISTS options (with a value identifying package location) you can effectively copy, move, delete, or verify the existence of packages across all package stores.

In conclusion, the traditional package deployment methods available in earlier versions of SQL Server Integration Services are still supported and fully functional in the current release. However, in most scenarios, you should consider migrating your environment to the latest Project Deployment Model due to a wide range of advantages it delivers.



European ASP.NET 4.5 Hosting - Amsterdam :: Web Sockets and How to Develop HTML5 Web Sockets in ASP.NET 4.5

clock December 20, 2012 05:02 by author Scott

HTML5 WebSockets allow you to perform two-way (duplex) communication between the client browser and the server. ASP.NET 4.5 and IIS 8 provide support for WebSocket protocol so that you can program WebSockets in your ASP.NET web forms and ASP.NET MVC applications. This article discusses what WebSockets are and how to develop web applications that take advantage of HTML5 WebSockets.

Overview of HTML5 Web Sockets

Typically a communication over the web is comprised of two distinct parties participating in the communication, viz. the client and the web server. An ordinary web page uses a request-response model of communication wherein the browser sends a request to the server and the server then sends back a response. Each request and response uses a new connection and that connection is closed once the response is returned by the server. As you might have guessed, such a communication is poor in terms of performance since a new connection is established between the same client and the server every time. Additionally, such a communication can't be two way, i.e. client talking to server and server talking to the client simultaneously.

In the case of two-way or duplex communication both the parties participating in the communication can communicate at the same time. A common application of the duplex communication is chat systems such as MSN or Yahoo Messenger and Google Talk. In any chat system, two or more members can chat with each other at the same time. As far as HTML5 is concerned, the technique to achieve two way communications is Web Sockets.

Unlike the request-response model, WebSockets keep the underlying communication channel open throughout the course of communication. A WebSocket based communication typically involves three steps:

- Establishing a connection between the client and the server or Hand Shake.
- Asking the Web Socket server to listen to the incoming communication
- Sending and receiving data

Web applications use HTTP protocol for their functioning and HTTP protocol essentially makes use of the request-response model. The plain HTTP protocol isn't well suited for performing two-way communications. The WebSockets therefore, need to "upgrade" the plain HTTP protocol to WebSocket protocol. This "upgrade" takes place while establishing the connection between the client and the server. In order to upgrade the communication from plain HTTP to WebSocket, you need a web server that is capable of doing this upgrade.

Enabling WebSocket Protocol in Windows 8

As far IIS is concerned, IIS 8.0 that ships with Windows 8 is capable of accepting Web Socket communications. If you are developing a web application that makes use of HTML5 Web Sockets, you may need to install WebSocket support in IIS 8.0. The following figure shows the "Turn Windows features on or off" option from the control panel. It can be used to install WebSocket protocol.



Notice how the "WebSocket Protocol" feature is checked under "World Wide Web Services". If the IIS installation doesn't have WebSocket protocol enabled your ASP.NET applications won't be able to receive and respond to the WebSocket requests on the server.

A WebSocket based application consists of two parts, viz. WebSocket server side code and WebSocket client side code. The WebSocket server side code sits on the web server and "listens" to the incoming communication from clients. When some communication is received from the client it processes the communication and typically sends some communication back to the client. If there is no communication from the client the WebSocket server can either keep waiting for the communication or can terminate the communication channel. The WebSocket client side code makes use of the WebSocket object of HTML5 for the purpose of sending and receiving data to and from the WebSocket server side code.

The WebSocket client side code follows the same coding pattern regardless of your web server software. As far as ASP.NET is concerned, IIS 8 and certain .NET framework classes together allow you to develop WebSocket server side functionality. To understand how the client side and server side code goes hand in hand let's develop a simple application that performs a two-way communication. The web form that acts as a WebSocket client is shown below:



Using the above web form you can send a text message from the client to the server. The server then sends the same message back to the client (this is purely for the sake of simplicity and testing purposes. You can send any other data from the server. Clicking on the Stop button stops the server and no further communication can take place between the client and the server.

Coding the Client Side

Open the default web form and add the following jQuery code to a <script> block:

var socket;
$(document).ready(function () {
    socket = new WebSocket("ws://localhost:1046/WebSocketGenericHandler.ashx");
    socket.addEventListener("open", function (evt) {
      $("#divHistory").append('<h3>Connection Opened with the Echo server.</h3> ');},
    false);  
    socket.addEventListener("message", function (evt) {
      $("#divHistory").append('<h3^gt;' + evt.data + '</h3> ');   },
    false);  
    socket.addEventListener("error", function (evt) {
      $("#divHistory").append('<h3>Unexpected Error.</h3> ');},
    false);
    ...
});


The code shown above declares a global variable named socket to hold a reference to a WebSocket object. A WebSocket instance is then created by passing the URL of the WebSocketHandler.ashx. The WebSocketHandler.ashx contains the WebSocket server side code that "listens" to the client requests. You will develop WebSocketHandler.ashx later in this article. Notice how the URL uses ws:// protocol instead of http://. Next, event handlers for the three events, viz. open, message, and error, are wired using the addEventListener() method. The open event is raised when the readyState property (discussed next) changes to 1 (OPEN) and indicates that the connection is ready to send and receive data. The message event is raised when a message is received from the WebSocket server. The error event is raised when an error occurs during the communication with the Web Socket server.

Inside the message event handler the data sent by the server is retrieved using the evt.data property. The returned data is then appended to a <div> element. The other event handlers simply output the specified messages in the <div> element. The data from the client is sent to the server when the Send button is clicked. The click event handler of the Send button looks like this:

$("#btnSend").click(function () {
    if (socket.readyState == WebSocket.OPEN) {
        socket.send($("#txtMsg").val());
    }
    else {
        $("#divHistory").append('<h3>The underlying connection is closed.</h3> ');
  }
});


The click event handler of the Send button checks the readyState property of the WebSocket object. If the readyState is OPEN, it calls the send() method on the WebSocket instance. This read only property returns the current state of the connection. Possible values are 0 - CONNECTING, 1 - OPEN, 2 - CLOSING, 3 - CLOSED. The send() method sends data to the WebSocket server side code over an established connection. The text entered in the textbox is passed as a parameter to the send() method.

You can close the underlying connection by calling the close() method of the WebSocket object as follows:

$("#btnStop").click(function () {
  socket.close();
});

Coding the Server Side

The WebSocketHandler.ashx contains the server side code that listens and responds to the client requests. This code is shown below:

public class WebSocketHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            context.AcceptWebSocketRequest(DoTalking);
        }
    }
    ...
}


The above code shows an ASP.NET generic handler - WebSocketHandler - that triggers the WebSocket server. The ProcessRequest() method of the generic handler first checks whether the incoming request is a WebSocket request. This is done by checking the IsWebSocketRequest property of the HttpContext object. This property works hand-in-hand with the IIS 8.0 WebSocket module and returns true if an incoming request is a WebSocket request. A Web Socket request is different than an ordinary HTTP request in that instead of using http:// protocol it uses ws:// (Web Socket) protocol.

If the IsWebSocketRequest returns true, the AcceptWebSocketRequest() method of the HttpContext is called. This method takes one parameter - user function - that supplies a function that listens and responds to the client requests. In this case the user function contains the logic to listen to the incoming data and send it back to the client. The user function supplied to the AcceptWebSocketRequest() method should be an asynchronous function as shown below:

public async Task DoTalking(AspNetWebSocketContext context)
{
    WebSocket socket = context.WebSocket;
    while (true)
    {
        ArraySegment buffer = new ArraySegment(new byte[1024]);
        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
        if (socket.State == WebSocketState.Open)
        {
            string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            userMessage = "You sent: " + userMessage + " at " +  DateTime.Now.ToLongTimeString();
            buffer = new ArraySegment(Encoding.UTF8.GetBytes(userMessage));
            await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
        else
        {
            break;
        }
    }
}


The DoTalking() method is marked as "async" indicating that the code inside it is going to run in asynchronous fashion. The DoTalking() method returns a Task object. The Task class acts as a wrapper to the asynchronous code. The DoTalking() method receives a parameter of type AspNetWebSocketContext. The AspNetWebSocketContext class gives you access to the WebSocket through its WebSocket property. The WebSocket class is the server side counterpart of the HTML5 WebSocket object. An endless while loop is then started so that the server can continuously listen to the incoming requests. To receive the incoming data, the ReceiveAsync() method of the WebSocket class is used. The ReceiveAsync() method is invoked along with the await operator. In this case the awaited task is to receive incoming data and store it in an ArraySegment, a byte array. The results of the receive operation are stored in WebSocketReceiveResult object. If the WebSocket is open as indicated by the State property, the received data is sent back to the client using the SendAsync() method. If the State property has any value other than Open, the while loop is exited thus terminating the server.

Summary

HTML5 WebSockets allow you to perform two-way (duplex) communication. To use HTML5 WebSockets in an ASP.NET application you need to enable the WebSocket protocol in IIS 8.0. You can then use IsWebSocketRequest property and AcceptWebSocketRequest() method to start the client-server communication. Using WebSockets, you can develop web applications such as Chat systems that require the ability to send and receive data simultaneously between the client and the server.

 



European World-Class Windows and ASP.NET Web Hosting Leader - HostForLIFE.eu

clock December 18, 2012 07:10 by author Scott

Fantastic and Excellent Support has made HostForLife.eu the Windows and ASP.NET Hosting service leader in European region. HostForLife.eu delivers enterprise-level hosting services to businesses of all sizes and kinds in European region and around the world. HostForLife.eu started its business in 2006 and since then, they have grown to serve more than 10,000 customers in European region. HostForLife.eu integrates the industry's best technologies for each customer's specific need and delivers it as a service via the company's commitment to excellent support. HostForLife.eu core products include Shared Hosting, Reseller Hosting, Cloud Computing Service, SharePoint Hosting and Dedicated Server hosting.

HostForLife.eu service is No #1 Top Recommended Windows and ASP.NET Hosting Service in European continent. Their services is ranked the highest top #1 spot in several European countries, such as: Germany, Italy, Netherlands, France, Belgium, United Kingdom, Sweden, Finland, Switzerland and many top European countries. For more information, please refer to http://www.microsoft.com/web/hosting/HostingProvider/Details/953.

HostForLife.eu has a very strong commitment to introduce their Windows and ASP.NET hosting service to the worldwide market. HostForLife.eu starts to target market in United States, Middle East and Asia/Australia in 2010 and by the end of 2013, HostForLife.eu will be the one-stop Windows and ASP.NET Hosting Solution for every ASP.NET enthusiast and developer.

HostForLife.eu leverages the best-in-class connectivity and technology to innovate industry-leading, fully automated solutions that empower enterprises with complete access, control, security, and scalability. With this insightful strategy and our peerless technical execution, HostForLife.eu has created the truly virtual data center—and made traditional hosting and managed/unmanaged services obsolete.

HostForLIFE.eu currently operates data center located in Amsterdam (Netherlands), offering complete redundancy in power, HVAC, fire suppression, network connectivity, and security. With over 53,000 sq ft of raised floor between the two facilities, HostForLife has an offering to fit any need. The datacenter facility sits atop multiple power grids driven by TXU electric, with PowerWare UPS battery backup power and dual diesel generators onsite. Our HVAC systems are condenser units by Data Aire to provide redundancy in cooling coupled with nine managed backbone providers.

HostForLife.eu does operate a data center located in Washington D.C (United States) too and this data center is best fits to customers who are targeting US market. Starting on Jan 2013, HostForLife.eu will operate a new data centre facility located in Singapore (Asia).

With three data centers that are located in different region, HostForLife.eu commits to provide service to all the customers worldwide. They hope they can achieve the best Windows and ASP.NET Hosting Awards in the World by the end of 2013.

About HostForLIFE.eu

HostForLife.eu is Microsoft No #1 Recommended Windows and ASP.NET Hosting in European Continent. Their service is ranked the highest top #1 spot in several European countries, such as: Germany, Italy, Netherlands, France, Belgium, United Kingdom, Sweden, Finland, Switzerland and many top European countries.

Our number one goal is constant uptime. Our data center uses cutting edge technology, processes, and equipment. We have one of the best up time reputations in the industry.

Our second goal is providing excellent customer service. Our technical management structure is headed by professionals who have been in the industry since its inception. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



European ASP.NET 4.5 Hosting - Amsterdam :: Using Caller Info Attributes in .NET 4.5

clock December 12, 2012 07:56 by author Scott

Introduction

When developing complex .NET applications sometimes you need to find out the details about the caller of a method. .NET Framework 4.5 introduces what is known as Caller Info Attributes, a set of attributes that give you the details about a method caller. Caller info attributes can come in handy for tracing, debugging and diagnostic tools or utilities. This article examines what Caller Info Attributes are and how to use them in a .NET application.


Overview of Caller Info Attributes


Caller Info Attributes are attributes provided by the .NET Framework (System.Runtime.CompilerServices) that give details about the caller of a method. The caller info attributes are applied to a method with the help of optional parameters. These parameters don't take part in the method signature, as far as calling the method is concerned. They simply pass caller information to the code contained inside the method. Caller info attributes are available to C# as well as Visual Basic and are listed below:

Caller Info Attribute

Description

CallerMemberName

This attribute gives you the name of the caller as a string. For methods, the respective method names are returned whereas for constructors and finalizers strings ".ctor" and "Finalizer" are returned.

CallerFilePath

This attribute gives you the path and file name of the source file that contains the caller.

CallerLineNumber

This attribute gives you the line number in the source file at which the method is called.


A common use of these attributes will involve logging the information returned by these attributes to some log file or trace.


Using Caller Info Attributes


Now that you know what Caller Info Attributes are, let's create a simple application that shows how they can be used. Consider the Windows Forms application shown below:


The above application consists of two Visual Studio projects - a Windows Forms project that contains a form as shown above and a Class Library project that contains a class called Employee. As you might have guessed the Windows Form accepts EmployeeID, FirstName and LastName and calls AddEmployee() method of the Class Library. Though the application doesn't do any database INSERTs for the sake of illustrating Caller Info Attributes this setup is sufficient.

The Employee class that resides in the Class Library project is shown below:


1. 
public class Employee
2. 
{
3. 
    public Employee([CallerMemberName]string sourceMemberName = "",
4. 
                    [CallerFilePath]string sourceFilePath = "",
5. 
                    [CallerLineNumber]int sourceLineNo = 0)
6. 
    {
7. 
        Debug.WriteLine("Member Name : " + sourceMemberName);
8. 
        Debug.WriteLine("File Name : " + sourceFilePath);
9. 
        Debug.WriteLine("Line No. : " + sourceLineNo);
10.
    }
11. 

12.
    private int intEmployeeID;
13.
    public int EmployeeID
14.
    {
15.
        get
16.
        {
17.
            return intEmployeeID;
18.
        }
19.
        set
20.
        {
21.
            intEmployeeID = value;
22.
        }
23.
    }
24. 

25.
    private string strFirstName;
26.
    public string FirstName
27.
    {
28.
        get
29.
        {
30.
            return strFirstName;
31.
        }
32.
        set
33.
        {
34.
            strFirstName = value;
35.
        }
36.
    }
37. 

38.
    private string strLastName;
39.
    public string LastName
40.
    {
41.
        get
42.
        {
43.
            return strLastName;
44.
        }
45.
        set
46.
        {
47.
            strLastName = value;
48.
        }
49.
    }
50. 

51.
    public string AddEmployee([CallerMemberName]string sourceMemberName="",
52.
                              [CallerFilePath]string sourceFilePath="",
53.
                              [CallerLineNumber]int sourceLineNo=0)
54.
    {
55.
        Debug.WriteLine("Member Name : " + sourceMemberName);
56.
        Debug.WriteLine("File Name : " + sourceFilePath);
57.
        Debug.WriteLine("Line No. : " + sourceLineNo);
58.
        //do database INSERT here
59.
        return "Employee added successfully!";
60.
    }
61.
    

The Employee class is quite simple. It contains a constructor, a method named AddEmployee() and three properties, viz. EmployeeID, FirstName and LastName. The caller info attributes are used in the constructor and AddEmployee() method. Notice how the caller info attributes are used. To use any of the caller info attributes you need to declare optional parameters and then decorate them with the appropriate attributes. In the above example the code declares three optional parameters, viz. sourceMemberName, sourceFilePath and sourceLineNo. Note that sourceLineNo is an integer parameter since the [CallerLineNumber] attribute gives a numeric result. The optional parameters are assigned some default values. These values are returned in case there is no caller information. Inside the constructor and AddMethod() the code simply outputs the parameter values to the Output window using Debug.WriteLine() statements.

The Employee class thus created is used by the Windows Forms application as follows:


1. 
private void button1_Click(object sender, EventArgs e)
2. 
{
3. 
    Employee emp = new Employee();
4. 
    emp.EmployeeID = int.Parse(textBox1.Text);
5. 
    emp.FirstName = textBox2.Text;
6. 
    emp.LastName = textBox3.Text;
7. 
    MessageBox.Show(emp.AddEmployee());
8. 
}

The Click event handler of the Add Employee button simply creates a new instance of the Employee class, assigns property values and calls the AddEmployee() method.

If you run the Windows Forms application and see the Output window you should see this:



The Output window shows the caller information

As you can see the Output window shows the caller information as expected.


Using [CallerMemberName] with INotifyPropertyChanged Interface


Though the primary use of caller info attributes is in debugging and tracing scenarios, you can use the [CallerMemberName] attribute to avoid using hard-coding member names. One such scenario is when your class implements the INotifyPropertyChanged interface. This interface is typically implemented by data bound controls and components and is used to notify the user interface that a property value has changed. This way the UI can refresh itself or do some processing. To understand the problem posed by hard-coding property names see the modified Employee class below:


1. 
public class Employee:INotifyPropertyChanged
2. 
{
3. 
    public event PropertyChangedEventHandler PropertyChanged;
4.  

5. 
    private int intEmployeeID;
6. 
    public int EmployeeID
7. 
    {
8. 
        get
9. 
        {
10.
            return intEmployeeID;
11.
        }
12.
        set
13.
        {
14.
            intEmployeeID = value;
15.
            if (PropertyChanged != null)
16.
            {
17.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("EmployeeID");
18.
               this.PropertyChanged(this, evt);
19.
            }
20.
        }
21.
    }
22. 

23.
    private string strFirstName;
24.
    public string FirstName
25.
    {
26.
        get
27.
        {
28.
            return strFirstName;
29.
        }
30.
        set
31.
        {
32.
            strFirstName = value;
33.
            if (PropertyChanged != null)
34.
            {
35.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("FirstName");
36.
               this.PropertyChanged(this, evt);
37.
            }
38.
        }
39.
    }
40. 

41.
    private string strLastName;
42.
    public string LastName
43.
    {
44.
        get
45.
        {
46.
            return strLastName;
47.
        }
48.
        set
49.
        {
50.
            strLastName = value;
51.
           if (PropertyChanged != null)
52.
            {
53.
               PropertyChangedEventArgs evt = new PropertyChangedEventArgs("LastName");
54.
               this.PropertyChanged(this, evt);
55.
            }
56.
        }
57.
    }
58. 

59.
    public string AddEmployee([CallerMemberName]string sourceMemberName="",
60.
                              [CallerFilePath]string sourceFilePath="",
61.
                              [CallerLineNumber]int sourceLineNo=0)
62.
    {
63.
       ...
64.
    }
65.
}

The Employee class now implements INotifyPropertyChanged interface. Whenever a property value is assigned it raises PropertyChanged event. The caller (Windows Forms in this case) can handle the PropertyChanged event and be notified whenever a property changes. Now the problem is that inside the property set routines the property names are hard-coded. If you ever change the property names you need to ensure that all the hard-coded property names are also changed accordingly. This can be cumbersome for complex class libraries. Using the [CallerMemberName] attribute you can avoid this hard-coding. Let's see how.

To use the [CallerMemberName] attribute to avoid hard-coding the property names you need to do a bit more work. You need to create a generic helper method that internally assigns the property values. The following code shows how this can be done:


1. 
protected bool SetPropertyValue<T>(ref T varName, T propValue, [CallerMemberName] string propName = null)
2. 
{
3. 
    varName = propValue;
4. 
    if (PropertyChanged != null)
5. 
    {
6. 
        PropertyChangedEventArgs evt = new PropertyChangedEventArgs(propName);
7. 
        this.PropertyChanged(this, evt);
8. 
        Debug.WriteLine("Member Name : " + propName);
9. 
    }
10.
    return true;
11.
}

The SetPropertyValue() method uses only the [CallerMemberName] attribute. It takes three parameters. The first reference parameter is the variable that holds a property value (strFirstName for example). The second parameter is the new property value being assigned to the property. Finally, the third optional parameter supplies the caller member name. Inside the SetPropertyValue() method you assign the property value to the variable, raises the PropertyChanged event and calls Debug.WriteLine() as before.

Now, you need to call the SetPropertyValue() method inside the property set routines as shown below:


1. 
private string strFirstName;
2. 
public string FirstName
3. 
{
4. 
    get
5. 
    {
6. 
        return strFirstName;
7. 
    }
8. 
    set
9. 
    {
10.
        SetPropertyValue<string>(ref strFirstName, value);
11.
    }
12.
}

Now when you assign any property value, the set routine will call the SetPropertyValue() method and pass its name to the SetPropertyValue() method. Inside the SetPropertyValue() method you use this name (propName parameter) without hard-coding the actual property name.

Summary


.NET Framework 4.5 introduces Caller Info Attributes that can be used to obtain information about the caller of a method. Three attributes, viz. [CallerMemberName], [CallerFilePath] and [CallerLineNumber] supply caller name, its source file and the line number at which the call was made. You can use caller info attributes for tracing, debugging, logging or diagnostic purposes.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in