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 ASP.NET 4.5 Hosting - UK :: How to Check that .NET has been Installed on the Server

clock November 16, 2015 21:51 by author Scott

Most of the newbies and few administrators handling the deployment of their company’s ASP.Net applications on the Windows Server must be knowing about the basics of how ASP.Net is associated with the IIS web server. Here’s a quick tip for you to quickly check  whether the exact version of .NET framework has been installed on the Server and also to check whether it has been registered with the IIS or not.

In this scenario, I'm going to consider a fresh installation of the Windows Server (2008 R2/ 2012 R2). SO make sure you have the below mentioned configuration done accordingly.

How to Find The Existence of the .NET Framework and Its Files

Navigate to this location, to make sure the .Net Framework that you are wanting/looking for is installed.

File location: (32-bit): C:\Windows\Microsoft.NET\Framework\ (By default)
For 64-bit: C:\Windows\Microsoft.NET\Framework64\ (By default)

There are several .NET Framework versions available. Some are included in some Windows OS by default and all are available to download at Microsoft website as well.

Following is a list of all released versions of .NET Framework:

- .NET Framework 1.0 (Obsolete)
- .NET Framework 1.1 (Obsolete, comes installed in Windows Server 2003)
- .NET Framework 2.0* (Obsolete, comes as a standalone installer)
- .NET Framework 3.0* (comes pre-installed in Windows Vista and Server 2008)
- .NET Framework 3.5* (comes pre-installed in Windows 7 and Server 2008 R2)
- .NET Framework 4.0*
- .NET Framework 4.5* (comes pre-installed in Windows 8/8.1 and Server 2012/2012 R2)

Note: The framework marked with (*) have their later versions which is available as service packs, that can be downloaded from Microsoft’s Download website.

To check the ASP.Net application version compatibility, refer this MSDN article. Which is also shown below

If you find the respective folder, say v4.0.xxx, then it means that the Framework 4.0 or above has been installed. X:\Windows\Microsoft.NET\Framework\v4.0.30319  (The X:\ is replaced by the OS drive)

Also you will find a similar folder for the x64 bit .Net Framework and its files associated in this location X:\Windows\Microsoft.NET\Framework64\v4.0.30319 (The X:\ is replaced by the OS drive)

This can also be confirmed using another method by navigating into the Windows Registry to find a key and its existence confirms the same.

How to Find the .NET Framework Versions by Viewing the Registry

1. On the Start menu, choose Run.

2. In the Open box, enter regedit.exe.

You must have administrative credentials to run regedit.exe.

In the Registry Editor, open the following subkey:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full

This confirms the existence of .Net framework 4 and above(4.5 / 4.5.1 / 4.5.2 Only).

In most of the cases people might ignore this, assuming they have already configured ASP.Net by choosing from the server roles or any other version of .Net application that was working earlier.

This step will guide you to check whether your new application (with respect to the .Net Framework compatibility) has its asp.net component registered or not.

Simply Check ASP.NET 4.5 has been Installed via IIS

To check that .net 4.5 has been installed on the server, please just simply create a website in IIS and hit the “Select” button to check the .Net framework versions available to create Application Pool.

If you find v4.5 instead of v4.0, then it clearly justifies that .Net framework version 4.5 or above (4.5 / 4.5.1 / 4.5.2 only) has been installed and made available to run any website that requires this framework’s version.

If you don't find it, then navigate to the framework’s root folder (refer pic 2) and run “aspnet_regiis.exe” which will in turn register the asp.net component to the IIS.

Once you have registered the ASP.Net component, restart the IIS from the command prompt by typing “iisreset”, then launch your IIS Manager and follow the Step 3, to check the version listed in the available frameworks in the “Add Website” windows as shown above.

Now you are all set to go and start deploying your web application through Web Deploy / FTP or any other.



European ASP.NET 4.5 Hosting - UK :: Zip File Manipulation in ASP.NET 4.5

clock December 11, 2014 08:16 by author Scott

One of the missing feature of .NET framework was a support for Zip file manipulation such as reading the zip archive, adding files, extracting files, etc. and we were using some third party libraries such as excellent the DotNetZip. In .NET 4.5, we have an extensive support for manipulating .zip files.

First thing that you should do is to add System.IO.Compression assembly as reference to your project. You may also want to reference System.IO.Compression.FileSystem assembly to access three extension methods (from the ZipFileExtensions class) for the ZipArchive class: CreateEntryFromFile,CreateEntryFromFile, and ExtractToDirectory. These extension methods enable you to compress and decompress the contents of the entry to a file.

Let’s cover the bits and pieces that we get from System.IO.Compression assembly at first. The below sample shows how to read a zip archive easily with ZipArchive class:

static void Main(string[] args) {

    const string zipFilePath = @"C:\apps\Sample Pictures.zip";

    using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))
    using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) {

        foreach (var zipArchiveEntry in archive.Entries)
            Console.WriteLine(
                "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName
            );
    }
}

In this sample, we are opening the zip archive and iterate through the collection of entries. When we run the application, we should see the list of files inside the zip archive:

It’s also so easy to add a new file to the zip archive:

static void Main(string[] args) {

    const string zipFilePath = @"C:\apps\Sample Pictures.zip";

    using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))
    using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)) {

        ZipArchiveEntry readMeEntry = archive.CreateEntry("ReadMe.txt");
        using (StreamWriter writer = new StreamWriter(readMeEntry.Open())) {
            writer.WriteLine("Lorem ipsum dolor sit amet...");
            writer.Write("Proin rutrum, massa sed molestie porta, urna...");
        }

        foreach (var zipArchiveEntry in archive.Entries)
            Console.WriteLine(
                "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName
            );
    }
}

In this sample, we are adding a file named ReadMe.txt at the root of archive and then we are writing some text into that file.

Extracting files is into a folder is so easy as well. You need reference the System.IO.Compression.FileSystem assembly along with System.IO.Compression assembly as mentioned before for this sample:

static void Main(string[] args) {

    const string zipFilePath = @"C:\apps\Sample Pictures.zip";
    const string dirToExtract = @"C:\apps\Sample Pictures\";

    using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))
    using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
        archive.ExtractToDirectory(dirToExtract);
}

There are some other handy APIs as well but it is so easy to discover them by yourself. 



European ASP.NET 4.5 Hosting - Amsterdam :: Using Model Binding ASP.NET 4.5 to Display Data

clock July 29, 2013 08:17 by author Scott

As I have previously written, ASP.NET 4.5 has introduced many new features. One of them is model binding in ASP.NET 4.5. Now, I will give implementation how to use model binding with ASP.NET Forms 4.5.

Sample data

Before going on with examples let’s create some test data too. Let’s define class Product as follows.

1.public class Product
2.{
3.   public int Id { get; set; }
4.   public string Name { get; set; }
5.   public decimal Price { get; set; }
6.}

We need more than one product and to avoid creating database or doing other complex things we define simple method that returns us list of products.

01.private IList<Product> GetProductList()
02.{
03.   return new[]{
04.      new Product { Id=1, Name="Heineken", Price=0.88m },
05.      new Product { Id=2, Name="Skopsko", Price=0.97m },
06.      new Product { Id=3, Name="Gambrinus", Price=0.63m },
07.      new Product { Id=4, Name="Lapin Kulta", Price=0.92m },
08.      new Product { Id=5, Name="Rock", Price=1.1m }
09.   };
10.}

That’s enough for preparation work. You can use this method also as static method of Product class.

Strongly typed controls

Previous versions of ASP.NET Forms used reflection on data source objects to read values from objects they were bound to. Web is full of examples about how to bind DataTable to GridView or Repeater and so on. With strongly typed controls ASP.NET Forms makes step closer to object orientation in presentation layer.

Let’s define strongly typed Repeater that shows us list of products.

01.<asp:Repeater
02.      runat="server" ID="Repeater1"
03.      ModelType="WebApplication45.Product"
04.      SelectMethod="GetProducts">
05.   <HeaderTemplate>
06.      <table>
07.      <tr>
08.      <th>ID</th>
09.      <th>Name</th>
10.      <th>Price</th>
11.      </tr>
12.   </HeaderTemplate>
13.   <ItemTemplate>
14.      <tr>
15.      <td><%# Item.Id %></td>
16.      <td><%# Item.Name %></td>
17.      <td><%# Item.Price %></td>
18.      </tr>
19.   </ItemTemplate>
20.   <FooterTemplate>
21.      </table>
22.   </FooterTemplate>
23.</asp:Repeater>

Note the following things:

1. There is new ModelType property we can use to specify type of data item.
2. There is new SelectMethod property that specifies the method to call when repeater wants to load data.
3. To show data in different templates we can use Item property that is strongly typed and – of course – IntelliSense is also supported. You can see IntelliSense in action on screenshot on below.

Now let’s see how SelectMethod works.

Select method

Select method is expected to return us result of type IQueryable<ModelType>. If our data source returns something else we can usually use LINQ extension methods to convert our source data to IQueryable. In our case GetProducts() method is defined as follows.

1.public IQueryable<Product> GetProducts()
2.{
3.   return GetProductList().AsQueryable();
4.}

SelectMethod allows us to do much more but for this example it is enough.

After running our ASP.NET Forms solution we will see product table like this.

Conclusion

Repeater is not the only strongly typed control available in ASP.NET 4.5 – there are many other familiar controls that have support for strongly typed data. In this posting we saw that defining strongly typed web controls is easy. It is also easy to provide data to these controls using data selecting method. SelectMethod is more powerful than you can see here but this is the topic of some other (hopefully interesting) posting.



European ASP.NET 4.5 Hosting - Amsterdam :: Revisiting IBundleTransform ASP.NET 4.5 and MVC 4

clock May 13, 2013 10:12 by author Scott

Web optimization frameworks include two defaults transform type JsMinify and CssMinify which is used by ScriptBundle and StyleBundle respectively. However we can create our own custom transform type to processe references as per our need. To create custom transform type, we need to create class which implements IBundleTransform interface.

IBundleTransform interface define a method named Process which process bundle response. In developer preview version, Process method had only one parameter of type BundleResponse, however onwards RC release, Process method introduced one more parameter of type BundleContext. In this post, we will see how we can utilize this additional parameter while creating our custom transform type.

BundleContext

As name suggest, with BundleContext, we can get information about bundles which could include existing bundle information, bundle url, HTTP context for bundle, etc. Following is the list of all property of BundleContext.

- BundleContext.BundleCollection : We can get collection of all bundles including default and custom bundle in application through this property.

- BundleContext.BundleVirtualPath : This property expose virtual bundle url i.e. ~/bundles/MyBundle.

- BundleContext.HttpContext : This property is type of HttpContextBase, and we can have access of HTTP context through this property. This is very much useful property when we are creating transform type which generate dynamic response. For e.g. we can access query string parameter passed to bundle url (~/bundles/MyBundle?id=123) through this property (context.HttpContext.Request.QueryString["id"]) and we can use it to create dynamic bundle response.

- BundleContext.UseServerCache : Default value of this property is true. It means only first request to bundle url will be intercepted by transform types and once response is generated it will be stored in server cache and further request to bundle url will be served from server cache without processing it. This will help to reduce bundle processing time and to increase performance. If we set BundleContext.UseServerCache to false then all request will be processed by transform type this is only necessary when bundle url are generating dynamic response. See detailed walkthrough later in this post showing how to use this property in accordance with BundleResponse.Cacheability.

- BundleContext.EnableInstrumentation : Default value of this property is false. This is used for tracing and analysis purpose. We can check value of this property and can write tracing code accordingly. We can also set true to this property to enable instrumentation for further lifecycle of Web optimization frameworks for current bundle request.

BundleResponse

Now let us recall BundleResponse parameter from old post. BundleResponse is used to retrieve list of files included in bundle so we can process it and generate response for bundle. As BundleResponse is used to generate response of bundles, it needs to take care of two primary properties of generated response. One is response content type and another one is HTTP Cache-Control header. So BundleResponse also expose properties for the same. Following is the list of all properties in BundleResponse class.

- BundleResponse.Files : This is IEnumerable collection of files which is included in bundle. We can iterate through this collection and process file content to generate bundle response.

- BundleResponse.ContentType : Through this property, we can set content type for bundle so that browser can render it appropriately. Default content type "text/html".

- BundleResponse.Cacheability : We can use this property to set Cache-Control HTTP header of bundled response. Default value of this property is Public.

- BundleResponse.Content : Anything which we set as a value of this property, that content will be sent back to browser as a response of bundle.

Following is the complete code which shows how to create custom transform type and how we can use it with bundling.

public class CustomTransformType : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        string strBundleResponse = string.Empty;
        foreach (FileInfo file in response.Files)
        {
            // PROCESS FILE CONTENT
        }
        response.Content = strBundleResponse;
    }


Bundle myBundle = new Bundle("~/bundles/MyBundle", new CustomTransformType());
myBundle.Include("~/path/to/file");
bundles.Add(myBundle);

Bundle and truly dynamic response

As we noted earlier, we can set BundleContext.UseServerCache to false in order to process all bundle request and generate dynamic response. Let try to simulate this by small walkthrough and see it works or we need to take care any additional parameter.

public void Process(BundleContext context, BundleResponse response)

{
    context.UseServerCache = false;
    response.Content = DateTime.Now.ToString();
}


We are returning current date time with UseServerCache set to false. Now try to hit bundle url multiple times by pressing F5. Oops… it seems it has processed bundle response only first time. Let dig more into this, open another browser and hit same url… ahmm it seems it has processed bundle response one more time… again press F5 multiple times…bad luck

As we can see, it seems (read again it seems) it is processing bundle response only first time for separate client (is it really? nop). Nop this is not the case. In fact this is how client deals with it due to HTTP cache control header. Confused? See response header of bundle url to get more information.

As we noted earlier default value of BundleResponse.Cacheability is Public. So even if we have set BundleContext.UseServerCache to false then also due to Expires response header and Public Cache-Control header client is not sending request back to server. So in this case we need to also set BundleResponse.Cacheability to NoCache. We can also set it to Private but in some client we need to press Ctrl + F5 to refresh bundle response.

public void Process(BundleContext context, BundleResponse response)
{
    context.UseServerCache = false;
    response.Cacheability = HttpCacheability.NoCache;
    response.Content = DateTime.Now.ToString();
}

After setting BundleResponse.Cacheability to NoCache try to refresh bundle url again now it is re generating bundle response on each request.



European ASP.NET 4.5 Hosting - Amsterdam :: How to Upload a file in MVC4 C#5 .NET 4.5

clock May 3, 2013 06:27 by author Scott

One of the features of this so called killer app will be to upload pictures (nothing special I agree). But how would I do this for all the clients I hope to support (WinRT/WP7/Html5/IOS).

Let me first present the server that will be used for all these clients, I’ll then follow up with what I consider to be the simplest client a html5 browser!

Server

So I fired up VS11 and created a new MVC4 application using .net 4.5 / C#  and the WebApi template.

I then added a controller called FileUploadController.cs

   1:  using System.Collections.Generic;
   2:  using System.Linq;
   3:  using System.Net;
   4:  using System.Net.Http;
   5:  using System.Threading.Tasks;
   6:  using System.Web.Http;
   7:   
   8:  namespace MvcApplication16.Controllers
   9:  {
  10:      public class FileUploadController : ApiController
  11:      {
  12:          public async Task<IEnumerable<string>> PostMultipartStream()
  13:          {
  14:              // Check we're uploading a file
  15:              if (!Request.Content.IsMimeMultipartContent("form-data"))           
  16:                  throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
  17:                 
  18:              // Create the stream provider, and tell it sort files in my c:\temp\uploads folder
  19:              var provider = new MultipartFormDataStreamProvider("c:\\temp\\uploads");
  20:   
  21:              // Read using the stream
  22:              var bodyparts = await Request.Content.ReadAsMultipartAsync(provider);           
  23:          
  24:              // Create response.
  25:              return provider.BodyPartFileNames.Select(kv => kv.Value);           
  26:          }
  27:      }
  28:      
  29:  }

You can see from line 12 that I’ve made this operation async, you’ve really got to admire the simplicity of async/await construct in .net 4.5! In line 22 you can see that the compiler and some state machine magic allow the freeing up of the asp worker thread…..

HTML5 Client

The client couldn’t have been easier, fist a look at it in the browser

   7:      <meta name="viewport" content="width=device-width" />
   8:  </head>
   9:  <body>
  10:      @using (Html.BeginForm("FileUpload", "api", FormMethod.Post, new { enctype = "multipart/form-data" }))
  11:      {
  12:          <div>Please select some files</div>
  13:          <input name="data" type="file" multiple>
  14:          <input type="submit" />           
  15:      }
  16:  </body>
  17:  </html>

The important part above is using the enctype attribute, in fact line 10 loosely translates to

<form action="~/api/FileUpload" enctype="multipart/form-data" method="POST">

Don’t believe me? Then try VS11’s awesome new feature – page inspector

Right click on the html and choose view in page inspector

and we’re done! Of course in the real world we’ll use ajax with a few trick re sandbox, but here’s the response in the browser with xml.

I’ll hopefully follow up with the samples for the client list below when I get to the respective development machines.

 



European ASP.NET 4.5 Hosting - Amsterdam :: AjaxControlToolkit version 7.0123 with .NET 4.5

clock April 25, 2013 06:26 by author Scott

Here’s my steps and workarounds from the very beginning (in Visual Studio 2012), hopefully some part of this will help fix whatever error you are encountering.

File -> New Project
.NET Framework 4.5
Visual C# -> Web
ASP.NET Web Forms Application
Add AjaxControlToolkit version 7.0123 (dll is actually 4.5.7.123 which is January 2013 I believe) via NuGet

Open Default.aspx
Add a calendar to the BodyContent / MainContent:

<asp:TextBox ID="myTextBox" runat="server" />
<ajaxToolkit:CalendarExtender ID="myCalendar" runat="server" TargetControlID="myTextBox" Format="dd/MM/yyyy" />

Run it up (F5 will do)

It might error about ASP.NET Ajax 4.0 scripts:
0x800a139e – JavaScript runtime error: AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. Ensure the correct version of the scripts are referenced. If you are using an ASP.NET ScriptManager, switch to the ToolkitScriptManager in AjaxControlToolkit.dll.

I’ve also seen it error about:
‘MsAjaxBundle’ is not a valid script name. The name must end in ‘.js’.

No bother, let’s remove that reference from the Site.Master, so:

<asp:ScriptManager runat="server">
    <Scripts>
        <%--Framework Scripts--%>
        <asp:ScriptReference Name="MsAjaxBundle" />
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
        <%--Site Scripts--%>

    </Scripts>
</asp:ScriptManager>

Now becomes:

<asp:ScriptManager runat="server">
    <Scripts>
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
    </Scripts>
</asp:ScriptManager>

Next is ToolkitScriptManager, the snippet above now becomes:

<ajaxToolkit:ToolkitScriptManager runat="server">
    <Scripts>
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
    </Scripts>
</ajaxToolkit:ToolkitScriptManager>

But of course this fails with:
Could not load file or assembly ‘System.Web’ or one of its dependencies. The system cannot find the file specified.

Remove the Assembly=”System.Web” part from the ScriptReference so we have have:

<ajaxToolkit:ToolkitScriptManager runat="server">
    <Scripts>
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
    </Scripts>
</ajaxToolkit:ToolkitScriptManager>

It seems the new web forms project template adds ‘Microsoft.AspNet.ScriptManager.MSAjax 4.5.6′ package, this appears to conflict with the toolkit, so remove this via “Manage NuGet Packages”
Visual Studio might still leave the dll in your bin directory even after a clean, make sure you manually clean that out.

 



European ASP.NET 4.5 Hosting - Amsterdam :: How to Enable Unobtrusive Validation Mode in ASP.NET 4.5

clock February 27, 2013 05:09 by author Scott

In this article we will learn how to enable Unobtrusive Validation in ASP.NET 4.5.

Visual Studio 2012 provides some new Validation features that include Unobtrusive Validation. When you work with this Validation mode you will find that there is not much difference in this validation and previous validations but to enable this type of validation you had to first configure your Web Application.

There are three ways to enable the Unobtrusive Validation in your Web Application; they are:

- By using Web.Config file
- By using Global.asax file
- By using Page_Load event on each page

The first method is by using the Web.Config file.

Step 1

Write the following code in your Web.Config file:

<configuration>
  <
appSettings>
    <
add key="ValidationSettings:UnobtrusiveValidationMode" value="None"></add>
  </
appSettings>
    <
system.web>
      <
compilation
 debug="true" targetFramework="4.5" />
      <
httpRuntime targetFramework="4.5" />
    </
system.web> 
</configuration>

Step 2

Now write the following code in your WebForm.aspx Page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Now debug your code, on debugging the code you will get the output like this:

When you click on the button in the output window you will see an Error Message. As you write in the Text Box and click again on the Button the error message will be disposed of automatically.

The second method is by using a Global.asax file.

Step 1

In the Global.asax file, first add the namespace "using System.Web.UI;".

After adding the namespace write the following code in the Application_Start method:

protected void Application_Start(object sender, EventArgs e)
{
    ValidationSettings.UnobtrusiveValidationMode =
 UnobtrusiveValidationMode.None;
}

Step 2

Now write the following code in your WebForm.aspx page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Again debugging your Web Application you will again get the same output as you got in the first method.

The third method is by simply writing the code on each page inside the Page_Load event.

Step 1

protected void Page_Load(object sender, EventArgs e)
{
    this.UnobtrusiveValidationMode = System.Web.UI.UnobtrusiveValidationMode.None;

}

Step 2

Now write the following code in your WebForm.aspx page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Again debug your Web Application and you will again get the same output as you got in the first method.

 



European ASP.NET 4.5 Hosting - Amsterdam :: How to Disable Bundling and Minification in ASP.NET 4.5/MVC 4

clock February 12, 2013 05:51 by author Scott

Lots of people are excited about the new bundling and minification feature in the next version of ASP.NET and MVC. One major drawback I see a lot of people clamoring about is the fact that you cannot conditionally disable bundling or minification when you are in debug mode. Out of the box (and to be clear, I’m referring to the version that ships with MVC 4 beta) it’s impossible to debug your CSS and Javascript.

I expect this will change in the release version, but for now you are forced to create your own custom bundles (something you’d end up doing anyway) and conditionally check if you’re in debug mode to short-circuit the bundling/minification.

Disabling minification while in debug mode

It’s as simple as an #if DEBUG line and creating a transformer that does nothing. For example:

01           protected void Application_Start()
02           {
03               IBundleTransform jsTransformer;
04           #if DEBUG
05               jsTransformer = new NoTransform("text/javascript");
06           #else
07               jstransformer = new JsMinify();
08           #endif
09          
10               var bundle = new Bundle("~/Scripts/js", jsTransformer);
11          
12               bundle.AddFile("~/Scripts/script1.js");
13               bundle.AddFile("~/scripts/script2.js");
14          
15               BundleTable.Bundles.Add(bundle);
16           }

Now when you reference this javascript bundle like <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script> in a view it will render a single bundled and minified script when in release mode, but as a single bundled, non-minified file while in debug mode.

Disabling bundling while in debug mode

The above approach improves this situation, but I don’t think it goes far enough. If I’m going to have multiple source files, I want to debug with the same multiple source files, at least initially. It would get too confusing writing code in a several files and then debugging it in a single monolithic file.

As an experiment to see if it was possible, I ended up building a better bundler that does just what I want: bundles and minifies in release mode, but doesn’t bundle or minify when the build is set to debug.

The entire class is below, explanation to follow:

01           public static class BetterBundler
02           {
03               private static bool _debug;
04               const string CssTemplate = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
05          
06               public static void Init()
07               {
08           #if DEBUG
09                   _debug = true;
10           #endif
11                   var bundle = new Bundle("~/content/css", new CssMinify());
12          
13                   bundle.AddFile("~/Content/test.css");
14                   bundle.AddFile("~/Content/site.css");
15                   
16                   BundleTable.Bundles.Add(bundle);
17               }
18          
19               public static MvcHtmlString ResolveBundleUrl(string bundleUrl)
20               {
21                   return _debug ? BundledFiles(BundleTable.Bundles.ResolveBundleUrl(bundleUrl)) : UnbundledFiles(bundleUrl);
22               }
23               
24               private static MvcHtmlString BundledFiles(string bundleVirtualPath)
25               {
26                   return new MvcHtmlString(string.Format(CssTemplate, bundleVirtualPath));
27               }
28          
29               private static MvcHtmlString UnbundledFiles(string bundleUrl)
30               {
31                   var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);
32          
33                   StringBuilder sb = new StringBuilder();
34                   var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
35          
36                   foreach (var file in bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl)))
37                   {
38                       sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(ToVirtualPath(file.FullName)));
39                   }
40          
41                   return new MvcHtmlString(sb.ToString());
42               }
43          
44               private static string ToVirtualPath(string physicalPath)
45               {
46                   var relativePath = physicalPath.Replace(HttpContext.Current.Request.ServerVariables["APPL_PHYSICAL_PATH"], "");
47                   return relativePath.Replace("\\", "/").Insert(0, "~/");
48               }
49          
50               public static MvcHtmlString CssBundle(this HtmlHelper helper, string bundleUrl)
51               {
52                   return ResolveBundleUrl(bundleUrl);
53               }
54           }

To summarize, I’m using the same technique to determine debug mode, and of course this could be extended to conditionally bundle or not based on any boolean. The interesting code is in the UnbundledFiles(string bundleUrl) method.

Currently, there is no concept of named bundles – bundles are specified simply by the virtual path of the resultant bundle. This means all our calling code in the view has to give is the virtual path of the bundle. We have to start from that and uncover all the physical files deeper within the BundleTable.

var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);

This line retrieves the bundle that we created from the BundleTable.

bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl))

This gets all of the physical files from the bundle.

The rest is just boilerplate code to turn those raw physical files back into relative virtual paths and into the proper html tags.

Finally, you’ll note that I have an HtmlHelper method in there, CssBundle(this HtmlHelper helper, string bundleUrl). To render a bundle link in a view, this must be used. Since the result of a bundle could be one or multiple files, I decided the simplest approach would be to allow the BetterBundler to render the full html tag itself. This could easily be changed or enhanced.

1              In the view:
2             
3              @Html.CssBundle("~/content/css")

The Result

In release mode:

<link href="/content/css?v=7GiB-1k9Pr1JbbYY72bT3T2EOpxXf0rGPdEOXVKl5oQ1" rel="stylesheet" type="text/css" />

In debug mode:

<link href="/content/test.css" rel="stylesheet" type="text/css" />
<link href="/content/site.css" rel="stylesheet" type="text/css" />

 



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 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