April 2007 - Posts
According to ADO.Net Team announcement earlier today, the ADO.Net Entity Framework will not ship with Visual Studio "Orcas" at the end of this year, but as an update, during the first half of 2008.
For me, this is very bad news. I've been playing with ADO.Net Entity Framework for several month now, since the first CTP. I gave a talk a few months ago about it, and many people had expected it to be released in the next few months.
I definitely don't know all the arguments that led to this decision, but I hoped that the Entity Framework ships in 2 releases. The API first, and the designers afterwards. Well, guess not...
Enjoy!
The ADO.Net team has found a bug in Visual Studio "Orcas" Beta1 where empty CSDL, MSL and SSDL files are generated after the Entity Domain Model wizard completes. They have released a patch for it.
Download it here.
Enjoy!
WF and WCF Integration in "Orcas" - Part 2 - Service Enabled Workflows
This is the second post I am talking about the Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Integration in Visual Studio "Orcas". These posts are being written in "Orcas" Beta 1 time, so the components, namespaces and properties may change in the future, but the principles should stay pretty much the same.
In the previous post, I've talked about Workflow Enabled Services. I have implemented a WCF Service with a workflow and hosted it. This post I am going to talk about Service Enabled Workflows. By this name I mean that a workflow which as part of its logic there is a Service call. This class will be done using the SendActivity that is shown in the first time in "Orcas" Beta 1.
Building a Simple WCF Service
To begin with, build a simple WCF Service. You can use the WCFWFIntegration.ServiceContracts from my previous post instructions to copy the OrderData, OrderInfo and FaultDataContract Data Contracts, and also copy the service contract itself.
[ServiceContract]
public interface IOrdersService
{
[OperationContract]
OrderInfo CreateOrder(OrderData orderData);
}
[DataContract]
public class OrderData { ... }
[DataContract]
public class OrderInfo { ... }
[DataContract]
public class FaultDataContract { ... }
To implement this service, create a new Class Library project and name it WCFWFIntegration.Services.
Add references to System.ServiceModel and WCFWFIntegration.ServiceContracts project.
Implement the service. For demo purposes, I had a random logic in the service:
public class OrdersService : IOrdersService
{
public OrderInfo Create(OrderData orderData)
{
Random rnd = new Random();
OrderInfo info = new OrderInfo();
info.OrderId = rnd.Next(1, 10);
return info;
}
}
To host this service, create a Console Application and name if WCFWFIntegration.Host.
Add references to System.ServiceModel and WCFWFIntegration.ServiceContracts project.
Use the following code snippet to host the service and expose it via Http endpoint:
ServiceHost serviceHost = new ServiceHost(typeof(OrdersService));
Binding binding = new WSHttpBinding();
serviceHost.AddServiceEndpoint(typeof(IOrdersService), binding, "http://localhost:8080/OrdersService");
serviceHost.Open();
Console.WriteLine("Service is listening. Press any key to close...");
Console.ReadLine();
serviceHost.Close();
Make sure the project builds and runs successfully.
Creating a Workflow Client
Create a new Sequential Workflow Console Application and name if WCFWFIntegration.WFClient.
Add references to WCFWFIntegration.ServiceContracts project.
Open the workflow in the designer and drag a SendActivity from the Toolbox.
This activity invokes service calls as part of a workflow. If you take a look at this activity properties you'll see that the ServiceOperationInfo property is erroneous.
Click this property to assign a Service Operation to invoke. This will show the Choose Service Operation Dialog that lets you import an existing Service Contract and choose an operation to invoke.
Use the import button to import the IOrdersService contract and select the Create operation. You can see some of the operation attributes in the lower part of the dialog.
After you confirmed the operation selection, the operation parameters will be dynamically added to the property pane of the SendActivity, and the ChannelToken property (more details later) will become mandatory. Bind it to a new field in your workflow. You should also bind the operation in and out parameters to members of the workflow.
The AfterResponse and BeforeSend properties are events that the activity raises when it executes. You can handle these events and add your logic before and after the call to the service is made.
The ChannelToken property holds the information the SendActivity requires in order to create a channel. It has a EndpointName, Name and OwnerActivityName properties. You should set these properties to values that fits the client endpoint configuration required to communicate with the service.
In order to set these properties, you have to write some code. I used a CodeActivity just before the SendActivity to do this:
this.channelToken.EndpointName = "CreateOrder";
this.channelToken.Name = "CreateOrderToken";
this.channelToken.OwnerActivityName = this.sendActivity1.Name;
while the configuration for the CreateOrder endpoint is:
<configuration>
<system.serviceModel>
<client>
<endpoint name="CreateOrder"
address ="http://localhost:8080/OrdersService"
binding ="wsHttpBinding"
contract ="Bursteg.Samples.WCFWFIntegration.ServiceContracts.IOrdersService"/>
</client>
</system.serviceModel>
</configuration>
Run both Host and WFClient projects and see how the Workflow client invokes the service operation.
In this post I showed how to create a client with Windows Workflow Foundation that invokes a WCF Service. This is an example for a Service Enabled Workflow. You can download a sample project that shows this integration.
Feedback So Far
1. After choosing a service operation, the operation parameters are added to the properties pane. I can bind the parameters, but not the fault contracts. How can I handle exceptions and receive any faults?
2. Debugging is problematic. I cannot debug the workflow that contains the SendActivity. Is it a known issue, or have I done something wrong?
3. I had to manually configure the ChannelToken property values. Is there any more convenient way to do it? Any designer?
4. For some reason, I got an exception saying that one of my data contracts was not marked as serializable. I had to add the Serializable attribute next to the DataContract attribute in order to get things work.
5. The Choose Service Operation dialog allows importing an existing Service Contract. I think it should be able to infer a service definition from its metadata, just like "Add Service Reference", and like the Web Service Activities do.
I will provide more feedback about this integration in the future.
Enjoy!
WF and WCF Integration in "Orcas" - Part 1 - Workflow Enabled Services
I've been waiting for a long time for Beta 1 of Visual Studio "Orcas" to get to play with the WCF and WF Integration. Back in Tech Ed 2006, Dennis Pilarinos talked about the fact that v1 of Windows Workflow Foundation will only enable developers to expose workflows as ASMX Web Services, and v2 will contain the Windows Communication Foundation Integration Activities (Send and Receive).
So, right after I downloaded Beta 1 I build a simple workflow that exposed via WCF Service (a.k.a "Workflow Enabled Service"). This post will show the steps I made in order to do this. You are welcome to use this post as a getting-started-guide.
Creating a Service Contract
Create a new class library called WCFWFIntegration.ServiceContracts.
Add references to System.ServiceModel and System.Runtime.Serialization.
Create the service contract you want to use. For demo purposes, I created the following Service Contract:
[ServiceContract]
public interface IOrdersService
{
[OperationContract]
OrderInfo CreateOrder(OrderData orderData);
}
that uses the following Data Contracts and Fault Contract.
[DataContract]
public class OrderData
{
private int amount;
private string currency;
[DataMember]
public int Amount
{
get { return amount; }
set { amount = value; }
}
[DataMember]
public string Currency
{
get { return currency; }
set { currency = value; }
}
}
[DataContract]
public class OrderInfo
{
private int id;
[DataMember]
public int Id
{
get { return id; }
set { id = value; }
}
}
[DataContract]
public class FaultDataContract
{
private int id;
[DataMember]
public int ErrorId
{
get { return id; }
set { id = value; }
}
private string message;
public string ErrorMessage
{
get { return message; }
set { message = value; }
}
}
Build the project and make sure it compiles.
Creating the Workflow that implements a Service Operation
Add a new project pf type Sequential Workflow Library and name if WCFWFIntegration.Workflows.
Rename the exiting workflow file name to CreateOrderWorkflow. This will also change the name of the class to CreateOrderWorkflow.
Add a reference to the WCFWFIntegration.ServiceContracts project.
Notice that the toolbox contains a new category called Windows Workflow v3.5. This category contains the new Send and Receive activities that implement the integration.

Drag the ReceiveActivity from the toolbox into the design surface. This will add the new activity to the workflow.
Notice that the ReceiveActivity is a composite activity and therefore can contain child activities. This activity executes when a WCF Service Operation is executed and completes when the operation returns a value or a fault. That said, all the service business logic should be implemented as child activities in this activity.
If you go to the properties pane and display the properties of the Receive Activity, you'll notice the ServiceOperationInfo property is marked as erroneous. This means that this ReceiveActivity is not bounded to any Service Operation.
If you click the error sign of this property the Choose Operation dialog will show. You can create a new Service Contract using this Dialog using the Add Contract button, or you can use the Import button to use an exiting contract.
After you choose the Service Contract and the Operation to implement, the input and output parameters will be added to the properties pane. You can bind them to new fields in the workflow.
The ReceiveActivity has some additional properties you should know about:
CanCreateInstance - Indicates whether this Receive activity starts a new workflow instance or uses an existing one. Similar to the IsActivating property of WebServiceInput activity.
FaultMessage - If the service returns a Fault Message, it will return the fault message object specified here.
OperationValidation - This is an event Handler. You can handle this event if you want to validate your parameters, perform security checks and so on.
Since this is the initiating service call, you should set the CanCreateInstance property to True.
Make sure to bind the return value to a new field of type OrderInfo.
Now, you can insert any additional activities as child activities of this ReceiveActivity.
Build this project and make sure if compiles. If you run into an error about missing SMDiagnostics.dll, you can remove the reference to this assembly from the project. This should be solved in later releases.
Hosting the Workflow Service
Create a new Console Application and name it WCFWFIntegration.Host.
Add references to System.ServiceModel and System.WorkflowServices which is the new assembly that contain all the integration components.
Add reference to the Workflow assemblies: System.Workflow.Runtime, System.Workflow.Activities and System.Workflow.ComponentModel.
Add references to the WCFWFIntegration.ServiceContracts and the WCFWFIntegration.Workflows projects.
Use this code to implement this Main method of this application:
WorkflowServiceHost serviceHost = new WorkflowServiceHost(typeof(CreateOrderWorkflow));
WSHttpContextBinding contextBinding = new WSHttpContextBinding();
serviceHost.AddServiceEndpoint(typeof(IOrdersService), contextBinding, "http://localhost:8080/OrdersService");
serviceHost.Open();
Console.WriteLine("Service is listening. Press any key to close...");
Console.ReadLine();
serviceHost.Close();
There are few things you should notice about this code:
1. Instead of using ServiceHost class in order to host a WCF Service, I used WorkflowServiceHost class. This host implements the mechanism of invoking workflows an services. If you look through this type's properties during debug, you'll notice that this service description contain ServiceType = null.
2. I used the WSHttpContextBinding as the binding for calling this service. As similar to standard HTTP binding that enabled cookies, this binding also keeps the context of the service calls. This allows us not to pass the WorkflowInstanceID to every service call explicitly.
Now, you can set the startup project to be the WCFWFIntegration.Host project and run to see if it is running OK.
Creating a Test Client
I still haven't managed to expose any Metadata Exchange endpoint for this service, since there is not actual service that implements this behavior. (Any Idea?) So, I had to couldn't add a service reference and use the generated proxy.
Create a new Console Application and name it WCFWFIntegration.Client.
Add references to the System.ServiceModel, System.WorkflowServices.
Add a reference to the WCFWFIntegration.ServiceContracts project.
Implement the Main method of this application using the following code:
Binding binding = new WSHttpContextBinding();
ChannelFactory<IOrdersService> factory = new ChannelFactory<IOrdersService>(binding, "http://localhost:8080/OrdersService");
IOrdersService proxy = factory.CreateChannel();
OrderData data = new OrderData();
data.Amount = 3;
data.Currency = "USD";
OrderInfo info = proxy.Create(data);
Console.WriteLine(info.Id);
Run both Host and Client projects and see how the client invokes the service operation implemented by a workflow.
You can download a sample project that shows the above integration.
I hope this post gives you a little sense about Workflow Enabled Services in Visual Studio "Orcas". In the next post I'll talk about Service Enabled Workflows. Stay tuned...
Feedback so far
1. I have a problem with the usage of WSHttpContextBinding. This means that a service consumer should know about the fact that this service operation is implemented with workflow.
2. When adding a new class to a workflow library, the file is added with a using directive to the System.Linq namespace. Since the workflow library doesn't contain any reference to this project, the project will not complie.
3. There is a reference to SMDiagnotics.dll in the workflow project that can make problems building this kind of projects.
4. The activities in the designer are wider than they were in Visual Studio 2005. This allows us to name the activities with names that are longer than 9 characters without breaking a line. Although this is a tiny thing, I know it will help me during presentations.
I will provide more feedback about this integration in the future.
Enjoy!
פוסט זה הוא פוסט המשך בסדרה "טיפים וטריקים: כתיבת פוסטים באתר הבלוגים".
בתור בלוגר טכני יוצא לי לפרסם לא מעט קטעי קוד.בעבר הייתי עובד קשה כדי להוסיף קטעי קוד לתוך הפוסטים, אבל בעידן Windows Live Writer, הדברים טיפה יותר קלים.
בצורתו לאחר ההתקנה, Windows Live Writer (להלן WLW) לא מאפשר לעשות Paste לתוכן מפורמט. לכן, הוספת קטע קוד מתוך Visual Studio תראה כך:
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(OrdersService));
host.Open();
Console.WriteLine("Service is listening. Press any key to close...");
Console.ReadLine();
host.Close();
}
כדי בכל זאת להוסיף בכל זאת קטע קוד מפורמט, שיכיל גם את הפונט שאני משתמש בו בעת כתיבה ב- Visual Studio וגם את הצבעים שהופכים את הקריאה והתמצאות בקוד לנוחים במיוחד אני משתמש בשני Add-Ins:
Copy Source As Html - שהוא Add-In ל- Visual Studio, שבעת העתקה של קוע קוד מתוך VS, מייצר ומכניס ל- Clipboard את תגי ה- Html המתאימים.
Insert Formatted Clipboard - הוא Add-In ל- WLW המאפשר לבצע Paste לטקסט מפורמט ובכל להתגבר על הבעייה שציינתי קודם.
בעזרת שני ה- Add Ins הנ"ל אפשר להעתיק Html המכיל קטע קוד מתוך ה- Visual Studio ולשתול אותו בתוך פוסט. ובסופו של דבר זה נראה ככה:
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(OrdersService));
host.Open();
Console.WriteLine("Service is listening. Press any key to close...");
Console.ReadLine();
host.Close();
}
אופציה נוספת היא להשתמש ב- Add In בשם BlogMyCode, שעושה את שתי הפעולות הנ"ל בקליק אחד. כלומר לאחר סימון קטע קוד אפשר להוציא אותי ל- WLW. החסרון בו הוא שעבור כל העתקה נוצר Post חדש, אבל בכל אופן שווה להכיר את האפשרות הזאת.
הורדות:
Windows Live Writer ניתן להורדה מכאן. שימו לב שהוא עדיין בגירסאת בטא. רצוי לקרוא מה שיוסי כתב בנושא הגדרת WLW לשימוש באתר הבלוגים.
Copy Source As Html ניתן להורדה מכאן.
Insert Formatted Text ניתן להורדה מכאן.
BlogMyCode ניתן להורדה מכאן.
תהנו!
פוסט זה הוא פוסט המשך בסדרה "טיפים וטריקים: כתיבת פוסטים באתר הבלוגים".
שאלה: מה משותף לבלוג של שחר, גיא, גיל, עומר, צוות SRL, מירון ועוד רבים אחרים?
תשובה: כולם נראים בדיוק אותו הדבר.
לעומת זאת הבלוגים של אוהד ושל קהילת מומחי המחשוב נראים טיפה אחרת, וזה עושה את ההבדל...
בעיני מאד חשוב לתת לבלוג שלך מראה ייחודי, שיבחין אותו מבלוגים אחרים. משהו שיתן חוויה נעימה יותר לקורא, יוסיף טיפה פן אישי לתוך הדף ועל הדרך גם יפתור מספר בעיות תצוגה של ה- Themes הקיימים.
כדי לשנות את הגדרות הסגנון של הבלוג שלך, אפשר לגשת ל- Control Panel, משם תחת Global Settings, לגשת ל- Change How my Blog Looks, ואחרי שבוחרים את ה- Theme שנראה לכם, אפשר לגשת לטאב ששמו CSS Overrides ולדרוס הגדרות סגנון שבאות עם ה- Theme כברירת מחדל בהגדרות משלכם.
לדוגמא ה- CSS Overrides של הבלוג שלי (מומלץ לצפיה דרך browser ולא דרך RSS Reader) מכיל את השינויים הבאים:
#content
{
width: 1016px;
}
#masthead
{
background-image: url(http://blogs.microsoft.co.il/photos/bursteg/images/original/Title1.aspx);
width: 1028px;
}
#main
{
width: 758px;
}
#nav
{
width: 1016px;
}
.post
{
font-family : Verdana;
margin: 0 0 20px 0;
}
.posthead
{
color: #c60;
}
.posthead a:link, .posthead a:visited, .posthead a:active
{
color: #c60;
}
.posthead a:hover
{
color: #c60;
}
.pageTitle
{
color: #c60;
}
legend
{
color: #c60;
}
#comments h2
{
color: #c60;
}
fieldset textarea
{
width: 674px;
}
fieldset .smallbox
{
width: 674px;
}
שימו לב שאחד השינויים שביצעתי, היה להחליף את התמונה שמגיעה כברירת מחדל עם ה- Paper Clip Theme. בעבר פרסמתי פוסט על איך ליצור תמונה מתאימה לשימוש עם Paper Clip.
דבר נוסף שביצעתי הוא לשנות את רוחב הבלוג. כיוון שאני מפרסם קטעי קוד רבים, רוחב ברירת המחדל של הבלוג היה צר מדי והביא לאי נוחות בעת קריאת קטעי קוד. כיום זה הרבה יותר נוח...
לשימושכם...
In MSDN Magazine May 2007 you can find a new article talking about transaction flowing and propagation in Windows Communication Foundation (WCF). This article shows how easy it is to configure and use transactions in order to build robust and high-quality service oriented applications.
Worth the time...
Enjoy!
Exactly a year ago, on April 11th I joined the Israeli Blogger's Community.
At the beginning I was not sure I could keep up with writing in this blog and didn't know how to write a good post. I began writing about WCF and Enterprise Library 2.0 and had only used 2 tags in my blog.
One year later, with more than 230 posts in my blog, and more than 20 tags, I can say I have a little addiction to blogging. I find myself documenting every piece of knowledge I gain, and really enjoying it!
So, I think after one year I can make a little survey for the blog readers in order to get some feedback. I'd appreciate if you take a few minutes to leave a comment with answers to the following questions:
- How often do you read this blog? Do you read it via RSS feed?
- Do you find this blog interesting? Is the information in this blog helpful in your daily work?
- What are the things you like most in this blog?
- What do you think should be improved in this blog?
Thanks you for your feedback!
As I have posted earlier, the first community drop of Web Service Software Factory v3 was announced this week, and the biggest thing in this release are the two new designers for Service Contracts and Data Contracts.
To demonstrate the designers, Don Smith has recorded a short video (very recommended).
Seeing this video, I couldn't stop thinking about the similarity between the Data Contract Designer and the Entity Data Model Designer that is part of ADO.Net Entity Framework (watch the EDM Designer in this video). In both designers you can add data entities, add properties and create relations, and finally, generate the code for them.
In the latest CTP's of "Orcas", the generated entities code can be decorated with DataContract attributes to enable WCF Serialization. That brings me to think that there is a certain redundancy in creating both designers on one hand, but keep them separated on the other.
So my feedback for the p&p team is to come up with a way to keep ADO.Net Entity Framework in mind while building this great software factory. For example, import an Entity Data Model as a Data Contracts model and only set the additional data contracts properties such as IsRequired, Order etc. I promise to keep watching this software factory as it develops and providing more feedback.
Good luck p&p team!
Enjoy!
פוסט זה הוא פוסט המשך בסדרה "טיפים וטריקים: כתיבת פוסטים באתר הבלוגים".
מספר בלוגרים שאלו אותי למה עברתי להשתמש ב- Feed Burner ואיך עוברים את זה בשלום, אז החלטתי להקדיש פוסט לנושא...

לגבי השאלה למה? התשובה מבחינתי היא סטטיטיקות קריאות לבלוג. אני יכול לראות כמה גישות יש לבלוג שלי, מהם הפוסטים הפופלארים וכו'. בקיצור רציתי לדעת האם מישהו באמת קורא את מה שאני כותב או שאני עושה את זה רק לעצמי. ושמחתי לגלות את התשובה...
לכל המתלבטים או סתם למתעניינים, הנה מדריך קצר:
מציאת כתובת ה- Private RSS Feed של הבלוג שלכם
כנסו ל- Control Panel של הבלוג שלכם, ותחת הקטגוריה Global Settings, כנסו ל- Syndication Settings. מסך זה מאפשר לכם להגדיר את התנהגות ה- Syndication של הבלוג, ובין היתר מאפשר לציין כתובת RSS Feed חיצונית. כאן נזין בהמשך את כתובת ה- Feed החדש שניצור.
שימו לב שבמסך זה למטה יש שתי כתובות Private RSS Feed ו- Private Atom Feed. יש להעתיק אותן, כיוון שנשתמש בהן בשלב הבא.
הצטרפות לשירות
להצטרפות, כנסו ל- http://www.feedburner.com, ובחרו בסרגל הכלים העליון באפשרות Register.

אחרי שתעברו את מסך הרישום, תוכלו לצרוב את כתובת הבלוג שלכם.
חשוב!
במסך זה יש להזין את כתובת ה- Private RSS (אותה כתובת שנמצאת בתחתית המסך Syndication Settings שבוקרנו בו קודם), ולא את כתובת ה- RSS של הבלוג שלכם. הסיבה היא שלאחר התהליך כתובת ה- RSS של הבלוג עומדת להשתנות ואז תיווצר הצבעה דו כיוונית ושום דבר לא יעבוד.
לאחר מכן (במסך הבא), יש לתת ל- Feed החדש כותרת (לדוגמא: Guy Burstein's Blog) ושם (לדוגמא GuyBursteinsBlog) שיצטרף לקידומת http://feeds.feedburner.com ויחד יהוו את הכתובת המלאה של ה- Feed. לסיום יש ללחוץ על Activate Feed.
בשלב הזה, תקבלו מסך Congratulations שמברך אתכם על סיום יצירת ה- Feed ומזמן אתכם לשדרג את החשבון בתוספת סכום סמלי.
שינוי ה- Feed באתר הבלוגים ל- Feed החדש
בחזרה למסך Syndication Settings, אפשר כעת למלא את השדה External Feed URL בכתובת ה- Feed החיצוני (http://feeds.feedburner.com/GuyBursteinsBlog), וללחוץ Save.
עכשיו, אם תכנסו לבלוג שלכם, ועברו עם העכבר מעל הלינק ל- RSS Feed שלכם, תראו שהוא התעדכן ל- Feed החדש.
סטטיטיקות על קוראי הבלוג
Feedburner אוסף ומציג סטטיסטיקות הקריאות של ה- RSS Feed של הבלוג כל 24 שעות האחרונות.
צריך לקחת את המספרים שהוא רושם בעירבון מוגבל, כיוון שחלק מ"קוראי" ה- Feed הם כל מיני Bots ו- Aggregators שקוראים את כל הבלוגים ואוספים פוסטים בכל מיני נושאים.
במסך הזה אפשר לבחור יום מסויים, ובו לראות את התפלגות הקוראים לפי פוסטים, התפלגות לפי סוגי תוכנות קריאת RSS וכו'.
באותו מסך, בטאב שנקרא Publicize ישנם מספר שירותים, שהחשוב ביניהם לדעתי הוא ה- Feed Count:
במסך מופיע תג ה- Html שיש להוסיף לבלוג ע"מ להציג את הסטטיסטיקה (פרטים בהמשך). בנוסף אפשר לשנות טיפה את הצבעים של הכיתוב והרקע כדי ליצור מראה ייחודי. במידה ותשנו, אז הקוד של תג ה- Html ישתנה גם הוא.
ב- Control Panel של הבלוג, תחת Global Settings יש לבחור ב- Title, Description, and News ובשדה News יש להוסיף את ה- Html של ה- Feed Count.
וזהו, מסודרים... (לא כמו גיא, תומר, קליינר וברלד... אבל יש לכם Feed חדש).
תהנו!
WCF Exception Handling with Exception Handling Application Block Integration
This post is one of a post series about WCF Integration in Enterprise Library 3.0. Specifically, this post is the first post I am talking about the integration between Exception Handling Application Block and Windows Communication Foundation (WCF). This post has a brief overview about the Exception Handling Application Block (EAB) and the WCF Fault Handling. Then, this post explains how to use the EAB integration with WCF.
Exception Handling Application Block
If you're familiar with the Exception Handling Application Block, you can skip to the next section. If you're not, stay around. To simply put it, the EAB works with exception handling policies. You configure a exception policy in the configuration file, and add one or more exception handlers to it. For example, the following configuration snippet configures a policy called "Server Policy" that replaces a Security Exceptions with Application Exceptions, and wraps a DB Concurrency Exception with a custom Exception Type.
<exceptionPolicies>
<add name="Server Policy">
<exceptionTypes>
<add name="SecurityException"
type="System.Security.SecurityException"
postHandlingAction="ThrowNewException">
<exceptionHandlers>
<add name="Replace Handler"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler"
exceptionMessage="Replaced: User is not authorized to perform the requested action."
replaceExceptionType="System.ApplicationException, mscorlib" />
</exceptionHandlers>
</add>
<add name="DBConcurrencyException"
type="System.Data.DBConcurrencyException, System.Data"
postHandlingAction="ThrowNewException">
<exceptionHandlers>
<add name="Wrap Handler"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WrapHandler"
exceptionMessage="Wrapped Exception: An error occurred while attempting to access the DB."
wrapExceptionType="MyApplicationException, MyApplication.Excecptions" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
Then, on order to handle an exception when caught, we use the following code:
try
{
// Do some operation that may cause an exception
}
catch
{
// Use the EAB to handle the exceptions according to the configuration
if ( ExceptionPolicy.HandleException(ex, "Server Policy") ) throw;
}
WCF and Exceptions
These is a lot to say about what happens when an exception occurs in a WCF Service Operation. To make a long story short, I'll say that the exception is not thrown back to the client and the channel becomes in Faulted state. The idea behind this design is that you don't want to reveal any information about the error that has occurs because it can contain information you don't want to share. For example, if you expose a Web Service to the Internet for other organizations to consume, you don't want them to know that you cannot insert a new record to table "tblUsers" because a user with name "Guy" already exists.
If you still want to return excecptions back to the client (recommended only during development time), you can add a service behavior:
<serviceBehaviors>
<behavior name="Debug">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
Note that this configuration is used only for unhandeled exceptions. If you are using a FaultContract to specify what type of faults your service might return, this setting will not change a thing about it.
Exception Handling Application Block Integration with WCF
In this post, I will not get into details about how the integration works, and I will focus on the things you should do or configure in order to benefit from this integration.
First, you have to create a Data Contract that will contain the details about the error that has occurred. For example:
[DataContract]
public class ServiceFault
{
private string message;
private Guid id;
[DataMember]
public string MessageText
{
get { return message; }
set { message = value; }
}
[DataMember]
public Guid Id
{
get { return id; }
set { id = value; }
}
}
Second, you have to create a WCF shielding policy in the exception handling policies section in the configuration file, as displayed in this configuration snippet.
<exceptionHandling>
<exceptionPolicies>
<add name="WCF Exception Shielding">
<exceptionTypes>
<add type="System.InvalidOperationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException" name="InvalidOperation">
<exceptionHandlers>
<add type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF"
name="DefaultFaultContract Handler"
faultContractType="Bursteg.Samples.WCFIntegration.ServiceContracts.ServiceFault, Bursteg.Samples.WCFIntegration.ServiceContracts">
<mappings>
<add name="Id" source="{Guid}"/>
<add name="MessageText" source="{Message}"/>
</mappings>
</add>
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
There are few things that you should notice in the above snippet:
1. The default name of the exception handling policy is WCF Exception Shielding. The exception handling app. block will look for this name if you don't tell it otherwise (more details later).
2. Make sure that the PostHandlingAction of the policy is ThrowNewException. This means that the exception with the FaultContract in it will be thrown after the handling is done.
3. The Exception handler called DefaultFaultContract Handler is an Exception Handler of type FaultContractExceptionHandler (more details on the next post) which converts the handled exception (this time it's System.InvalidOperationException) to the FaultContract specified in the faultContractType attribute.
4. What this handler does in order to convert an exception to the configured fault contact, is simply mapping of properties according to the <mappings> list above. In this case the property MessageText in the ServiceFault class will get the value in the Message property of the exception. Notice that the Id property of the ServiceFault is mapped to the source {Guid}. This means that the Id property will have the Handling Instance Id property of the exceptions that is automatically created by the Exception Handling Application Block.
Third, you have to add the exception shielding into the service contract or the service class. This is done by the [ExceptionShielding] attribute.
[ServiceContract]
[ExceptionShielding]
public interface IOrdersService
{
...
}
If you changed the name of the policy that the exception shielding is using from WCF Exception Shielding, or you have many services and each one has its own specific policy, you should pass the name of the policy to this attribute:
[ServiceContract]
[ExceptionShielding("Policy Name")]
public interface IOrdersService
{
...
}
As I mentioned earlier, the FaultContractExceptionHandler converts the exception to a Fault Contract. This means that you have to specify the FaultContract to your service contract in order for receiving it in the client side:
[ServiceContract]
[ExceptionShielding]
public interface IOrdersService
{
[OperationContract]
[FaultContract(typeof(ServiceFault))]
int CreateOrder(string currency, double amount);
}
One thing you should note is that if you used the <serviceDebug> option and set the includeExceptionDetailInFault to true, the exception shielding will not work. So be sure to turn this option off.
Now, in order to receive this meaningful exception in the client, you should catch a FaultException<T> where T is the FaultContract use used.
try
{
// Call the service method that has a fault contract on it
}
catch (FaultException<ServiceFault> ex)
{
ServiceFault fault = ex.Detail;
Console.WriteLine(fault.MessageText);
Console.WriteLine(fault.Id);
}
You can download a sample project that shows this integration.
Enjoy!
This post is one of a post series about WCF Integration in Enterprise Library 3.0. Specifically, this post is the forth post I am talking about the integration between Validation Application Block and Windows Communication Foundation (WCF). In the first post I talked about the kinds of parameters validation that can be used. In the second post I talked about what happens when the parameters are not valid. In the third post I talked about how to extend WCF with the Validation Application Block to enable validation. This post will explain how the integration really built and how it works.
Parameter Inspector
WCF has many extensibility points over its layers. You can extend the Service Model, the Channel Layer, the Messaging Layer and so on. One of ways to extend WCF is using a Parameter Inspector. A parameter inspector enables inspection or modification of information prior to and subsequent to calls on either the client or the service. In order to implement a parameter inspector, one should implement the IParameterInspector Interface:
public interface IParameterInspector
{
void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState);
object BeforeCall(string operationName, object[] inputs);
}
Operation Description
Without getting in to much details about it, WCF separates the static descriptions of the operations, contracts and endpoints and the runtime definitions of them. When you create a proxy on the client or when you create a Service Host on the server, WCF builds the runtime description of the contracts, operations and endpoints. During this creation of the runtime description, all the behaviors and extensions are added.
You can use the following code in order to get a reference to the OperationDescription which you want to add the parameter inspector to, and see in runtime what are the values of its properties:
public OperationDescription GetOperationDescription(Type contractType, string operationName)
{
ContractDescription contract = new ContractDescription(contractType.Name);
OperationDescription operation = new OperationDescription(operationName, contract);
operation.SyncMethod = contractType.GetMethod(operationName);
return operation;
}
Once you have the OperationDescription, you can create an instance of the ValidationParameterInspector:
ValidationParameterInspector validationInspector = new ValidationParameterInspector(operation, "myRuleset");
Now, you can test the validation of your service operations without having to use a client:
try
{
// Create the data contract parameter to pass to the operation
OrderData orderData = new OrderData();
orderData.Amount = 3.0;
orderData.Currency = "ASD";
validationInspector.BeforeCall("CreateOrder", new object[] { orderData });
}
catch (FaultException<ValidationFault> e)
{
ValidationFault fault = e.Detail;
DisplayFault(fault);
}
One thing you should know is that the ValidationParameterInspector has implementation only for the BeforeCall method (makes scene...), so you should not test the AfterCall method.
Validation Behavior
As I mentioned in an earlier post, you can use the ValidationBehavior attribute above a service contract to tell the WCF runtime to add the validation behavior. This behavior implements both IEndpointBehavior and IContractBehavior interfaces apply extensions to the runtime service contract and endpoint descriptions. In the case of the Validation Application Block, this behavior adds the above Parameter Inspector.
I hope this post helps you to understand how the Validation Application Block Integration with WCF works.
Enjoy!
Since the Service Factory was released its first version, back in July 2006, a great deal of work has been done. The Service Factory v1 (July 2006) contained the guidance for building ASMX Web Services. The v2 (December 2006) was released after the release of .Net Framework 3.0 and added the guidance for building WCF Services.
Today, Don Smith has announced posted the first community drop of Service Factory v3. Although no new distributed systems technology was released from January, the v3 brings some new and important improvements.
The biggest thing is the addition of models. You now have visualization of the application you're building. Currently, in this drop, there are 2 designers - for Service Contracts and for Data Contracts.
Service Contract Designer:
Data Contract Designer:
Another improvement is that you don't have to decide in which technology you want to implement the service from the very beginning. You can postpone this decision as late as you like.
As Don mentions, the v3 of Service Factory should be released in October, and until then we can expect to see a new and updated drop every 2 weeks on Friday.
Enjoy!
More Posts
Next page »