Oct
5
Written by:
Michael Washington
10/5/2013 6:28 AM
The primary reason you may want to use WCF RIA Services with Visual Studio LightSwitch 2013 is to:
- Combine more than one entity into a single entity.
- Eliminate unneeded columns in an entity to improve performance (otherwise large amounts of data, for example pictures, will be transmitted even when they are not shown).
- Implement calculated fields that allow the resulting values to be searchable and sortable.
The LightSwitch OData services return one Entity collection at a time. This makes grouping and totaling across Entity collections difficult. Using WCF RIA Services provides a clean elegant solution.
The official documentation from Microsoft on creating WCF RIA Services is available at this link.
WCF RIA Services have been covered previously on this site. This article reflects the latest changes in Visual Studio 2013.
The Sample Application
We start with the application used in the article: Online Ordering System (An End-To-End LightSwitch Example).
We upgrade it to Visual Studio 2013.
We now want it to display the total for each Order on the Main page.
Create A WCF RIA Service
First, Add a New Project to the existing LightSwitch project.
Create a Class Library called WCF_RIA_Project.
Delete the Class1.cs file that is automatically created.
Add a New Item to WCF_RIA_Project.
Add a Class called WCF_RIA_Service.cs.
The Class file will show in the Solution Explorer.
Right-click on References and select Add References to add the following references to the WCF_RIA_Project…
- System.ComponentModel.DataAnnotations
- System.Configuration
- System.Data.Entity
- System.Runtime.Serialization
- System.Web
To add a reference to System.ServiceModel.DomainServices.Server, click the Browse button…
Navigate to %ProgramFiles%\Microsoft SDKs\RIA Services\v1.0\Libraries\Server and select it.
Click the Add button.
Click OK.
Add the following Using Statements to the class:
using System.Data.EntityClient;
using System.Web.Configuration;
using LightSwitchApplication.Implementation;
(LightSwitchApplication will display with a squiggly red line because the class is missing, but it will be added in the next step)
Reference The LightSwitch Object Context
Now, we will add code from the LightSwitch project to our WCF RIA Service project. We will add a class that LightSwitch automatically creates, that connects to the database that LightSwitch uses.
We will use this class in our WCF RIA Service to communicate with the LightSwitch database.
Right-click on the WCF_RIA_Project and select Add then Existing Item.
Navigate to ..Server\GeneratedArtifacts (in the LightSwitch project) and click on ApplicationDataObjectContext.cs and select Add then Add As Link.
We used “add As Link” so that whenever LightSwitch updates this class, our WCF RIA Service is also updated.
This is how our WCF RIA Service would be able to see any new Entities (tables) that were added, deleted, or changed.
The file will show in the project.
Create the Domain Service
Replace the entire code for the WCF_RIA_Service.cs file with the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Server;
using System.Data.EntityClient;
using System.Web.Configuration;
using LightSwitchApplication.Implementation;
namespace WCF_RIA_Project
{
// This class is used as the class that is returned
// This can have any 'shape' you desire
// Make sure this is outside of the WCF_RIA_Service class
// but inside the WCF_RIA_Project namespace
public class EnhancedOrder
{
[Key]
public int ID { get; set; }
public string UserName { get; set; }
public DateTime OrderDate { get; set; }
public decimal? OrderTotal { get; set; }
}
public class WCF_RIA_Service : DomainService
{
// This Context property is code that connects to the LightSwitch database
// The code in the Database connection region can be reused as it is
#region Database connection
private ApplicationData m_context;
public ApplicationData Context
{
get
{
if (this.m_context == null)
{
string connString =
System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["_IntrinsicData"].ConnectionString;
EntityConnectionStringBuilder builder = new EntityConnectionStringBuilder();
builder.Metadata =
"res://*/ApplicationData.csdl|res://*/ApplicationData.ssdl|res://*/ApplicationData.msl";
builder.Provider =
"System.Data.SqlClient";
builder.ProviderConnectionString = connString;
this.m_context = new ApplicationData(builder.ConnectionString);
}
return this.m_context;
}
}
#endregion
[Query(IsDefault = true)]
public IQueryable<EnhancedOrder> GetAllOrders()
{
// Get all the Order Details
var colEnhancedOrder = from Orders in this.Context.Orders
// Shape the results into the
// EnhancedOrderDetail class
select new EnhancedOrder
{
// The Order ID
ID = Orders.Id,
// The Order Date
OrderDate = Orders.OrderDate,
// The UserName
UserName = Orders.UserName,
// The order Total
OrderTotal =
// Get all order details lines of the Order
(from OrderDetails in Orders.OrderDetails
// Group the products in the Order Details
group OrderDetails
by OrderDetails.OrderDetail_Product into grouping
// Shape a new entity
select new
{
// Create a total property that is the Quantity times the
// Product price
TotalOrder = grouping.Sum(x => x.Quantity)
* grouping.Sum(x => x.Product.ProductPrice),
}).Sum(x => x.TotalOrder) // Add the sum of all the TotalOrders
};
return colEnhancedOrder;
}
// Override the Count method in order for paging to work correctly
protected override int Count<T>(IQueryable<T> query)
{
return query.Count();
}
}
}
Consume The WCF RIA Service
Build the solution.
In the Solution Explorer (of the LightSwitch project), right-click on the Server project and select Add Data Source.
Select WCF RIA Service and click Next.
The wizard will look for WCF RIA Services.
This step can take a long time because it wont find any at this point.
Eventually the Add Reference button will be enabled.
Click it.
Select Solution then Projects and then the WCF_RIA_Project and click OK.
The wizard will look for WCF RIA Services.
The wizard will find the WCF_RIA_Service in the WCF_RIA_Project.
Click Next.
Check the box next to the Entities, and click Finish.
The Entity will display.
Consume the WCF RIA Service
We can now add the collection to a screen as we would any other collection.
We open the Main screen and select Add Data Item, and select the EnhancedOrders collection.
The collection will show in the View Model on the left-hand side of the screen.
We drag and drop it to the design surface.
We can change the control type to a Table.
We delete unneeded fields.
We can allow an Order to be edited by selecting the table and wiring up a method to the Item Tap action.
We right-click on the method and select Edit Execute Code.
We use the following code for the method:
myapp.Main.EnhancedOrders_ItemTap_execute = function (screen) {
// Get the Order entity that has the same ID
// as the selected EnhancedOrders entity
myapp.activeDataWorkspace.ApplicationData
.Orders_SingleOrDefault(screen.EnhancedOrders.selectedItem.ID)
.execute().then(function (result) {
// Get the OrderEntity
var OrderEntity = result.results[0];
// Open the showAddEditOrder screen
myapp.showAddEditOrder(OrderEntity, {
afterClosed: function (AddEditOrderScreen, navigationAction) {
// If the user commits a change
// refresh the Screen.
if (navigationAction === msls.NavigateBackAction.commit) {
// Refresh the screen collections
screen.EnhancedOrders.refresh();
screen.Orders.refresh();
}
}
});
});
};
When we run the application the orders will show with their calculated field.
Note, when you build the project, do not be concerned about the warnings. However, you can get rid of them by following the directions at this link: Getting rid of compilation warnings in an intrinsic ria service.
WCF RIA Services Can Read, Update, Insert, and Delete
See the article: WCF RIA Service: Combining Two Tables for an example.
Download Code
The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx
(you must have Visual Studio 2013 (or higher) installed to run the code)
48 comment(s) so far...
Brilliant !
I've been looking all over for this
Thank you for all your great work fro the Lightswitch community
Mick
By MDL on
10/19/2013 4:27 AM
|
Great Article. I little question, using that estructure, in this case VS is going to publish a WFC_RIA_serviceData.svc file wich grant acces to the information via OData So, ¿Do you know if you can add more security to that particular file? (QueryInterceptor, filter, etc)...and more important...How?
Regards,
Gabriel
By Gabriel Marazzi on
12/13/2013 5:39 AM
|
@ Gabriel Marazzi - See my answer in the official LightSwitch forums at: http://social.msdn.microsoft.com/Forums/vstudio/en-US/1ffaeadd-abbd-42c4-a712-45f022300b3b/wcf-ria-services-and-odata-security?forum=lightswitch
By Michael Washington on
12/13/2013 6:24 AM
|
Michael,
Great job as usual. Can you please elaborate how to move the WCF RIA Service created here over to Azure so that LightSwitch would use it instead? Basically I am trying to create a solution with LightSwitch , WCF RIA and Database all in Azure. Thanks.
By Frank on
12/20/2013 1:07 PM
|
@Frank - Please make a post on the official LightSwitch Forums at: http://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
12/20/2013 1:08 PM
|
Hello Michael,
I have the following use case : I have a button on UI, from which I want to trigger the execution of a sql stored procedure, through a wcf ria ExecuteCommand(cmdName) method. (in fact I have many such buttons, which trigger many different procedures, and a 'generic' method to call them)
Because providing the procedure name and parameters from java-script screen to call a wcf ria method would pose a security risk (because client-server communication can be intercepted, and sensible information stolen at server calls) I therefore only want to send from the screen to wcf ria a signal to execute a command X; after this, in wcf ria I would get all the parameters I need from the lightswitch context, neccesary for the command X, and after this execute the stored proceduce safely.
My problem is getting all the data I need: if in my lightswitch datasource I have queries defined on tables, is there any way to call them in wcf ria ? (I see that my queries defined in lightswitch visual editor are not visible in wcf ria). for example I have defined a query in lightswitch : AgentsTable.GetCurrentAgent() (that returns a agent entity whose username is the same as Application.User.Name), how whould I call this query in wcf ria ?
Or atleast, is there a way to get Application.User in wcf ria ?
Thanks
By Gabriel Cazan on
4/12/2014 11:32 AM
|
Hi Michael, i followed your instructions here to create a ria webservice. But sometimes i cannot build the solution. as soon as i include the ApplicationDataObjectContext.cs as a link the solution will no longer build. when i remove the link to ApplicationDataObjectContext.cs the build runs fine.
you have any ideas what the Problem is?
Regards Thomas
By DarkSideNRW on
3/30/2014 9:45 AM
|
@DarkSideNRW - Sorry no, I use this all the time and it works for me.
By Michael Washington on
3/30/2014 10:05 AM
|
@DarkSideNRW - I have same problem. Did you find out what solution was?
By Mark Anderson on
4/12/2014 10:24 AM
|
@ Gabriel Cazan - You will want to post to the official LightSwitch forums at: http://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
4/12/2014 11:34 AM
|
This post appears to apply to Lightswitch HTML projects. Are you aware of any easy to understand instructions for enabling RIA Services for Lightswitch 2013 Desktop ?
By Gustav Scholtz on
4/19/2014 4:43 AM
|
@Gustav Scholtz - The WCF RIA service is the same, consuming it is different, but the only change is that you use the Desktop Clint Screen.
By Michael Washington on
4/19/2014 4:47 AM
|
Hi Michael,
Thank you very much for this very helpful article. This is what I'm looking for - A 'native' way to feed customize data to LS html client.
But unfortunately, looks like it doesn't work with the latest VS/LS update. Even the sample project doesn't work.
Could you please help to provide the update on this?
Thanks again!
Yelong
By Yelong on
5/6/2014 8:08 AM
|
@Yelong - I have the March update and I tested the code and it works.
By Michael Washington on
5/6/2014 1:03 PM
|
HI Michael, I tried your tutorial step by step but was not able to find ApplicationDataObjectContext.cs file in my server project. Im using VS 2013 -with march 2014 update.
By priyanka on
6/17/2014 9:26 AM
|
@priyanka - You have to have at least one table in your project and to build the project for the ApplicationDataObjectContext.cs to exist. That is why the first step in the tutorial is to start with the project created in the End-To-End tutorial :)
By Michael Washington on
6/17/2014 3:07 PM
|
Hi Michael,
great article and website - I am a frequent visitor. I have followed this article and built a WCF RIA service which compiles fine. However, when calling any function in the service no data is returned. I am not querying the intrinsic database, but SQL Server 2012. Are there any changes that I need to make to get it to work (other than changing the context connection string) against SQL Server?
Regards,
Alan
By Alan Barnard on
6/30/2014 3:45 AM
|
@Alan Barnard - This tutorial only works for querying the intrinsic database.
By Michael Washington on
6/30/2014 3:46 AM
|
@Michael, does the LightSwitch with WCF RIA Service support CRUD, how LightSwitch know which method should be invoked(for create/delete/update),is there some sample I can follow?
By ArthurJiang on
7/22/2014 3:46 AM
|
@ArthurJiang - See http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/187/LightSwitch-HTML-Picture-Manager-Using-WCF-RIA-Services.aspx for a CRUD example.
By Michael Washington on
7/22/2014 3:50 AM
|
I have a problem with creating and using classes in LightSwitch 2013. I used the example by Beth on sending smtp mail to try to send a mail in the 2013 version but is not working. I created the class and stored it in a folder I named utilitypack under the server section.
So, I went back to consume it under one of the entities class but it flagged error -smtpmailhelper not defined!
Please help me, how can I declare the class in the consuming area?
By Fred on
11/19/2014 4:53 AM
|
@Fred - Because this is not related to WCF RIA Services please post your question on the official LightSwitch Forums for better help: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
11/19/2014 4:57 AM
|
I am able to configure the environment successfully but Unable to load data from entities. What may be the reason for this
By mannu on
12/9/2014 4:35 PM
|
Thank you Michael for this and the vast amount of examples & tutorials.
I have a WCF RIA wrapper around a SOAP service and all the simple entities work just fine thanks to examples like this one. Unfortunately Lightswitch does not like my represenation of complex entities like SalesInvoice that contains a list of SalesInvoiceLines. How should I represent such an entity in RIA so that Lightswitch can accept it?
By MisterB on
1/3/2015 5:07 AM
|
@MisterB - I do not have any examples but you can find some on the internet. However, What I do is to only use simple entities (without any properties that represent nested collections) and them create the associations needed in the LightSwitch entity designer using the Relationship button. If you need further help please post your question on the official LightSwitch Forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
1/3/2015 5:55 AM
|
Thank you Michael I will try your method and post any other questions to the official forum.
By MisterB on
1/4/2015 1:42 AM
|
@Michael - Nice work, but! The solution proposed by Bess much better, because you do not need to create any additional WCF RIA service and the code is two to three times shorter. http://blogs.msdn.com/b/bethmassi/archive/2014/05/01/storing-images-in-azure-blob-storage-in-a-lightswitch-application.aspx TNX for idea, your code help me in copypasting for Picture_Inserting, _Updating, _Deleting, Query_Executed and saved much time for me!!!
By Serguei Vine on
4/6/2015 6:28 AM
|
May the Seven Gods bless you for this, I have been struggling with a problem like this for a month, why doesnt this article show up first on google?
By Alpha Shuro on
4/9/2015 3:50 AM
|
If you're getting this error, "Inner exception message. Invalid object name dbo". It could be because of your connection string. Use the code here for your connection string, https://msdn.microsoft.com/en-us/library/gg589479.aspx
By Jerry on
4/24/2015 10:56 AM
|
Hi Michael, great post and example. We are here trying to build up a simple mock-up with LS and Dynamics Crm and use it as potential platform for enterprise solutions. Everything goes perfect so far but we are struggling loading the ContextData Object, we are trying to create that object exactly as the platform does but apparently the connection string is not valid (?). This is the code, pretty much the same that you had in your sample:
string assemblyName = global::System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; string connString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["MYContextData"].ConnectionString; EntityConnectionStringBuilder builder = new EntityConnectionStringBuilder(); builder.Metadata = "res://" + assemblyName + "/WCF_RIA_MyServiceData.csdl|res://" + assemblyName + "/WCF_RIA_MyServiceData.ssdl|res://" + assemblyName + "/WCF_RIA_MyServiceData.msl"; builder.Provider = "System.Data.SqlClient"; builder.ProviderConnectionString = connString; this.m_context = new CSMADevContextData(builder.ConnectionString);
And this is the error: {"Keyword not supported: 'service url'."}
Web config connectionString="Service Url=http://myserver/myCRM/XRMServices/2011/OrganizationData.svc;Is Windows Authentication=True;Allow Invalid Certificate=False" />
which is weird because we were looking into the GeneratedArtifacts/DataServiceImplementation.cs and looking at how LS create the context and apparently is the same code.
Any comment will be welcome,
Cheers. Israel
By Israel de Andrés on
4/25/2015 4:48 AM
|
@Israel de Andrés - There are products that will connects LightSwitch to Dynamics CRM. For help, please post your question on the official LightSwitch Forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
4/25/2015 4:48 AM
|
Hi Michael, Great article, and great site !
I just can't seem to get the following code working in VB.
Could you please take a look at it ?
public IQueryable GetAllOrders() { // Get all the Order Details var colEnhancedOrder = from Orders in this.Context.Orders // Shape the results into the // EnhancedOrderDetail class select new EnhancedOrder { // The Order ID ID = Orders.Id, // The Order Date OrderDate = Orders.OrderDate, // The UserName UserName = Orders.UserName, // The order Total OrderTotal = // Get all order details lines of the Order (from OrderDetails in Orders.OrderDetails // Group the products in the Order Details group OrderDetails by OrderDetails.OrderDetail_Product into grouping // Shape a new entity select new { // Create a total property that is the Quantity times the // Product price TotalOrder = grouping.Sum(x => x.Quantity) * grouping.Sum(x => x.Product.ProductPrice), }).Sum(x => x.TotalOrder) // Add the sum of all the TotalOrders }; return colEnhancedOrder; }
By Bartg on
5/9/2015 2:49 AM
|
@Bartg - Please post your question on the official LightSwitch Forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
5/9/2015 11:17 PM
|
Thank you very much this is very useful, Just to share that when I tried your tutorial to create a WCF RIA Service for my own desktop client solution, everything worked perfectly in the debug mode but it didn't work in the release mode until I added the reference: System.Web.ApplicationServices.
By Ayman on
10/16/2015 3:58 AM
|
Hi Michael, Thank you very much for writing an excellent post. I have followed it step by step and everything works perfectly fine. Sorry for this stupid question, but what should I do if I wanted to add second WCF RIA "virtual entity" to the existing Lightswitch project? Do I need to follow all steps from the beginning, i.e. add new WCF RIA project for each "virtual entity" I want to add?
Thanks in advance!
Kind regards, Robert
By hmmmmm83 on
2/3/2016 9:57 AM
|
@Hmmmmm83 - I have no examples of adding a second WCF RIA project, sorry.
By Michael Washington on
2/3/2016 9:58 AM
|
Thank you very much for quick response. I've tried adding new class to the WCF RIA project for each new "virtual entity". That seems to work fine. Thanks once more and sorry for dumb question.
Regards, Robert
By hmmmmm83 on
2/4/2016 9:07 AM
|
Hi Michael, I'm following step by step your indications, except for the "System.Runtime.Serialization", added in the references because the compiler notified "The type or namespace name 'DataMemberAttributeAttribute' could not be found (are you missing a using directive or an assembly reference?)". Now I'm trying to solve another issue: "The type or namespace name 'ApplicationData' could not be found (are you missing a using directive or an assembly reference?)". I searched without result: any idea?
Thanks
By 2TEDP on
6/22/2016 3:29 AM
|
@2TEDP - You will want to download the completed code from the Download page on this site and compare it to your own. If you need further help please post your question on the official LightSwitch Forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
6/22/2016 3:30 AM
|
I called my datasource in a different way: "JobsData" vs "ApplicationData". Solved: thanks a lot!
By 2TEDP on
6/22/2016 4:53 AM
|
I follow this tutorial but i have error(request failed with status code 500 and status text internal server)how can i fix it?
By Mahoda on
6/23/2016 5:23 PM
|
@Mahoda - You will want to download the completed code from the Download page on this site and compare it to your own.
By Michael Washington on
6/23/2016 5:24 PM
|
i download the completed code and it's look like mine and problem still,do you think it's problem with server? please can you help me
By Mahoda on
6/24/2016 4:39 AM
|
@Mahoda - If you need further help please post your question on the official LightSwitch Forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
6/24/2016 4:40 AM
|
did WCF RIA service don't work without file handler that will use the Server Application Context API
By Mahoda on
7/12/2016 8:40 AM
|
Hi Michael, I have referenced your articles, book and other resources, but the server project is still unable to find the WCF RIA service.
I know my configuration works because I downloaded your 'end to end example' and appended my code and objects to it. To clarify, my class is pulling from a edmx. So it works there, but I cannot replicate it in my own project.
I then tried a clean version of lightswitch, follow every step, but again am not able to see the service. Is there some difference in VS 2015 (the version I'm on) when creating the steps?
All references have been double, triple checked. I am not sure if there is something I may be missing. Thanks
By DarkKnoght on
11/17/2016 2:40 PM
|
@DarkKnoght - There is no difference in VS2015. Sorry I can't think of what is wrong :( Perhaps post to the LightSwitch forums: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=lightswitch
By Michael Washington on
11/17/2016 2:41 PM
|
FYI, ensure that the .net framework of the ria project matches that in the web.config of the server project (now permanent at 4.6). Otherwise, the ria service will remain invisible.
By alex on
5/18/2017 4:37 AM
|