How to access WCF RIA service from Windows Service? - c#

I have a functioning Silverlight 4 application (VS2010, SL4, WCF RIA, hosted on my dev box using Cassini, 64-bit Windows 7). Inside the ClientBin directory I have an .svc file that describes my service:
<% #ServiceHost Service="MyApp.Services.MyService
Factory="System.ServiceModel.DomainServices.Hosting.DomainServiceHostFactory" %>
When I browse to http://localhost:52878/ClientBin/MyApp-Services-MyService.svc I see the following:
You have created a service. To test
this service, you will need to create
a client and use it to call the
service. You can do this using the
svcutil.exe tool from the command line
with the following syntax:
svcutil.exe http://localhost:52878/ClientBin/MyApp-Services-MyService.svc?wsdl
I want to access that service from a Windows Service application. My understanding is that I need to enable SOAP end-points in order to make this happen. So, I add the following to my web.config file:
<domainServices>
<endpoints>
<add name="soap"
type="System.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory,
System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
Firstly, Intellisense complains about the presence of the tag, saying:
The element system.ServiceModel has
invalid child element domainServices.
Secondly, the aforementioned Silverlight application stops working, presumably because this change breaks the underlying web services.
Thirdly, it appears that the System.ServiceModel.DomainServices.Hosting assembly doesn't actually contain the SoapXmlEndpointFactory type; if I try to browse to the service after adding the above to web.config I see:
Could not load type
'System.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory'
from assembly
'System.ServiceModel.DomainServices.Hosting,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'.
If I inspect the assembly using Reflector, I see that it contains the DomainServiceEndpointFactory and PoxBinaryEndpointFactory types, but no SoapXmlEndpointFactory.
Could someone please let me know how I should be doing this? I can't believe that it should be this hard to simply consume a WCF RIA service in something other than a Silverlight application!

Instead of ...
System.ServiceModel.DomainServices.Hosting
use the assembly ...
Microsoft.ServiceModel.DomainServices.Hosting
from the WCF RIA Services toolkit. It contains the type SoapXmlEndpointFactory.
The default location is ... %Program Files%\Microsoft SDKs\RIA Services\v1.0\Toolkit\Libraries\Server

Have you tried just executing
svcutil.exe
http://localhost:52878/ClientBin/MyApp-Services-MyService.svc?wsdl
Alternatively, have you installed the RIA Services toolkit?
http://www.microsoft.com/downloads/details.aspx?FamilyID=7b43bab5-a8ff-40ed-9c84-11abb9cda559&displaylang=en
It's required for SOAP and JSON endpoints

The SoapXmlEndpointFactory class is part of the
Microsoft.ServiceModel.DomainServices.Hosting
assembly, which is included in the Silverlight Toolkit.
See here

<sectionGroup name="system.serviceModel">
<section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication" requirePermission="false" />
</sectionGroup>
Declare this in the ConfigSections. It's important to include the sectionGroup correctly

Related

Why do I have to specify the assembly in my app.config but not for my web.config when using custom sections

I have custom sections in my project. The following line works for my Web API project from the web.config:
...
<sectionGroup name="Project.Models">
<section name="product" type="Project.Models.Configuration.ProductSettings" />
</sectionGroup>
</configSections>
<Project.Models>
<product id="1" />
</Project.Models>
When I run my unit tests, I get the following error:
System.Configuration.ConfigurationErrorsException : An error occurred creating the configuration section handler for Project.Models/product: Could not load type 'Project.Models.Configuration.ProductSettings' from assembly 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Could not load type 'Project.Models.Configuration.ProductSettings' from assembly 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Why do I have to specify the assembly name when referencing this from my unit tests app.config? This resolved the issue, but not sure why it's needed.
<section name="product" type="Project.Models.Configuration.ProductSettings, Project.Models" />
It depends on the host that executes your code.
Without extra plumbing you'll find that in the inner workings of the Configuration namespace the type attribute is fed into the static method Type.GetType(string typeName).
For the typeName parameter you'll find in its description:
If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
The key part is currently executing assembly. That seems to be never the case for normal appdomains, and thus for the application that runs your unit-test (which I assume is VS).
The ASP.NET web hosting on the other hand provides an internal HttpConfigurationSystem class that re-implements the calls to GetSection. It is a little hard to follow but it looks like an internal class BuildManager loads all assemblies and iterate over all types, to find one that matches.
This explains the difference in behavior. It is adviced to always specifiy the assemblyname. In the asp.net scenario, if the assemblyname is present in the type parameter it short-circuits to the Type.GetType call which prevents the loading and inspection of all dll's in the bin folder of your webapp.

Configuration binding extension 'system.serviceModel/bindings/pollingDuplexHttpBinding' could not be found

Problem
I'm getting the following error whenever I try to load out .svc url (Local)
Configuration binding extension 'system.serviceModel/bindings/pollingDuplexHttpBinding' could not be found. Verify that this binding extension is properly registered in system.serviceModel/extensions/bindingExtensions and that it is spelled correctly.
Enviroment
The project was build by a ex colleague of mine, who I can't reach. It's a webservice build in .Net Framework 4
I get this error when I attempt to gain access to our .svc file
In the web.config I have this setting:
<system.serviceModel>
<extensions>
<bindingExtensions>
<add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, version=3.0.0.0, Culture=neutral" />
</bindingExtensions>
</extensions>
which is later used as <endpoint address="" binding="pollingDuplexHttpBinding" contract="<ourcompany>.DataService.IMessageService"/>
Attempts
In regards to other posts about this error I have already tried:
Installing Dot net 3.5 SP1
Removing the line from web.config
Reinstalled IIS
I have no idea what to do, or how to fix this.
The strange part is that it does work on our live server, but not on my own computer for testing purposes!
Refer - Unrecognized element 'pollingDuplexHttpBinding' in service reference configuration
<!-- Register the binding extension from the SDK. -->
<extensions>
<bindingExtensions>
<add name=
"pollingDuplexHttpBinding"
type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement,System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
The difference here is, Version=4.0.0.0 and PublicKeyToken=31bf3856ad364e35.
You can get more information on the Section "To use PollingDuplexHttpBinding" section of - How to: Build a Duplex Service for a Silverlight Client.
Good luck. :)

Adding Routing to eliminate .SVC in REST service isn't working

I am building a dummy WCF REST service just for purposes of learning how it works (preparing for real service build). I have the REST service working and responding with both JSON and POX formatting. However, I cannot get the routing solution to work in order to eliminate the ".svc" file. I am using VS 2010, WCF 4.0 and IIS 7.5 on Win Server 2008 R2.
Right now the URL works as: "/api/rest/rest.svc/json/myMethod" but I want to just have "/api/rest/json/myMethod". I have found numerous articles here on SO and elsewhere which claims to remove the ".svc" file. I believe I have it setup as instructed, but the project will not build because of an error in the Global.asax file.
It says to add the following to the Application_Start function:
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(),
typeof(RestService)));
I also added the following to the web.config:
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=31BF3856AD364E35" />
</modules>
<handlers>
<add name="UrlRoutingHandler"
preCondition="integratedMode"
verb="*" path="UrlRouting.axd"
type="System.Web.HttpForbiddenHandler,
System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
I also added the aspNetCompatibility lines to the web.config and above the class in the svc.cs file.
Th issue is that I can't even get the project to build. When I add the RouteTable.Routes.Add line to the global.asax and build it, I get the following errors:
The type
'System.ServiceModel.Activation.ServiceHostFactory'
is defined in an assembly that is not
referenced. You must add a reference
to assembly
'System.ServiceModel.Activation,
Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'.
The type or namespace name
'ServiceRoute' could not be found (are
you missing a using directive or an
assembly reference?)
Any ideas why this is failing?
make sure that "System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" is referenced in the project, if it is make sure to add this to the web.config file as well. – Joakim Mar 25 at 19:03

Consuming RIA services without a silverlight project

We have a silverlight project that uses RIA services. There is some code that I want to share between that project and a web service. I have to leave the code where it is now, i.e. I cannot share the code.
What I thought would be good is for the web service to call the RIA service. It will be sitting on the same server.
I went to my web service project, and added a service reference to the ria service. I clicked advanced and ticked the option for it to 'generate asynchronous operations'.
I thought it would be all good to go, but I got some warnings. The client code that it generated was missing any actual code relating to the asynchronous calls, and the app.config is also empty. Here are the warnings,
Warning 2 Custom tool warning: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:portType[#name='CarServiceSoap']
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:binding[#name='BasicHttpBinding_CarServiceSoap'] C:\Develop\DotNet\Trunk\Applications\WcfServices\CarTransmitter\CarTransmitter.Core\Service References\CarService\Reference.svcmap 1 1 CarTransmitter.Core
Warning 3 Custom tool warning: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:binding[#name='BasicHttpBinding_CarServiceSoap']
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:service[#name='CarService']/wsdl:port[#name='BasicHttpBinding_CarServiceSoap'] C:\Develop\DotNet\Trunk\Applications\WcfServices\CarTransmitter\CarTransmitter.Core\Service References\CarService\Reference.svcmap 1 1 CarTransmitter.Core
Warning 1 Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'CarData.Organisation, CarData, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' with data contract name 'Organisation' in namespace 'http://schemas.datacontract.org/2004/07/CarData' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types.
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:portType[#name='CarServiceSoap'] C:\Develop\DotNet\Trunk\Applications\WcfServices\CarTransmitter\CarTransmitter.Core\Service References\CarService\Reference.svcmap 1 1 CarTransmitter.Core
Use the RIA services project option to create your service library. That creates 2 projects that are bound together (for code gen of the proxy objects). Both are effectively just libs (1 Silverlight and 1 .Net)
Link any RIA services client library to you Silverlight app. Then link the .web RIA project to your hosting web app (for the standard RIA use). You can also add the .web library to your Wcf service as a .Net lib (not consume it as a service).
If you did not create your main Silverlight project as a RIA services project you will need to move the settings across from the app.config file to your web.config file. If you already have the service support settings you only need to copy the db connection string across. The db connection string only should be needed for you Wcf project.
You should then be able to either use the server-side RIA calls (don't forget to add your own submitchanges calls as RIA does that behind the scenes once per batch of updates), or just use the data layer (EF etc) directly.
Not finished completely, got quite a bit further along. The problems I am having now warrant a new question.
The solution to the above problem is to untick the option 'reuse types in referenced assemblies'. When you add service reference, you click the advanced button and you get the option 'reuse types in referenced assemblies'.
This is because I am sharing some code between the two projects I am using, and it was trying to 'reuse' objects I had on my side in the shared code. Instead I just wanted it to create proxy objects for me and not reuse those objects.
Yes. It is possible to do.
Create a library project
Add LINQ to Entity model
Add public class DomainService1 : LinqToEntitiesDomainService
Check if your web.config looks like this one
[?xml version="1.0"?]
[configuration]
[configSections]
[sectionGroup name="system.serviceModel"]
[section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication" requirePermission="false" /]
[/sectionGroup]
[/configSections]
[system.webServer]
[validation validateIntegratedModeConfiguration="false" /]
[modules runAllManagedModulesForAllRequests="true"]
[add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /]
[/modules]
[/system.webServer]
[system.serviceModel]
[domainServices]
[endpoints]
[add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /]
[add name="soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /]
[add name="JSON" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /]
[/endpoints]
[/domainServices]
[serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /]
[/system.serviceModel]
[connectionStrings]
[add name="ASPNETDBEntities1" connectionString="metadata=res:///Model1.csdl|res:///Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=ASPNETDB;persist security info=True;user id=sa;password=yourpassword;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /][/connectionStrings]
[system.web]
[compilation debug="true"][assemblies][add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /][/assemblies][/compilation]
[/system.web]
[/configuration]
Do WEB Publishing locally and test service link.
Enjoy!

NService bus and the GAC

I have recently tried to migrate the NServiceBus libraries to the GAC as they are pretty big and are required in nearly all of my software. I am using the newest .NET 4.0 Build (2.0.0.1219) and have used GACUTIL to copy NServiceBus & NServiceBus.Core into the new GAC and log4net into the old 2.0 GAC. I have managed to get log4net working by wiring in the version and PublicKeyToken but I cannot get the NServiceBus.Core working. Every time I start a piece of software I get the following error:
"Type NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer. Check that it appears in the list of configured assemblies/types to scan."
When I copy the DLL NServiceBus.Core to the local folder it works fine.
my config looks like this:
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core, Version=2.0.0.1219, Culture=neutral, PublicKeyToken=9fc386479f8a226c" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core, Version=2.0.0.1219, Culture=neutral, PublicKeyToken=9fc386479f8a226c" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, NServiceBus.Core, Version=2.0.0.1219, Culture=neutral, PublicKeyToken=9fc386479f8a226c"/>
</sectionGroup>
So i'm wondering has anyone else got NServiceBus successfully working with the GAC?
Cheers
It is an issue with NServiceBus stripping strong names. Use the <runtime> element in web.config:
<runtime>
<qualifyAssembly partialName="MessagesDll" fullName="MessagesDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4d476a51357cea5c" />
NServiceBus scans the assemblies in a directory (the run directory for an application, the website's compiled directory for a web application) in order to load all the message handlers, and that means it needs to scan itself as well for all the types it needs for dependency injection.
I'm not sure that this model supports assemblies living in the GAC by default, although if you're configuring NServiceBus yourself, you can specify the assemblies to load yourself through the NServiceBus.Configure.With(params Assembly[] assemblies) overload, just make sure to include all the NServiceBus assemblies and Log4Net at the very least.
However, I would contend that GAC-ing the NSB assemblies might not be the best idea. Each endpoint having its own copy of the assembly reinforces the autonomy of the endpoints, and will make it much easier if you ever need to upgrade to a new version of NServiceBus, since you would be able to test each endpoint individually and not just put a new assembly in the GAC, add a binding redirect, and hope everything continues to run fine.

Categories