first of all, I am well aware that there are two other questions about the same topic I'm about to inquire, and I must sadly say that they haven't worked for me.
As it stands I am trying to create a simple WCF service which is to be consumed by a desktop application. I created it off the WCF Service Application that is offered through the New -> Project in Visual Studio 2013. That project has a template which has these two files: An interface called IService1.cs and the Service which is called Service1.svc.
Right out of the box this whole package works, but when I decide to rename those files with "IReservationService" and "ReservationService" respectively and put in my own code (which I can't find any mistakes in, not yet), when I decide to see if it's all working I get this bad boy:
I regret to tell you that some parts of it are in Spanish, if you can't interpret them just yell at me and I will translate all of it for you.
This is the code involved:
IReservationService.cs
namespace WebService
{
[ServiceContract]
public interface IReservationService
{
[OperationContract]
List<Business.Reservation> RequestReservationRetrieval();
}
}
ReservationService.svc
namespace WebService
{
public class ReservationService : IReservationService, IDisposable
{
ReservationRepository repo;
public List<Business.Reservation> RequestReservationRetrieval()
{
//code goes here, skipped it so it doesn't clutter
}
private void ChangeSyncDate(DateTime date)
{
//code goes here, skipped it so it doesn't clutter
}
public void Dispose()
{
repo.Dispose();
}
}
}
As soon as I change the code in those two classes (IService1.cs and Service1.svc) which I assumed would have been refactored for mine to fit somewhat perfectly, that doesn't seem to be the case, and I get the error that is displayed in the image.
Any ideas on how to fix this?
This was pretty much a refactoring nightmare, because the issue was somewhat hidden.
There's two files in ReservationService, or rather the Service that's to be consumed, in my case:
ReservationService.svc and ReservationService.svc.cs
ReservationService.svc contains just this tiny line:
<%# ServiceHost Language="C#" Debug="true" Service="WebService.Service1" CodeBehind="ReservationService.svc.cs" %>
And oh, surprise, there it is. Service="WebService.Service1" is exactly what was causing all these issues.
In order to get to ReservationService.svc, or whatever it's called on your Project you need to Right Click the .svc and click "View Markup".
This is an issue no one should ever have to deal with, I swear.
Related
i created a Backend-Service (Windows-Service) wich provide Data to my Network-Clients over WCF, handles the connection to the Database and some specific tasks.
Everytime when changed something in my DTO-Objects the changes were made correctly on the client side when i update the service-reference.
But now the Update-Process does not create the correct proxy for the WCF-Service.
When i add some DTO-Objects the information abount the new DTO's updated correctly to the client but when i add some Propertys to existing DTO-Objects the Update-Servicereference Function does not include the new Propertys.
I already tried to create a completely new application and add the Service-Reference within this Test-Scenario but also in this case the new property does not appear in the proxy-class.
First time i noticed this behaviour was as i try to create a new property in my "File.cs" DTO. I thinked that the name "File" (the class definition has the same name) creating this error. So i decided to rename the "File" DTO-Class to AttachmentFile and the new propertys are created correctly on the proxy.
But now i try to add Propertys to the Classes DeviceStayType and ProcessStateType and theres the same behaviour. No Error is displayed and the Git says that the proxy changed when i press Update Service-References but the propertys are still missing on the client side.
Here are some snippets:
The old DeviceStayType-Class:
[DataContract]
public class DeviceStayType : TypesBase
{
}
The new DeviceStayType-Class:
[DataContract]
public class DeviceStayType : TypesBase
{
[DataMember(Name = "TableName")]
[MaxLength(200)]
public string TableName { get; set; }
}
The generated Proxy for the DeviceStayType
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="DeviceStayType", Namespace="http://schemas.datacontract.org/2004/07/ProductLifecycle.Backend.Models.DTO")]
[System.SerializableAttribute()]
public partial class DeviceStayType : ProductLifecycle.Frontend.CommunicationService.TypesBase {
}
Hope that anyone can help :(
Thanks,
Michael
OK. After some tests i decided to outsource the Models in an DLL which both projects (backend and frontend) have a reference for.
It seems that this was the only way to fix this issue. I think this behaviour is produced when theree are two webservices; one in the frontend as Callback (Streamed because theres a much better performance) and one in the backend as Managing-Service. Both services used the same classes and i thought this could be a possible reason because the Backend-Service sends the Models to the Frontend-Client and the Frontend-Service sends the Models to the Backend-Client as well.
Now with the outsourced classes and much lighter conversions the scenario works in my case.
I have an application which contains multiple hubs all on unique paths, so when calling the default :
routes.MapHubs("path", new HubConfiguration(...));
It blows up saying that the signalr.hubs is already defined (as mentioned here MapHubs not needed in SignalR 1.01?).
Now I can understand that it should only be called once, but then you will only get 1 path, so is there any way to handle a path per hub scenario? like how with MVC you specify the controller and action? so something like:
routes.MapHub<SomeHub>("path", new HubConfiguration(...));
== Edit for more info ==
It is mentioned often that you should never need to call this map hubs more than once, and in most scenarios I can agree, however I would not say that this is going to be the case for all applications.
In this scenario it is a website which at runtime loads any plugins which are available, each plugin is exposed the dependency injection framework to include its dependencies and the route table to include its routes. The hubs may have nothing to do with each other (other than the fact that they are both hub objects). So the hubs are not all known up front and are only known after the plugins are loaded, and yes I could wait until after this and try binding the hubs there, however then how do I have custom routes for each one then?
This seems to be a case of SignalR trying to abstract a little too much, as I dont see it being a bad idea to have custom routes rather than the default "/signalr", and as the routes all have different responsibilities it seems bad to have one entry route for them all.
So anyway I think the question still stands, as I dont see this as being a bad use case or bad design it just seems to be that I want to be able to have a route with a hub applied to it, much like in mvc you apply a controller and action to a route.
You shouldn't need more than the signalr.hubs route. If you point your browser to that route, you will see it automatically finds all public types assignable to IHub and creates a JavaScript proxy for them. You can interact with different hubs by name from JavaScript, i.e. if you have the following Hub:
public class GameHub : Hub
You can connect to that specific hub by doing:
var gameHubProxy = $.connection.gameHub;
You can also explicitly specify a name for your hub by adding the HubNameAttribute to the class:
[HubName("AwesomeHub")]
public class GameHub : Hub
You can then retrieve the specific proxy by doing
var awesomeHubProxy = $.connection.awesomeHub;
UPDATE:
I'm not sure whether SignalR will be able to run on multiple paths in the same application. It could potentially mess things up and the default assembly locator won't be able to pick up hubs loaded at runtime anyway.
However, there is a solution where you can implement your own IAssemblyLocator that will pick up hubs from your plugin assemblies:
public class PluginAssemblyLocator : DefaultAssemblyLocator
{
private readonly IEnumerable<Assembly> _pluginAssemblies;
public PluginAssemblyLocator(IEnumerable<Assembly> pluginAssemblies)
{
_pluginAssemblies = pluginAssemblies;
}
public override IList<Assembly> GetAssemblies()
{
return base.GetAssemblies().Union(_pluginAssemblies).ToList();
}
}
After you've loaded your plugins, you should call MapHubs and register an override of SignalRs IAssemblyLocator service:
protected void Application_Start(object sender, EventArgs e)
{
// Load plugins and let them specify their own routes (but not for hubs).
var pluginAssemblies = LoadPlugins(RouteTable.Routes);
RouteTable.Routes.MapHubs();
GlobalHost.DependencyResolver.Register(typeof(IAssemblyLocator), () => new PluginAssemblyLocator(pluginAssemblies));
}
NOTE: Register the IAssemblyLocator AFTER you've called MapHubs because it will also override it.
Now, there are issues with this approach. If you're using the static JavaScript proxy, it won't be re-generated every time it's accessed. This means that if your /signalr/hubs proxy is accessed before all plugins/hubs has been loaded, they won't be picked up. You can get around this by either making sure that all hubs are loaded by the time you map the route or by not using the static proxy at all.
This solution still requires you to get a reference to your plugin assemblies, I hope that's feasible...
like the title says, I want to keep my logic in a separate project to the service contract(s) so this can stay separate and hidden. I've seen it said that this can be done, but I can't find any examples as to how.
I moved all the necessary code out to a different project, but when I test it only the types are visible to the client, not the methods.
All the methods are marked as [OperationContract] in the interface.
I'm guessing there must be a way of specifically connecting the implementation logic to the contract other than just Class : IInterface, otherwise, what would happen if there were 2 similar classes, e.g.: Class1 : IInterface and Class2 : IInterface? How would WCF know which class to use?
I've done it this way (sorry for bad names, that's just for concept):
1) Created separate project for implementation
2) Created separate project for service contract (to avoid circular references)
3) Added service contract project as reference to implementation project
4) Added contract and implementation project to host project
5) Updated Service.svc with full type name
Service.svc body:
<%# ServiceHost Language="C#" Debug="true" Service="Implementation.ServiceImplementation" %>
How would WCF know which class to use?
Because you tell it, in the various configuration files.
I can heartily recommend WCF the Manual Way…the Right Way for motivation and a complete walkthrough for what you are trying to do - what I have here is just the pertinent points of such an implementation.
You have three assemblies: Service, Client, ServiceContracts (interfaces only). Service and Client both reference ServiceContracts. Service contains classes implementing the interfaces. Client has proxy classes:
using System.ServiceModel;
using ServiceContracts;
public class ExampleServiceProxy : ClientBase<IExampleService>, IExampleService
{
public string ExampleMethod()
{
return Channel.ExampleMethod();
}
}
The client's config file contains an entry pointing at the service's svc file; the service's svc file looks like this:
<%# ServiceHost Language="C#" Debug="true" Service="Service.ExampleService"
CodeBehind="ExampleService.svc.cs" %>
And the service .svc.cs file looks like:
using ServiceContracts;
public class ExampleService : IExampleService
{
public string ExampleMethod()
{
return string.Empty;
}
}
That's it!
I like to interact with some of my wordpress blogs through xmlrpc interface. During my research I found xml-rpc.net-Library (www.xml-rpc.net) which works really fine except for one thing.
I build my xmlrpc.net instance like this:
[XmlRpcUrlAttribute("http://my-example-blog.com/xmlrpc.php")]
public class WP : XmlRpcClientProtocol
{
public WP()
{
}
...
}
But I want to set the xmlrpc-Url dynamically during runtime. So I like to add more blogs during the UI at runtime and don't want to implement each blog "hard-coded".
Does anybody had a same problem and can help me? Is there another possibility within xmlrpc.net-library or do you know another good xmlrpc library?
Greets,
Raffi
You can specify the URL at runtime:
proxy.Url = "http://my-example-blog.com/xmlrpc.php";
I'm trying to inject specific class into my WCF service but it doesn't work and I can't understand why. I'm VERY NEW to MEF and patterns, just trying to make it work. Watched series of videos to understand what it is about but bootstraping won't work in my case since it is not Silverlight
http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1-introduction
Here is my Web application's Global.asax code. This is non MVC, just regular ASP.NET app:
private void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
var catalog = new WebScopedCatalog(new DirectoryCatalog(Server.MapPath("~\\bin")));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
FIRST, I'm not sure I even bootrstrap it properly.. SECOND, I'm using http://www.timjroberts.com/2011/02/web-scoped-mef-parts/ as a guidance for web-scoped parts. I need that because some injected objects supposed to live during request only.
Now, I have following class:
[Export(typeof(ITest))]
[WebPartCreationPolicy(WebCreationPolicy.Session)]
public class Test : ITest
{
public string TestMe()
{
return "Hello!";
}
}
And my service looks like:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MobileService
{
[Import]
public ITest MyTestClass { get; set; }
public MobileService()
{
int i = 10;
}
When breakpoint hits at i=10 - I have NULL inside MyTestClass. Clearly, MEF does not initialize this class for me. Am I missing something?
EDIT:
When I examine catalog - I see my class Exported but I don't see it imported anywhere...
EDIT 2:
Daniel, Thank you. It makes sense. It still feels litle like a magic for me at this point. Yes, WCF creates this service. Than I have MembershipProvider and various Utility classes that ALL need the same import. And I'm not creating neither of those classes so I can't have Mef creating them. (Service created by WCF, MembershipProvider created by who-knows-what, Utility classes have static methods..) I wanted to use Mef instead of storing my stuff in HttpContext.Current. My container object doesn't have SatisfyImports. It has SatisfyImportsOnce. What if I do it in many different constructors? Will Mef share same singleton or it will be creating new instance every time?
At this point I wonder if I should even use Mef in this particular scenario..
MEF won't satisfy imports for objects it doesn't create. What is it that creates MobileService? If it's not MEF, then the import won't be satisfied by default. Even if it is MEF, the import wouldn't be satisfied in the constructor- you can't set properties on an object you create until it is done being created (ie the constructor has finished).
You can call container.SatisfyImportsOnce(mobileService) to satisfy the imports of a part. You should try to avoid doing this everywhere you need a MEF import. If you can, you should export a part and import it from another part so that MEF handles the creation for you. However, it looks like this part may be created by WCF so you can't have MEF create it, and in that case it would be OK to use SatisfyImportsOnce.
Response to EDIT2: If you use the same container each time, MEF will by default only create one instance of the part with the export. You can set the CreationPolicy to NonShared (in either the export or import attribute) to change this.
As for whether it makes sense to use MEF the way you are trying to, I don't know enough about writing web services to give you any advice on that.
The web-scoped part creation policy that I wrote won't help with WCF services.
I've posted a new blog post that documents an approach to composeable WCF services:
http://www.timjroberts.com/2011/08/wcf-services-with-mef/
Basically, you need to implement a custom Instance Provider that is MEF-aware and can compose the WCF service object when it is created.
I wrote about how to compose your WCF in a generic way that its configuration based here:
Unit Testing, WCF and MEF
I actually built my solution on the code samples Tim Robert's provided in his post. only that I took it a bit further and instead of using code in the global asax i moved the configuration into the web.config so its easier to maintain.