Files to look at:
- Customer.cs (VB: Customer.vb)
- Program.cs (VB: Program.vb)
- Service1.svc.cs (VB: Service1.svc.vb)
- Web.config (VB: Web.config)
Scenario
In this example we will implement a distributed object layer service (IObjectLayer/ISerializableObjectLayer) working via WCF. A distributed services layer relies on lower layers, but hides the details of these layers from upper layers that contain the application and business logic layers. This arrangement allows the application developer to work at a higher level of abstraction layers.
Steps to implement:
1. Create a new Class Library project and add a Customer class via the DevExpress v1X.X ORM Persistent Object item template. You can see the source code of this class in the Customer. xx file.
2. Create a new WCF Service Application project and remove files with auto-generated interfaces for the service.
3. Add reference to the newly created class library.
4. Modify the Service class as shown in the Service. xx file to create a data provider and data layer.
5. Modify binding properties as shown in the example's web.config file. At this stage, the service part is ready to work and we need to implement a client to consume data from our data store service (for demonstration purposes, we will create a Console Application).
6. Add a Console Application into solution and add reference to the newly created class library.
7. Modify the Main method in the same manner as the Program. xx file to connect to our service using the web.config configuration.
8. The final step is to add the App.config file to our client application and modify it as shown in the example's App.config file.
If you run the client application, you will see the following output:
Important notes:
Please note that the port number in the connection string may be different. You can check it in the properties of the service project in the Solution Explorer:
Troubleshooting
- If WCF throws the "Entity is too large" error, you can apply a standard solution from StackOverFlow: http://stackoverflow.com/questions/10122957/
- If WCF throws the "The maximum string content length quota (8192) has been exceeded while reading XML data. " error, you can extend bindings in the following manner:
XML<bindings>
<basicHttpBinding>
<binding name="ServicesBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed" >
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
See The maximum string content length quota (8192) has been exceeded while reading XML data
See also:
Transferring Data via WCF Services
How to use XPO with a Web ServiceHow to connect to a remote data service instead of using a direct database connection
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using DevExpress.Xpo;
namespace ClassLibrary1 {
public class Customer : XPObject {
public Customer(Session session) : base(session) { }
string _CompanyName;
public string CompanyName {
get { return _CompanyName; }
set { SetPropertyValue("CompanyName", ref _CompanyName, value); }
}
string _CompanyAddress;
public string CompanyAddress {
get { return _CompanyAddress; }
set { SetPropertyValue("CompanyAddress", ref _CompanyAddress, value); }
}
string _ContactName;
public string ContactName {
get { return _ContactName; }
set { SetPropertyValue("ContactName", ref _ContactName, value); }
}
string _Country;
public string Country {
get { return _Country; }
set { SetPropertyValue("Country", ref _Country, value); }
}
string _Phone;
public string Phone {
get { return _Phone; }
set { SetPropertyValue("Phone", ref _Phone, value); }
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using ClassLibrary1;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
namespace ConsoleApplication1 {
class Program {
static IObjectLayer ObjectLayer;
static void Main() {
ISerializableObjectLayer serializableObjectLayer =
new SerializableObjectLayerServiceClient("BasicHttpBinding_ObjectLayer");
serializableObjectLayer.CanLoadCollectionObjects.ToString();
XpoDefault.DataLayer = null;
XpoDefault.Session = null;
ObjectLayer = new SerializableObjectLayerClient(serializableObjectLayer);
using(UnitOfWork uow = new UnitOfWork(ObjectLayer)) {
using(XPCollection<Customer> customers = new XPCollection<Customer>(uow)) {
foreach(Customer customer in customers) {
Console.WriteLine("Company Name = {0}; ContactName = {1}",
customer.CompanyName, customer.ContactName);
}
}
}
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.Xpo.DB;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
using ClassLibrary1;
namespace WcfService1 {
public class Service1 : SerializableObjectLayerService {
public Service1()
: base(new ObjectServiceProxy()) {
}
static Service1() {
string connectionString = MSSqlConnectionProvider.GetConnectionString("localhost", "ServiceDB");
IDataStore dataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.DatabaseAndSchema);
XPDictionary dictionary = new ReflectionDictionary();
dictionary.CollectClassInfos(typeof(Customer).Assembly);
XpoDefault.DataLayer = new ThreadSafeDataLayer(dictionary, dataStore);
XpoDefault.Session = null;
}
public Service1(ISerializableObjectLayer serializableObjectLayer)
: base(serializableObjectLayer) {
}
}
public class ObjectServiceProxy : SerializableObjectLayerProxyBase {
protected override SerializableObjectLayer GetObjectLayer() {
return new SerializableObjectLayer(new UnitOfWork(), true);
}
}
}
Code<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<endpoint address="" binding="basicHttpBinding" contract="DevExpress.Xpo.DB.ISerializableObjectLayerService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>