Friday, December 18, 2009

Debug a dump of an ASP.NET Web Site - Visual Studio 2010

I have seen video from Scott Hanselmanon Channel 9, about debugging feature in Visual Studio 2010,


Presented technique can be very helpful for solving problems with ASP.NET on the productive web server


http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-Debugging-Crash-Dumps-with-Tess-Ferrandez-and-VS2010/

Thursday, December 10, 2009

I just bought Resharper 4.5

I used trial of Resharper 4.5 for Visual Studio 2008.
Now it is my must have tool for .NET development. I just bought a profesional licence for this product including update to the Resharper 5.0 :)

Why do I like this tool so much?

Because it helps keep my code clean and support code refactoring much better the Visual Studio.

I hope new version for Visual Studio 2010 will be even better.

Tuesday, December 1, 2009

Generate PDF from Reporting Services - cache problem

I develop reports with Reporting Services server and WCF as data sources
Reports are generated in PDF format.

I could not see changes in my reports after updating data.
I found the solution on Peter's Gekko blog.

I added  following  to my report url:

&rs:ClearSession=true

Here is my code:

var reportUrl = ConfigurationManager.AppSettings["ReportURL"];


var reportParameters = @"&rs:Command=Render&rc:toolbar=false&rs:Format=PDf&rc:OmitFormulas=true&rs:ClearSession=true&id=";


System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(string.Concat(reportUrl, reportParameters, myId)), "_blank");

Thursday, November 26, 2009

I started to use features from C# .NET 3.5

I started to use 3 new features i c#.NET 3.5


1) extension method,

I call this  "static  noon-static" :)

such extension method help get user names in one string for the collection

public static string Namen(this List<Benutzer> instance)
{

var namen = new StringBuilder();
foreach (var benutzer in instance)
{

if (namen.Length > 0)
{

namen.Append(", ");

}
namen.Append(benutzer.Vorname);

}
return namen.ToString();

}


2) Auto-Implemented Properties, code snippet in VisualStudio 2008  "prop"

[DataMember]
public stirng Wert { get; set; }

[DataMember]
public string WertTyp { get; set; }


3) implicit type declaration

var masse = new Masse();



LINQ objects, how easy and usefull is this!


I try to use new usefull features from .NET 3.0/3.5 more often.
 
Today I needed to calculate a sum for objects in a List.

Always before I used foreach loops, but in .NET 3.5 I have LINQ. 
I can calculate my result this way:


var anteileSume = stoffList.Distinct().Sum(stoff => stoff.Anteil);




This is just great! :)


Very helpfull list of LINQ samples I found here on MSDN .

Thursday, November 19, 2009

WCF used in Silverlight,

WCF client in Silverlight, has for me two main differences comparing to client implemented in ASP.NET:

- Silverlight works asynchronous with services
- can't use .NET assemblies, Silverlight can use only assemblies compiled as Silverlight assemblies or use libraries from the Silverlight, not from .NET



How to write and consume WCF services in Silverlight is very good described in this article:
http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightServiceAccess

more important parts of mentioned article, that focus on implementation for Silverlight:

- Asynch Pattern, asynchronous calls to the WCF:



   1:  public void LoadBerechnung(RequestDO requestDO)
   2:  {
   3:      AsyncCallback asyncCallback = delegate(IAsyncResult result)
   4:      {
   5:          var item = ((IAsyncBerechnung)result.AsyncState).EndBerechne(result);
   6:          Control.Dispatcher.BeginInvoke(() => SetStoffe(item));
   7:      };
   8:   
   9:      Berechnung.BeginBerechne(stoffRequestDO, asyncCallback, stoffBerechnung);
  10:  }
  11:   
  12:  private void SetStoffe(StoffResultDO stoffResultDO)
  13:  {
  14:      if (stoffResultDO!=null)
  15:      {
  16:          Produkt.prop1.DataSource = stoffResultDO.Text;
  17:          Produkt.prop2.Description = stoffResultDO.ErrorText;
  18:      }
  19:  }

This part i find very important:"There's absolutely no technical reason why Silverlight can't use .NET assemblies." in this articel is detailed description to this topic:
http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightServiceAccess WWith "File-Level Technique" described here I can compile files from .NET assembly as Silverlight assembly.

What can I do, when I have something .NET specific in my data contract file?
I use "conditional compilation symbols" from visual studio project:



#if NETCLR [System.Serializable]#endif
This way its possible, to use logic implemeted for .NET in Silverlight application / very easy :)



Wednesday, November 18, 2009

Consuming WCF services with channel factory



Creating WCF services hosted on IIS server is a very common scenario.
Often service proxy files for a service are generated with help of Visual Studio or by using SvcUtil.exe
Generating proxy is very easy, but I read, that using channel factory is much better and more profesional aproach.

you can read about this on this site:
"...Now we may turn our attention to the client application. To begin, let me start off by reminding everyone that you shouldn't ever use "Add Service Reference" in Visual Studio for magical service client creation. The code is incredibly verbose, hard to manageable, edits are prone to being overwritten, and it's almost always used as an excuse to not actually learn WCF. There are few things worse than having to deal with people who thing they know a product simply because they know how to use a mouse. There are reasons why Juval Lowy, in all his books and talks, repeatedly tells people to avoid using this flawed feature. Fortunately, as professionals, we have the ability to understand how to do things without magic."

For me very important reason is, that I can use my data contract clases from WCF service in my client application. I don't lose functionality implemented in these classes.

Here is my WCF servicve and its client with channel factory

in web application project I inserted service file SVC:

Repository.svc


I skiped implementation of the service class. Important is, that this class implement interface defined in service contract. In this case it is IRepository

WCF configuration in the web application (my service host)





   1:  <service behaviorConfiguration="returnFaults" name="Services.BusinessLayer.Pakete.PaketRepository">
   2:      <endpoint binding="basicHttpBinding" bindingConfiguration="myBinding" contract="Tesa.Etv.Interface.TvAuftrag.ITvAuftragRepository"/>
   3:      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
   4:  service>


Service implementation is hosted on specific web site for example on:

http://localhost/Test/Repository.svc

 now its time for a client.
because we don't generate service proxy file, we can reuse assembly with a contract from the server in a client application.
This way we declare service endpoint in clients configuration file:


   1:  <endpoint address="http://localhost/Test&Repository.svc"
   2:  behaviorConfiguration="Delegation" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding"
   3:  contract="Repository" name="BasicHttpBinding_IRepository" />


Channel factory as a property, to comunicate with service in a web client:




   1:  protected ITvAuftragRepository TvAuftragRepository
   2:  {
   3:      get
   4:      {
   5:          if (Session["_tvService"] == null)
   6:          {
   7:              Session["_tvService"] = new ChannelFactory("BasicHttpBinding_ITvAuftragRepository").CreateChannel();
   8:          }
   9:   
  10:          return Session["_tvService"] as ITvAuftragRepository;
  11:      }
  12:  }
this way wen can comnunicate with WCF from the client application, and reuse classes created for the server interfaces

Data-Driven Services with Silverlight 2

In my web application project, the most of the user interface is implemented in Silverlight 3.
Silverlight uses data from the WCF services.


to understand how Silverlight work with WCF together I recomend book about this:

"Data-Driven Services with Silverlight 2"
http://my.safaribooksonline.com/9780596156688

I read most parts of this book, it helped me a lot.

After readig this book I understand:

1) basic of creating UI w Silverlight - I can read xaml and edit it
2) description in details about data binding in Silverlight
3) Implemetation of WCF services and consuming WCF services in Silverlight

To read about it in short, there is an article written by the author of this book John Papa in msdn magazine:

http://msdn.microsoft.com/en-us/magazine/cc794260.aspx#id0190070

Thursday, November 12, 2009

Very usefull and free screen capture tool - Jing

nice screen capture tool- Jing
http://www.jingproject.com/


With free version you can capture video with lenth up to 5 minutes, how many you want.


In many scenarios 5 minutes of video is full enough.
Videos are in flash format + sound recording

WCF use control that require STA thread



My WCF service use WebBrowser .NET control from System.Windows.Forms.

This control requires STA thread:
The WebBrowser class can only be used in threads set to single thread apartment (STA) mode. To use this class, ensure that your Main method is marked with the STAThreadAttribute attribute.

and WCF service is always MTA thread.

to use webBrowser control in my service i found the workaround here:

I just reused this code sample to my needs and it works great!
With this implementation you can run control that requires STA thread in WCF services, that are MTA.

create class:

  1:  [AttributeUsage(AttributeTargets.Method)]
   2:  public class STAOperationBehavior : Attribute, System.ServiceModel.Description.IOperationBehavior
   3:      {
   4:      //- @AddBindingParameters -//
   5:   
   6:      public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
   7:      {
   8:      //+ blank
   9:      }
  10:   
  11:      //- @ApplyClientBehavior -//
  12:      public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
  13:      {
  14:      }
  15:   
  16:      //- @ApplyDispatchBehavior -//
  17:      public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
  18:      {    
  19:          dispatchOperation.Invoker = new STAInvoker(dispatchOperation.Invoker);
  20:      }
  21:   
  22:      //- @Validate -//
  23:      public void Validate(OperationDescription operationDescription)
  24:      {
  25:      //+ blank
  26:      }
  27:  }
  28:   
  29:   
  30:  public class STAInvoker : System.ServiceModel.Dispatcher.IOperationInvoker
  31:  {
  32:      //- $InnerOperationInvoker -//
  33:   
  34:      private IOperationInvoker InnerOperationInvoker { get; set; }
  35:      //+
  36:   
  37:      //- @Ctor -//
  38:      public STAInvoker(IOperationInvoker operationInvoker)
  39:      {
  40:          this.InnerOperationInvoker = operationInvoker;
  41:      }
  42:   
  43:      //+
  44:      //- @AllocateInputs -//
  45:      public Object[] AllocateInputs()
  46:      {
  47:          return InnerOperationInvoker.AllocateInputs();
  48:      }
  49:   
  50:      //- @Invoke -//
  51:      public Object Invoke(Object instance, Object[] inputs, out Object[] outputs)
  52:      {
  53:          Object result = null;
  54:          Object[] staOutputs = null;
  55:   
  56:          System.ServiceModel.OperationContext context = System.ServiceModel.OperationContext.Current;
  57:          System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
  58:          {
  59:              using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
  60:              {
  61:                  result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
  62:              }
  63:          }));
  64:   
  65:          thread.SetApartmentState(System.Threading.ApartmentState.STA);
  66:          thread.Start();
  67:          thread.Join();
  68:          //+
  69:          outputs = staOutputs;
  70:          //+
  71:          return result;
  72:      }
  73:   
  74:      //- @InvokeBegin -//
  75:      public IAsyncResult InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state)
  76:      {
  77:          return InnerOperationInvoker.InvokeBegin(instance, inputs, callback, state);
  78:      }
  79:   
  80:      //- @InvokeEnd -//
  81:      public Object InvokeEnd(Object instance, out Object[] outputs, IAsyncResult result)
  82:      {
  83:          return InnerOperationInvoker.InvokeEnd(instance, out outputs, result);
  84:      }
  85:   
  86:      //- @IsSynchronous -//
  87:      public bool IsSynchronous
  88:      {
  89:          get { return InnerOperationInvoker.IsSynchronous; }
  90:      }
  91:  }
  92:   

now decorate you service methode with "STAOperationBehavior" attribute, 
and then it should work with controls that require STA.

now my WCF service works with with BrowserControl!

  1:  [STAOperationBehavior]
  2:  public fResultDO Berechne(StoffRequestDO stoffRequestDO)



Wednesday, November 11, 2009

Hosting WCF service in Windows service

my WCF service will be not hosted in IIS as usually, but in windows service.
In this post I will describe whole process of implementing WCF service hosted in windows service, including cross-domain policy issue.


Create web application project.
define service contract


    1:  [ServiceContract(Namespace ="http://StoffBerechnung")] 

   2:  public interface IStoffBerechnung
   3:  {
   4:      [OperationContract] 
   5:      StoffResultDO Berechne(StoffRequestDO stoffRequestDO); 
   6:  }


Then I need data contract for my service.
As a parameter for a service method  I send object of the following class:

   1:  [DataContract]
   2:  public class RequestDO
   3:  {
   4:   
   5:      [DataMember]
   6:      public List Stoffe { get; set; }
   7:   
   8:      public RequestDO()
   9:      {
  10:          stoffe = new List();
  11:      }
  12:   
  13:  }
that contains collection of

   1:  public class StoffDO
   2:  {
   3:      [DataMember]
   4:      public string GefahrSaetze { get; set; }
   5:   
   6:      [DataMember]
   7:      public decimal Stoffgehalt { get; set; }
   8:   
   9:      public StoffDO(string saetze, decimal gehalt)
  10:      {
  11:   
  12:          Saetze = saetze;
  13:          Gehalt = gehalt; 
  14:      }
  15:  }
As a result, WCF service returns object of the following class:

   1:  [DataContract]
   2:  public class StoffResultDO
   3:  {
   4:      [DataMember]
   5:      public string Text { get; set; }
   6:   
   7:      [DataMember]
   8:      public string FehlerText { get; set; }
   9:   
  10:      [DataMember]
  11:      public List<string> ObligatorischeSymbole { get; set; }
  12:   
  13:      [DataMember]
  14:      public List<string> OptionaleSymbole { get; set; }
  15:   
  16:      public StoffResultDO()
  17:      {
  18:          ObligatorischeSymbole = new List<string>();
  19:          OptionaleSymbole = new List<string>();
  20:   
  21:          Text = string.Empty;
  22:          FehlerText = string.Empty;
  23:      }
  24:  }

Now I have complete implementation of my service:

- service contract interface 
- service contract implementation
- data contract

Now its time to implement windows service to host WCF service

   1:  public partial class StoffBerechnungService : ServiceBase
   2:  {
   3:      public ServiceHost serviceHost;
   4:      public Service.StoffBerechnung service;
   5:   
   6:      public StoffBerechnungService()
   7:      {
   8:          ServiceName = "StoffBerechnung.Service"; 
   9:      }
  10:   
  11:      [STAThread]
  12:      protected override void OnStart(string[] args)
  13:      {
  14:          if (serviceHost != null)
  15:          {
  16:              serviceHost.Close();
  17:          }
  18:   
  19:          // Create a ServiceHost for the Service type and provide the base address.
  20:          serviceHost = new ServiceHost(typeof(Service.StoffBerechnung));
  21:          serviceHost.Open(); 
  22:      }
  23:   
  24:      protected override void OnStop()
  25:      {
  26:          if (serviceHost != null)
  27:          {
  28:              serviceHost.Close();
  29:              serviceHost = null;
  30:          }
  31:      }
  32:  }
WCF project configuration file:

   1:  <system.serviceModel>
   2:      <services>
   3:      <service name="Service.StoffBerechnung"
   4:          behaviorConfiguration="StoffBerechnungServiceBehavior">
   5:          <host>
   6:              <baseAddresses>
   7:                  <add baseAddress="http://localhost:8000/StoffBerechnungService"/>
   8:              baseAddresses>
   9:          host>
  10:          
  11:          <endpoint address="" binding="basicHttpBinding" contract="StoffBerechnung.Interfaces.StoffBerechnung" />
  12:          
  13:          <endpoint address="http://localhost:8000/" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior"
  14:          contract="StoffBerechnung.Interfaces.IClientAccessPolicy" />
  15:      service>
  16:      services>
  17:      <behaviors>
  18:      <serviceBehaviors>
  19:          <behavior name="SstoffBerechnungServiceBehavior">
  20:              <serviceMetadata httpGetEnabled="true"/>
  21:              <serviceDebug includeExceptionDetailInFaults="True"/>
  22:          behavior> 
  23:      serviceBehaviors>
  24:      <endpointBehaviors>
  25:          <behavior name="webHttpBehavior">
  26:              <webHttp/>
  27:          behavior>
  28:      endpointBehaviors>
  29:      behaviors>
  30:  system.serviceModel>

Why do I need additional webHttpBinding endpoint and its service behaviour? This additional endpoint exposes clientpolicy.xml file.

When service is hosted in window service, then its in another domain then client application hosted on IIS web server. 
For example http:\\mydomain and http:\\mydomain:8000

That cause cross domain policy issue.

WCf service requires client policy file.
In WCF services hosted on IIS we can just copy policyfile.xml into website root.
In windows service we expose this file using special endpoint.


helpful description: How to solve cross domain policy issue by hosting WCF in windows service: http://www.darkside.co.za/archive/2009/04/09/consuming-self-hosted-wcf-service-silverlight.aspx


I need to implement additional operation contract in my service


   1:  [ServiceContract] 
   2:  public interface IClientAccessPolicy 
   3:  {
   4:        [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
   5:        Stream GetClientAccessPolicy(); 
   6:  } 
for this operation contract I create webHttpBinding endpoint and create implmentation


   1:  public Stream GetClientAccessPolicy()
   2:  {
   3:      string result = Properties.Resources.configurationpolicy; 
   4:   
   5:      if (WebOperationContext.Current != null)
   6:      { 
   7:          WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; 
   8:      }
   9:   
  10:      return new MemoryStream(Encoding.UTF8.GetBytes(result)); 
  11:  }

As you can see, policy file is stored in resources.
my policy file:





   1:  xml version="1.0" encoding="utf-8"?>
   2:  <access-policy>
   3:      <cross-domain-access>
   4:          <policy>
   5:              <allow-from http-request-headers="*">
   6:                  <domain uri="*"/>
   7:              allow-from>
   8:              <grant-to>
   9:                  <resource path="/" include-subpaths="true"/>
  10:              grant-to>
  11:          policy>
  12:      cross-domain-access>
  13:  access-policy>
At the end I install my service using installutil.exe tool Then WCF service hosted in windows service is ready. To check if it works, you can try opening policy file and service endpoint in a browser.