URL WCF RestFul .net with spring - c#

I need to call my service with the standard url restful:
http://localhost/users : getall user
http://localhost/user/1 : get user with id 1
But the standard URLs in WCF looks like:
http://localhost/Userservice.svc/getallusers
I would like to change this, but since I use the Spring.net framework in my service WCF, I must create my Custom ServiceHostFactory MyServiceHostFactory
Spring is used in my project to do the injection dependencies and thus nothing new object
I try to add a route in global.asax
RouteTable.Routes.Add(new ServiceRoute("Users", new MyServiceHostFactory(), typeof(UserService)));
But when i call my service http://localhost/users
, I receive the error: ServiceHost only supports class service types
I don't understand the problem and is it possible to resolve this problem ?
Thanks for your help

Related

DI Singleton Service Instantiates Twice

I register a service as Singleton in the program.cs file like this.
builder.Services.AddSingleton<ITest, Test>();
and if I request an instance of it in program.cs
var testService = builder.Services.BuildServiceProvider()
.GetRequiredService<ITest>();
It creates a new object which is the first object, but when I request it through constructor injection in some other service it creates a new object again. Shouldn't it return the first object that it created while startup in Program.cs?
Note : This behavior is only if I request service in the program.cs other than that it returns the same object, even if I request it using IServiceProvider.GetRequiredService();
i have tested the same scenario in dot net 5 web api as well in which i register the service in ConfigureServices method of Startu.cs file
services.AddSingleton<ITest, Test>();
and request the service in Configure method like this
var test = app.ApplicationServices.GetRequiredService<ITest>();
and when i request it in constructor in some other service it will return the same object.
Why?
In your starup file, you don't have a service provider yet. You only have the Services property that allows you to define your services.
Since you want to instantiate one, you call builder.Services.BuildServiceProvider() which builds a service provider for you, that you then use to get a service. Inside that service provider, your service lives as singleton.
Then, you proceed in your application and the framework, being happy that you defined your services, then builds it's own service provider. Which you can access via app.ApplicationServices. That one, too, has a single instance of your class, since it's a singleton.
And from now on, since all your services and controllers use the service provider created by the framework, not the one you created manually in startup, all of them will get the same instance.

Creating dynamic JavaScript proxy for custom ApplicationService

I've read the ABP documentation.
Here is my solution architecture for my new project based on the ABP Framework.
First of all, I want to ask if there is anything wrong with this design?
I've registered all my app services to IocManager in my Holitera.ApplicationModule.
So now I can call my app services from MVC controllers. RegionAppService is my new AppService here.
Here is the registration:
And my RegionAppService class:
public class RegionAppService : AsyncCrudAppService<Region, RegionDto,int>, IRegionAppService
{
private readonly IRepository<Region> _regionRepository;
public RegionAppService(IRepository<Region> regionRepository) :
base(regionRepository)
{
CreatePermissionName = "CreateRegionPermission";
_regionRepository = regionRepository;
}
}
Now I want to create a CRUD Razor page like the Roles view in the default template. But I couldn't register my custom RegionAppService to the JavaScript proxy services.
Do I need a dynamic Web API module to do that? Is that necessary? If it is, then how are Role, User, Customer, Account services registered to the dynamic JS proxy? I couldn't find the configuration for that. As much as I know there is no configuration for dynamic Web API module in the default MVC template? So I don't have an API module yet.
I'm going to need a dynamic JavaScript module later, but not now. First, I just want to handle this.
And by the way, what is the difference between dynamic AJAX call methods and dynamic Web API module? Are they same or if not, how?
Thanks :)
anything wrong with this design?
Entity and DomainService go in Core project. Dto and AppService go in Application project.
You can read about NLayer Architecture.
It's how the other services are discovered, and the right approach.
Do i need dynamic web api module to do that? Is that neccessary?
No.
how are Role, User, Customer, Account services are registered to dynamic js proxy? I couldn't find the configuration for that. As much as i know there is no configuration for dynamic api module in default mvc template?
It's done in YourProjectNameWebCoreModule. You can create controllers for additional assemblies:
Configuration.Modules.AbpAspNetCore()
.CreateControllersForAppServices(
typeof(RegionAppService).GetAssembly()
);

Accept WCF request in WebAPI

I need to enable my webAPI REST service to accept a request in the format of:
www.someURL.com/OldService.svc
I am working on an existing application that used to use WCF. These methods do not have to return anything but a 200 response. We need the REST service to handle this call so we can retire the old WCF service, but systems will fail if we don't support this WCF request.
Has anybody done this before?
edit:
Is it possible to do this with just adding a new route?
You can add a WCF service (.svc) to a Web API project by simply adding a New Item and selecting Web, it will then show up in the list as WCF Service.
Maybe you could use the Route attribute(using System.Web.Http) for the old service? I've used this for route names like [Route("SomeRoute")] but I'm not 100% sure if the .svc extension will interfere with anything.
[Route("OldService.svc")]
[HttpPost]
public HttpResponseMessage NewData(Data SomeData)
{}

Custom ServiceHost with DI and InstanceContextMode.Percall

In my Managed Application, I currently have my WCF services running as:
SomeService service = new SomeService(container) //IUnityContainer
ServiceHost serviceHost = new ServiceHost(service, serviceAddress);
Whats the catch ? SomeService defined with:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single
This is not good anymore, I need to make it InstanceContextMode.PerCall.
When trying to .Open() If changing the InstanceContextMode to "PerCall" - it will throw:
System.InvalidOperationException: In order to use one of the ServiceHost constructors that takes a service instance, the InstanceContextMode of the service must be set to InstanceContextMode.Single. This can be configured via the ServiceBehaviorAttribute. Otherwise, please consider using the ServiceHost constructors that take a Type argument
Is this the solution to my problem ? How do I pass values to the constructor on my wcf service?
My Main concern:
I run different types of services inside this managed application, It seems that this solution is good only if i run one type of service.
When more than one service instance will be needed (PerCall or PerSession) then passing a single service instance into the ServiceHost isn’t enough... which is the exception.
Controlling instance creation is managed by the IInstanceProvider.
Is this the solution to my problem ? How do I pass values to the constructor on my wcf service?
This only answers half your question. You are using Unity. The management of creating the container needs to be part of the implementation. The most common solution is to use Unity.WCF which is also available as a NuGet package.
Note that Unity.WCF doesn’t support object lifetimes based WCF OperationContexts. There are multiple (more complicated) implementations like this that do.

Can I generate a service reference automatically for a REST WCF service?

The ONLY argument I can see for SOAP WCF over REST (json) wcf is the fact that once my service is created I can add a a reference in visual studio and I get a load of strongly typed classes ready for me and a client class that I can call all my webmethod through. It even sets up the web.config as far as I remember.
However when I expose a REST (json) service I still get a WSDL. So Im wondering is there still a way to build my references automatically?
Not using WCF tools. Unlike with SOAP (which has an established protocol for describing services - WSDL), REST doesn't. WADL is one such protocol, but it isn't too widespread and WCF does not support it. You still get a WSDL, because WCF will describe everything it can from the service. However, the WSDL won't have a <wsdl:port> element, which would describe the REST endpoint, which is why you get the WSDL, but cannot generate a reference to it.
The post at http://blogs.msdn.com/b/carlosfigueira/archive/2012/03/26/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work.aspx has a lot more info on this issue.
Very old question, newer answer.
today using openapi (swagger) I can achieve this by using swagger inspector doing samples i can document my rest services as well as create a spec yml/json file allowing for validations and acceptance criteria as well as automated clients for java,python,c#,ruby,javascript and others I'm sure
I would like top elaborate:
Although it is true you cannot get a WSDL add service reference with a JSON REST WCF service, what I do is create two met data hooks:
is the operations returning JSON
is a single XML op returning a class wrapper which includes all the service classes I allow, I call it Discover:
i.e.
public class Discover
{
public Manager Manager {get;}
public Employee Emp {get;}
....
}
[OperationContract]
public Discover DiscoverDTOs()
You can, indirectly. While the client generated by Visual Studio won't work, that client implements an interface, also generated, that you can use like this:
WebChannelFactory<IService> factory = new WebChannelFactory<IService>(new Uri(endpointAddress));
IService proxy = factory.CreateChannel();
int result = proxy.Operation(1, 2, 3);
WebChannelFactory has another overload which accepts a WebHttpBinding, you can configure based on the service configuration, or you can make this configuration manually in your app.config file.

Categories