European Silverlight 4 & Silverlight 5 Hosting BLOG

BLOG about Silverlight 5 Hosting and Its Techologies - Dedicated to European Windows Hosting Customer

European WCF 4.0 Hosting - Amsterdam :: Creating WCF 4.0 Service and Hosting in IIS 7.5

clock May 22, 2012 11:02 by author Scott

This article will give step by step walkthrough

1. How to create a basic WCF 4.0 Service?


2. How to host WCF Service in IIS 7.5?


3. Hot to test service in a client.


Create WCF Service

Create WCF service. Open visual studio select new project and then from WCF tab select WCF Service application to create a new WCF service.




Delete the default code created by WCF from
IService1 and Service1.svc.cs

a. So delete the data contract

b. Modify the service contract as below. Just make one operation contract to return a string .

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService5
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetMessage();

    }  

}

Service1.svc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService5

{
    public class Service1 : IService1
    {
        public string GetMessage()
        {
            return "Hello From WCF Service ";
        }
    }
}

Leave the default configuration created by WCF.

Web.Config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>        
          <serviceMetadata httpGetEnabled="true"/>        
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer
</configuration>

Host WCF Service in IIS 4.0

Open IIS

a. Open the command prompt in administrator mode. To do click on Start button then type RUN in search and then in Run window type inetmgr to open IIS .



Now you will have IIS open like below




b. Right click on Sites and then click Add Web Site




c. Now a window will open




Give any name of your choice as the site name. I am giving name here
HostedWcfService



Now click on
select and choose ASP.Net v4.0 from the drop down.



Now in the physical path section, we need to give physical path of the service. So to get the physical path of the service, right click on the WCF Service project in visual studio and click open project in windows explorer. Open the project in windows explorer and from address bar copy the path and paste that below. Or you can browse also. Just click on browse button and navigate to project folder of the WCF Service.




Now at the Binding section select HTTP. Give any port number. I am selecting the port as 4567




Do not give any name as host name. Leave it blank




Check the check box Start Web Site Immediately.




And now click OK on the window.


d. Now open visual studio command prompt in administrator mode. Right click and select as administrator






Type the below command


aspnet_regiis.exe /iru



You will get the message Finished Installing ASP.Net 4.0


e. Now go to
inetmgr, you would able to see the site you just created in previous step.



Publishing the WCF Service

Go back to WCF Service. Right click and select Publish




On clicking of publish a window will come.




Give a Service URL. You are free to give any Service URL here. Just make sure host name is geeting resolved. In stead of localhost you can give IP address or your machine name also.




Give the name of the site
HostedWcfService. We created this site in previous step.



Leave the credential inactive.




Now click on
Publish.



You will get the message in bottom
publish succeeded

Browsing the service hosted in IIS


Open
Inetmgr and right click on site HostedWcfService. Then from Manage Web Site select Browse option.



When you click on browse site will get open in browser




You will get the above error. Just in address bar append Service1.svc with the address to open the service in browser.


http://localhost:4567/Service1.svc


And in browser you will get the service up and running




So now you successfully created and hosted the WCF 4.0 service in IIS 7.5


Testing the Service at client

a. Create console application project




b. Right click and add the service reference.




c. Give in address the address of service hosted in IIS and click GO.




d. Call the service as below ,


Program.cs

using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{
    class Program
    {
        static void Main(string[] args)
        {
            Service1Client proxy = new Service1Client();
            Console.WriteLine(proxy.GetMessage());
            Console.Read();
        }
    }
}

Output


 

 

 

 



European WCF 4.5 Hosting - Amsterdam :: Beyond Configuring Web Services in WCF 4.5

clock April 27, 2012 10:34 by author Scott

In previous post, you can see how easy it was to add a basic HTTP Web Service to a Web site in the beta of the .NET Framework 4.5 through code: Just add a shared/static method called Configure to your service and put some code in it to configure the ServiceConfiguration object passed to the method. In fact, because of the defaults that WCF 4.5 takes for a WCF service in a Web Site you don’t really need to add any code at all. In my example I did add some code to explicitly enable my service as a basic HTTP Web Service. I also chose to configure the service to return a contract and verbose error messages (both of which are turned off by default) to support testing.

But the power of WCF is in providing multiple ways of accessing the same code–as a basic Web Service or as a high performance TCP-based service. Adding TCP access requires a change in the project type: Testing a TCP-based service from Visual Studio is awkward (at best). Instead, you’ll want to create a WCF Service library where you service is hosted by WAS rather than IIS. While that makes testing your TCP access is simplified, the defaults don’t give you a service automatically and you’ll need to use a few more lines of code.


After creating your WCF Service library project add a new WCF Service to it, giving the service some meaningful name (I used “CustomerService”). Then, to demonstrate the power of configuring by code, go to your app.config file and delete the entire system.model element. You’re now ready to control your service from code.


These two lines of code make your service available as a Web Service and as a TCP-based service (which will have orders-of-magnitude better performance than the HTTP-based Web service):


PublicSharedSub Configure(sc AsServiceConfiguration)

sc.EnableProtocol(
New BasicHttpBinding
sc.EnableProtocol(
New NetTcpBinding)

While that (in theory) makes your service accessible, it doesn’t make the information about the service (the metadata) available. As a result, you won’t be able to either use Visual Studio’s WCF Test Client or be able add a service reference for your service to another project by using the Add Service Reference dialog’s Discover button. To enable the metadata you use the same code that I had in my previous post but with one extra line of code that specifies the address where the metadata is available. In that line you create a System.URI object specifying the address (the address must reference your computer name but the port and service name are up to you) and use it to set the HttpGetUrl property:


Dim behavior As New Description.ServiceMetadataBehavior

behavior.HttpGetEnabled =
True
behavior.HttpGetUrl = New System.Uri("http://localhost:1868/Customers")

sc.Description.Behaviors.Add(behavior)

You also need to add endpoints for HTTP and TCP access to your service. For that, you use the AddServiceEndpoint method on the ServiceConfiguration object passed to your Configure method. The first parameter to the AddServiceEndpoint is the type of the interface that your service implements (“ICustomers” in this example), the second parameter is the binding class for the endpoint, and the final parameter is the address itself (make sure that you use different addresses for each endpoint):


sc.AddServiceEndpoint(GetType(ICustomerService),

         New BasicHttpBinding(),
         "http://localhost:1868/Customers")
sc.AddServiceEndpoint(GetType(ICustomer),

         New NetTcpBinding(),  
         "net.tcp://localhost:1867/Customers")

There is an annoyance when you go to test your service: In a Service Library, in the absence of any entries in the config file, the test client can’t retrieve the information about the service. You’ll first get a dialog that the “WCF Service Host cannot find any service metadata”–just click the No button to continue. When the Test Client appears, it won’t display any services. You’ll need to go to the Test Client’s File menu and select Add Service to display the Add Service dialog box. In the box, enter the URL you used to set the HttpGetUrl property followed by “?wsdl” (e.g. “http://localhost:1868/Customers?wsdl”—and make sure you type the URL exactly the way it appears in your code). When you click the OK button, the Test Client will finally grab the service information and you’ll be able to test your service. The good news here is that, once you enter the URL with ?wsdl successfully, you won’t have to enter it again (you will still need to go through all the dialogs, though).

And there you go: With less than a dozen lines of code you’ve configured a service as both a basic HTTP service and TCP-based service. Adding additional access methods (e.g. named pipes, advanced web services, https) should just consist of enabling the protocol with the EnableProtocol method and adding a compatible endpoint.

 



European WCF Hosting - Amsterdam :: How to Solve - The type provided as the Service attribute could not be found

clock April 25, 2012 07:08 by author Scott

This had me stumped for a little while today. Whilst trying to host a WCF service in IIS we got this message when we tried to access the .svc file:

The type 'YourType, YourAssembly', provided as the Service attribute value in the ServiceHost directive could not be found.


At first the message seemed to be very specific about not being able to find the
type - almost as though it had found the assembly so I changed the YourAssembly to utter nonsense to see if the error changed. Alas no, so it was possible that the assembly couldn't be 'found', let alone the type.

Everything seemed to be in order as far as the assembly was concerned. He was in the bin folder and security was setup appropriately. The type, namespace and assembly were quadruple checked and
definitely correct. We even hooked up WinDbg and used the sxe ld YourAssembly command in the hope that we'd see the module attempt to load and fail. But nothing.

So I did what I always do in these situations and reverted to my ol' skool
Response.Write-ASP-classic-style debugging techniques. First step was to drop in an aspx page that used the Activator to create the type dynamically. Here's the ASPX page (no .aspx.cs required):

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Runtime.Remoting" %>

<%
ObjectHandle oh = Activator.CreateInstance("YourAssembly", "YourType");
Response.Write(oh.Unwrap().ToString() + " loaded OK");
%>

Just drop this page next to your .svc file and navigate to it in the browser. If it works and you can see the name of your type then you have a different problem to ours. I got an error that looked like this:


Could not load file or assembly 'SomeOtherAssembly' or one of its dependencies. The system cannot find the file specified.

Aha! So we could find the type specified in the Service attribute but we couldn't find some of its dependences. That's better - turns out I was missing an assembly that had to be GAC'd for this to work.



Press Release – HostForLIFE.eu Proudly Announces SQL 2012 Hosting for European Market

clock April 23, 2012 07:41 by author Scott

HostForLIFE.eu was established to cater to an under served market in the hosting industry; web hosting for customers who want excellent service. HostForLIFE.eu – a cheap, constant uptime, excellent customer service, quality, and also reliable hosting provider in advanced Windows and ASP.NET technology. We proudly announces the availability of the SQL 2012 hosting in our entire servers environment. HostForLife customer can choose SQL 2012 when creating a database from inside HostForLife hosting control panel.

The first new option is Windows SQL Server 2012, which is available to customers from today. With the public release just last week of Microsoft’s latest version of their premier database product, HostForLife has been quick to respond with updated their shared server configurations. SQL Server 2012 Web Edition is available for the same low monthly rental price as the previous SQL 2008, as well as Express Edition, which is a basic version of Microsoft’s SQL Database product, available for free.


“We’re proud to be at the cutting edge for new technologies. With these additions, customers have the option to explore these new products in the safe environment of their own shared server. Developers and IT Managers can research the potential impact of next-generation software without risking current infrastructure. With Microsoft’s announcement of the general availability of their new SQL server, we are proud to launch SQL 2012 hosting along with a suite of SQL 2012 management tools." Said John Curtis, VP Marketing and Business Development at HostForLIFE.eu.


John added, “It’s very important to our customers that we support their current deployments; we want to make sure that our customers have their good opportunity to test this new technology."


“HostForLIFE customers can now take advantage of SQL Server 2012’s advanced BI capabilities, We’re excited to see the benefits of this release add value to the energy management and manufacturing arena. Ensuring compatibility with Microsoft’s new SQL Server 2012 demonstrates how HostForLife and Microsoft remain committed together to providing leading edge technology for the benefit of our shared customers." Said CEO of HostForLIFE.eu, Anthony Johnson.


For more information about this new product, please visit
http://www.hostforlife.eu/SQL-2012-European-Hosting.aspx.

About us:


We are European Windows Hosting Provider which FOCUS in Windows Platform ONLY. We support Microsoft technology, such as the latest ASP.NET 4, ASP.NET MVC 3, SQL 2008/2008 R2, and much more.


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 it's 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 WCF 4.5 Hosting - Amsterdam :: One Line of Code to Configure WCF 4.5

clock April 10, 2012 11:47 by author Scott

The WCF 4.5 beta simplifies configuring WCF, provides better support for code-based configuration, and makes it easier to do code-based configuration in Web sites. Don’t get me wrong: I like the WCF configuration files but, I gather, I may be in a minority. Many developers prefer to configure their WCF services from code where possible. Unfortunately, one of the places where that isn’t possible is the most common place to host WCF services: in a Web application (well, I’m told it was possible but only in the sense that it’s possible to remove your own appendix).

WCF 4.5 (at least, in the beta) provides a simple solution: Add a static/shared method called Configure to your service class and fill it with the code required to configure your service. WCF will call that Configure method at the appropriate moment and pass the method an instance of the ServiceHost class. In your Configure method, you can work with that ServiceHost to configure your service.


What’s especially impressive is how simple it is. The default settings alone mean that if you add an svc file to your Web site then you have a Web Service. You can make that explicit, however, with a single line of code. This example makes the service containing this method available as a Web Service with no WCF-related tags required in the config file at all:


Public Shared Sub Configure(sc AsServiceConfiguration)

 sc.EnableProtocol(NewBasicHttpBinding())
End Sub

You can configure these services by instantiating behavior classes, configuring them, and adding them to the ServiceConfiguration’s Description property’s Behaviors collection. That’s a good thing because, while my previous example was all the code you need (in fact one more line than you needed), it’s probably not all the code you want, for two reasons.


Configuring the Service

First, with just that code you won’t be able to retrieve the WSDL contract for this service (what WCF refers to as service’s “metadata”) so you won’t be able to use Visual Studio’s WCF test client (you also won’t be able to use the Discover button in Visual Studio’s Add Service Reference dialog). For testing purposes, and until you can save to a separate file the WSDL contract that you can give to the developers building the clients/consumers for this service, you’ll want to configure your service to return a WSDL contract. To tell your service to make its metadata available you add code like the following to your Configure method. This code creates a ServiceMetadataBehavior object, sets its HttpGetEnabled property to True (that actually turns on the feature), and add the configured behavior to the Behaviors collection:

Dim behavior As New Description.ServiceMetadataBehavior
behavior.HttpGetEnabled = True
sc.Description.Behaviors.Add(behavior)


Second, by default, WCF services don’t return a lot of information in their exception messages. That’s a good thing: While that information is very useful in debugging, it probably isn’t something you want to share with the general public. However, in testing, you probably do want that those chattier error messages and you can enable the with this code in the Configure method:

Dim debugBehavior As New Description.ServiceDebugBehavior
debugBehavior.IncludeExceptionDetailInFaults = True
sc.Description.Behaviors.Add(debugBehavior)

But both of these changes highlight an issue with code-based configuration. In production, you probably don’t want your service freely giving up its contract to whoever asks for it. Instead you probably want to control access to your service’s contracts so that you have some idea who’s using your service and can contact those users when you’re making changes to your service. And you certainly don’t want to send out those verbose error messages from your production system. So, before moving your service to production you’re going to want to change the values used in this code.

The problem is that, with the code I’ve used here, there’s no simple way to inspect the assembly you’re deploying to production to determine if the settings are correct: the code is compiled and is unreadable. One of the nice features of the config files is that you could inspect them (and even change them) with Notepad. The right answer is probably to move settings that will change from one installation to another (e.g. test and production) into your AppSettings where you’ll still have visibility to them.

Please visit our site at
http://www.hostforlife.eu if you need Silverlight 5 WCF RIA hosting. Starts from only €2.45/month.

 



European WCF 4.5 Hosting - Amsterdam :: WCF 4.5 Features

clock March 22, 2012 07:14 by author Scott

This post discusses the new features in WCF 4.5. There have been significant improvements in WCF 4.5 on configuration.

Simplifying the generated configuration file in client

A client configuration file is generated when you add a service reference in Visual Studio 2010. The configuration files in earlier version of WCF contained the value of every binding property even if it is a default value. In WCF 4.5 Configuration files contain binding properties that are set to non-default value.


Example of configuration file generated by WCF 3.0



Example of same configuration file generated by WCF 4.5




Single WSDL File

In earlier version of WCF, WSDL document specifies dependencies via xsd:import attributes. WSDL file generated by WCF looks as below




Some clients may not consume the above WSDL file generated from WCF earlier version. In WCF 4.5 there is a single WSDL file and no external references to schema types.


When you browse the service metadata file in WCF4.5 then you will see the below options




If you want the single WSDL file then you can use the second link which ending with ?singlewsdl


Multiple Authentication Support on single end point in IIS

Hosting the WCF Service is bit tricky. You will get an error message when your service endpoint authentication is not matching the IIS’s authentication types.




ClientCredentialType
attribute is a new feature in WCF 4.5 which tells the service to inherit the authentication types from IIS host.

Now you can enable multiple authentication types in IIS




After enabling the authentication types in IIS then if you browse service’s WSDL file then you will see the below authentication types




WebSocket Support

Two new bindings have been added to support communication over a WebSocket transport.


NetHttpBinding and NetHttpsBinding


Streaming Improvements

Support for asynchronous streaming has been added to WCF. To enable asynchronous streaming, add the DispatcherSynchronizationBehavior endpoint behavior to the service host and set its AsynchronousSendEnabled property to true. You will get the scalability benefit when service sending streamed messages to multiple clients.

In earlier versions when you host WCF service on IIS, there were some around buffering the messages. When receiving a message for IIS hosted service which used to stream a message, asp.net would buffer entire message before sending it to WCF.

Now the buffering has been removed in .NET 4.5 and now IIS hosted WCF services can process the incoming stream before the entire message has been received.

More about the features can be read here

 



European Silverlight 4 Hosting - Amsterdam :: How to Use AutoCompleteBox in Silverlight 4

clock March 14, 2012 07:44 by author Scott

In this article let us see how to use a AutoCompleteBox Control in a Silverlight application. As usual, open the visual studio and select the Silverlight project.

First let us drag a AutoCompleteBox to Stack Panel as shown below into
MainPage.xaml.

<sdk:AutoCompleteBox x:Name="CountriesNames" Width="200" />


Now we will add List to
AutoCompleteBox from MainPage.xaml.cs as shown below. In the below code, First i prepared list of type string and assigned a name "Countries" to it. Then i added strings( Countries names) to the list "Countries".

List<string> Countries = new List<string>();
             Countries.Add("India");
             Countries.Add("USA");
             Countries.Add("Japan");
             Countries.Add("UK");
             Countries.Add("Australia");
             Countries.Add("Switzerland");
             CountriesNames.ItemsSource = Countries;


At last i am binding this list "
Countries" to the "AutoCompleteBox" using its name "CountriesNames". Thats it!!! Just press F5 and see the result. The output of the above code looks like as

<image>


Note
: For the people who find it difficult to integrate the above code, I am pasting the complete code here.

MainPage.Xaml:

<UserControl x:Class="SilverlightTest1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <StackPanel Background="White">
        <StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
            <TextBlock Text="CountriesList: " Margin="5" VerticalAlignment="Center" />
            <sdk:AutoCompleteBox x:Name="CountriesNames" Width="200" />
        </StackPanel>
     </StackPanel>

</UserControl>


MainPage.Xaml.cs:

public MainPage()
{
InitializeComponent();
List<string> Countries = new List<string>();
Countries.Add("India");
Countries.Add("USA");
Countries.Add("Japan");
Countries.Add("UK");
Countries.Add("Australia");
Countries.Add("Switzerland");
CountriesNames.ItemsSource = Countries;

}

 



European Silverlight 4 Hosting - Amsterdam :: Dynamic Types to Simplify Property Change Notification in Silverlight 4 and 5

clock March 1, 2012 07:59 by author Scott

The biggest problem with data-binding is the requirement to implement the INotifyPropertyChange interface. There are dozens of solutions out there that try to simplify the process with techniques ranging from parsing lambda expressions and walking the stack frame to using IL weaving to modify classes at compile time. The most popular approach is to derive from a base class and call a base method to handle the event.

The frustration often comes from mapping data objects that don't implement the interface to view models that do. Wouldn't it be nice to have a simple, straightforward way to manage this without duplicating properties and writing tedious mapping code? It turns out there is.


For this particular problem, I started with the solution. Given a model, say, a ContactModel, I wanted to be able to do this:


public PropertyNotifier<ContactModel> Contact { get; set; }
public void SetContact(ContactModel contact)
{
   Contact = new PropertyNotifier(contact);
}


In other words, a nice type would wrap the object and expose it with full property change glory, and little effort on my part.


So, where to start? To begin with I created a simple base class that allows for property change notification. For now I'm going to ignore some of the interesting ways to actually call the notification.


public abstract class BaseNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChange(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


This class is really all you need to have your own MVVM framework. Next is some heavy lifting. Because the solution uses dynamic types and heavy reflection, it will not work on Windows Phone 7. It will, however, work with Silverlight 4, and there is perhaps an even more elegant solution to be derived from this work in Silverlight 5 by adding ICustomTypeProvider to the mix.


How can this create a bindable object in Silverlight 4 or 5? First, create the shell of the view model. It should create the proxy class with property change notification. It should allow you to pass in a template and have that template mirrored by the proxy. Ideally, it should be easy to get the template back out (i.e. yank out the original model to send on its way after it has been modified). Here's the start:


public class PropertyNotifier<TTemplate> : BaseNotify where TTemplate : class
{
   public TTemplate Instance { get; set; }
   public INotifyPropertyChanged NotifyInstance { get; set; }
}
   

Simple enough. Not sure if the notifier instance really deserves a public setter... but it is there for now. Now comes the fun part!


The type must be created on the fly, so it needs a dynamic assembly and module to host the type. There is no sense in creating a new one for each type, so these can be static properties that live on the notifier. There should also be a type dictionary to map the source type to the proxy type (to avoid recreating the proxy type) and a mutex to avoid collisions with the dictionary (thread safety).


private static readonly ModuleBuilder _builder;
private static readonly Dictionary<Type, Type> _types = new Dictionary<Type, Type>();
private static readonly object _mutex = new object();       

static PropertyNotifier()
{
    var assemblyName = new AssemblyName("PropertyNotifier");
    var currentDomain = AppDomain.CurrentDomain;
    var builder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

    _builder = builder.DefineDynamicModule("PropertyChangeModels");
}


If you are afraid of collisions you can give the assembly a creative name like a GUID or append random text and strings if you like. This makes it nice and readable in the debugger. The assembly is created in the current domain and the module defined to host dynamic types.


Without understanding the details of how the type is actually built, you can still wire in the constructor and put in a placeholder, like this:


public PropertyNotifier()
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_types.ContainsKey(typeof (TTemplate)))
        {
            _types.Add(typeof(TTemplate), _BuildType());
        }                               
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    var type = _types[typeof (TTemplate)];          

    NotifyInstance = (INotifyPropertyChanged)Activator.CreateInstance(type);                   
}

public PropertyNotifier(TTemplate instance) : this()
{
    Instance = instance;
}


If the type has not been created, it is built. An overloaded constructor will take in an instance and then set it.


Next, assuming the type is built (we'll get into the gory details later), a few methods will help with mapping properties. First, define a delegate for the getter and setter. Then, define a dictionary of dictionaries. The key to the outer dictionary will be the type, and the inner dictionary will map the property name to the getter or setter method.


private delegate void Setter(object target, object value);

private delegate object Getter(object target);

private static readonly Dictionary<Type, Dictionary<string,Setter>> _setterCache = new Dictionary<Type, Dictionary<string,Setter>>();
private static readonly Dictionary<Type, Dictionary<string,Getter>> _getterCache = new Dictionary<Type, Dictionary<string, Getter>>();


The helper methods will inspect the type for the property information and use reflection to grab the getter or setter. They will then store these in the cache for future look ups:


private static object _GetValue(object target, string property)
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_getterCache[target.GetType()].ContainsKey(property))
        {
            var method = target.GetType().GetProperty(property).GetGetMethod();
            _getterCache[target.GetType()].Add(property, obj => method.Invoke(obj, new object[] {}));
        }
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    return _getterCache[target.GetType()][property](target);               
}

private static void _SetValue(object target, string property, object value)
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_setterCache[target.GetType()].ContainsKey(property))
        {
            var method = target.GetType().GetProperty(property).GetSetMethod();
            _setterCache[target.GetType()].Add(property, (obj,val) => method.Invoke(obj, new[] { val }));
        }
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    _setterCache[target.GetType()][property](target, value);
}


You can call the first with an object and the property name to get the value. Call the second with the object, the property name, and the property value to set it. Subsequent calls will not require inspection of the properties as the methods will be cached to call directly.


So the proxy still hasn't been built yet, but that's more complicated. First, get the simple stuff out of the way. When the instance is passed in, automatically wire the properties to the proxy. When the proxy is created, hook into the property change notificaton to automatically push changes back to the original instance:


private TTemplate _instance;

// original object
public TTemplate Instance
{
    get { return _instance; }
    set
    {               
        _instance = value;
        NotifyInstance = (INotifyPropertyChanged)Activator.CreateInstance(_types[typeof (TTemplate)]);

        foreach(var p in typeof(TTemplate).GetProperties())
        {
            var sourceValue = _GetValue(value, p.Name);
            _SetValue(NotifyInstance, p.Name, sourceValue);
        }

        RaisePropertyChange("Instance");
    }
}

// proxy object
private INotifyPropertyChanged _notifyInstance;

public INotifyPropertyChanged NotifyInstance
{
    get { return _notifyInstance; }
    set
    {
        if (_notifyInstance != null)
        {
            _notifyInstance.PropertyChanged -= _NotifyInstancePropertyChanged;
        }

        _notifyInstance = value;
        _notifyInstance.PropertyChanged += _NotifyInstancePropertyChanged;

        RaisePropertyChange("NotifyInstance");               
    }
}

void _NotifyInstancePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (Instance == null)
    {
        return;
    }          

    if (_setterCache[typeof (TTemplate)].ContainsKey(e.PropertyName))
    {
        _SetValue(Instance, e.PropertyName, _GetValue(NotifyInstance, e.PropertyName));
    }
}


OK, all of the proxy and marshalling is in place. Now it's time to build the type! First step is to define the type name and set the parent so it derives from the BaseNotify object:


private static Type _BuildType()
{
    var typeBuilder =
        _builder.DefineType(string.Format("{0}Notifier", typeof (TTemplate).Name), TypeAttributes.Class | TypeAttributes.Public);

    typeBuilder.SetParent(typeof(BaseNotify));
}


Next, grab a handle to the property change method from the base class and set up a dictionary to cache the getters and setters on the template type:


var propertyChange = typeof(BaseNotify).GetMethod("RaisePropertyChange", new[] { typeof(string)});

_getterCache.Add(typeof(TTemplate), new Dictionary<string, Getter>());
_setterCache.Add(typeof(TTemplate), new Dictionary<string, Setter>());                       


Now comes the fun part, looping through the properties and caching the getters/setters (this is from the template):


foreach(var p in typeof(TTemplate).GetProperties())
            {
                var getterInfo = p.GetGetMethod();
                _getterCache[typeof(TTemplate)].Add(p.Name, obj=>getterInfo.Invoke(obj, new object[]{}));

                var setterInfo = p.GetSetMethod();
                _setterCache[typeof(TTemplate)].Add(p.Name, (obj,value)=>setterInfo.Invoke(obj, new[]{value}));
}


Each property has a private backing field, so create the field on the proxy type:


var field = typeBuilder.DefineField(string.Format("_{0}", p.Name), p.PropertyType, FieldAttributes.Private); 
              

Next, define the property.


var property = typeBuilder.DefineProperty(p.Name, PropertyAttributes.HasDefault, p.PropertyType,null);

The property needs a getter. This is where the code is a little more interesting becaues it requires emitting IL code. Fortunately, you can build a sample class and use ILDASM.EXE to disassemble it and learn what the proper op codes are. Here is the getter method:


var getter = typeBuilder.DefineMethod(string.Format("get_{0}", p.Name),
    MethodAttributes.Public |
    MethodAttributes.SpecialName |
    MethodAttributes.HideBySig,
    p.PropertyType, Type.EmptyTypes);
var getterCode = getter.GetILGenerator();

getterCode.Emit(OpCodes.Ldarg_0);
getterCode.Emit(OpCodes.Ldfld, field);
getterCode.Emit(OpCodes.Ret);

Next is the setter method. The setter method has some extra code that loads the property name and then calls the property change method. That is why the handle to the method was captured earlier.

var setter = typeBuilder.DefineMethod(string.Format("set_{0}", p.Name), 
    MethodAttributes.Public |
    MethodAttributes.SpecialName |
    MethodAttributes.HideBySig, null,
    new[] { p.PropertyType });

var setterCode = setter.GetILGenerator();

setterCode.Emit(OpCodes.Ldarg_0);
setterCode.Emit(OpCodes.Ldarg_1);
setterCode.Emit(OpCodes.Stfld, field);


// property change
// put the property name on the stack
setterCode.Emit(OpCodes.Nop);
setterCode.Emit(OpCodes.Ldarg_0);
setterCode.Emit(OpCodes.Ldstr, p.Name);
setterCode.Emit(OpCodes.Call, propertyChange);
setterCode.Emit(OpCodes.Nop);               

setterCode.Emit(OpCodes.Ret);

Now that the methods have been generated, they must be attached to the property:

property.SetGetMethod(getter);
property.SetSetMethod(setter);

That's the hard part! The easy part is to define a default constructor (calls down to the base) and create the actual type. Remember, this is the method called in the constructor so the type is returned and stored in the dictionary, then the activator is used to create the instance. Also, go ahead and set up the getter and setter cache:

typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);                        

var type = typeBuilder.CreateType();           

_getterCache.Add(type,new Dictionary<string, Getter>());
_setterCache.Add(type,new Dictionary<string, Setter>());           

return type;

Believe it or not, that's what it takes to build a proxy, assuming the base class contains simple properties and no complex nested types or structures. Here's a simple template to test the proxy with:

public class ContactTemplate
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }       
}

Here's a view model that is based on the template. It uses the property notifier to wrap the properties with property change notification. It also creates a default template in the constructor just to give you some information to work with when the application runs:

public class ContactViewModel : PropertyNotifier<ContactTemplate>
{      
    public ContactViewModel()
    {
        var template = new ContactTemplate
                            {
                                Id = 1,
                                FirstName = "Jeremy",
                                LastName = "Likness"
                            };
        Instance = template;
    }      
}

Now some XAML to bind it all together:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.DataContext>
        <ViewModels:ContactViewModel/>
    </Grid.DataContext>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="First Name: "/>
    <TextBlock Text="Last Name: " Grid.Row="1"/>
    <TextBlock Text="Edit First Name: " Grid.Row="2"/>
    <TextBlock Text="{Binding NotifyInstance.FirstName}" Grid.Column="1"/>
    <TextBlock Text="{Binding NotifyInstance.LastName}" Grid.Row="1" Grid.Column="1"/>
    <TextBox Text="{Binding NotifyInstance.FirstName,Mode=TwoWay}" Grid.Row="2" TextChanged="TextBox_TextChanged" Grid.Column="1" Width="200"/>
</Grid>

When you run the application, you'll find the property change works just fine. Now, with this helper class, anytime you need to take a simple data object and implement property change, you can just wrap it in the property notifier and bind to the InstanceNotifier property. This works perfectly well in Silverlight 4.



European Silverlight 4 Hosting - Amsterdam :: HTTP Error 404.0 - Not Found (MapRequestHandler / StaticFile) when deploying WCF Web API on IIS 7.x

clock February 15, 2012 07:12 by author Scott

If you’re deploying a WCF Web API application to your IIS 7.x you might receive a HTTP Error 404.0 (MapRequestHandler / StaticFile):



As you know, WCF Web API relies on .NET Framework 4.0.

So lets take a look into the application pool for our application:



Everything looks fine here.

So lets dig a little bit deeper – namely inspect the ISAPI Filters:



Looks like ASP.NET 4 is missing here… so lets fix it:

PS C:\Windows\Microsoft.NET\Framework64\v4.0.30319> .\aspnet_regiis.exe -i
Start installing ASP.NET (4.0.30319).
........
Finished installing ASP.NET (4.0.30319).


Now hit F5 in your browser:



(If it’s not working after installing ASP.NET 4.0.x please review the version in your application pools settings again and fix it if necessary).



European Silverlight Hosting - Amsterdam :: Data Driven Example Using Silverlight Business Application

clock February 13, 2012 07:36 by author Scott

This post discusses how to displays data from the AdventureWorks Database on to Silverlight pages. In this walkthrough you will find the page that displays the data from customer table in adventure database and allows the user to traverse the records. You need to have Visual Studio 2010 SP1 installed on your machine.

Silverlight business application contains two projects a Silverlight application and an ASP.NET Web application which hosts the Silverlight application.

To change the application string value that displaying in the page

1. Expand the assets folder and expand the resources

2. Change the application name as shown below and run the application





3. Creating a data model for the application, right click the Silverlight web application click add new item and select the ADO.NET Entity Data model as shown below



In choose model content page, click generate content from database option as shown in the below dialogue



Select the database object that you want to display the data in Silverlight pages



Customer table appear in the entity designer as shown below



Build the solution.

Adding a domain service

A domain service exposes the data model to client. You can add the domain service to the server project as shown below

Right click the ASP.NET web application  and add new item, select the domain service class from project dialogue box



Select the Customers table and Enable Editing checking boxes, and then click ok



Build the solution

Creating a Silverlight page to display data

1. In solution explorer right click the Views folder Silverlight client application, Add New Item dialogue box , select the Silverlight Category and then click the Silverlight Page template.




2.  To display the data in data grid, click the datasources and then click the Show Data Sources

The data source window displays the customer entity, drag the customer node to the designer



3. Add a navigation button to the page that we created above in Homepage as shown below

   1: <Rectangle x:Name="Divider3" Style="{StaticResource DividerStyle}"/>
   2: <HyperlinkButton x:Name="Link3" Content="Customer List"
       Style="{StaticResource LinkStyle}"
   3: NavigateUri="/Customers" TargetName="ContentFrame"/>

4.  Run the application. You will notice Customer List button in navigation bar as shown below




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