Read Global Application property from WCF Service - c#

I'm using in my Global.asax class the object Application to store data.
Application.Set("data", "test");
Now, in my WCF Service, I want to be abble to read this property. How can I do that?
Application["data"];
In debug, I can see my global.asax is called (Begin_Request), but in my webservice's method, how can I access to this Application?

var yourData=HttpContext.Current.Application["data"];
bear in mind anyway thay if you will deploy the Service on a Server Farm you could have issues as the Application is inProc and each server will have its own Application variable

in order to get the HttpContext.Current working with wcf you gotta turn on compatibility:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
then you can get access as Massimiliano Peluso suggests:
// in the wcf service
var yourData=HttpContext.Current.Application["data"];

Related

How to control number of inbound connections on webHttpBinding service?

I have a standard Web Service that processes JSON requests via an webHttpBinding. I am trying to find out whether there is a limit on how many concurrent connections it can handle and how to control it. Can't find anything. I am missing something simple or some setting?
Here is a skeleton of my service:
[ServiceContract]
public interface IMyService {...}
[ServiceErrorBehavior(typeof(ErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService : IMyService {...}
I have some suggestion for this, but this will not be direct config related change. Hold on and read this.
In WCF, there is InstanceContextMode and ConcurrencyMode properties defined for ServiceBehavior. These parameters are configurable only within the service code, and not in XML configuration, because they relate to the runtime behavior of the service and the service developer should be aware of their values. The InstanceContextMode parameter determines how many instances of the service have to be created by the WCF runtime. The possible values are:
PerCall: a new InstanceContext object is created for each call.
PerSession: a new InstanceContext object is created for each session. If the channel does not create a session this value behaves as if it were PerCall.This is the default value.
Single: only one InstanceContext object is used for all incoming calls and is not recycled subsequent to the calls. If a service object does not exist, one is created.
More helpful Blog
Use WCF Service Throttling to control the service.
<behaviors>
<serviceBehaviors>
<behavior name="Throttled">
<serviceThrottling
maxConcurrentCalls="1"
maxConcurrentSessions="1"
maxConcurrentInstances="1"
/>
</behavior>
</serviceBehaviors>
</behaviors>
Always remember that service behaviors do not override limits defined in the host (or binding). For example when using webHttpBinding the default IIS Maximum Concurrent Connections would likely need to be changed for large concurrency values.
Turns out it has more to do with threading than anything else. The default ASP.NET settings are pretty conservative, so you have to hike them up. Once I did that, the concurrent connections bottleneck completely disappeared.
Make sure you have the following in the appropriate machine.config (not web.config):
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
<system.web>
<processModel
autoConfig="true"
maxWorkerThreads = "100"
maxIoThreads = "100"
minWorkerThreads = "50"
minIoThreads = "50"
/>
<httpRuntime
minFreeThreads="176"
minLocalRequestFreeThreads="152"
/>
</system.web>
</configuration>
I took all this info from Tuning IIS article by Stuart Brierley. The only thing I changed significantly from his recommendations is maxConnection value.

wcf returning only html of metadata page

UPDATE: i have solved my issue:
the following config line needed removed:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
When i run the wcftestclient utility i get the following error and result from the services when invoking hello world. Any help is greatly appreciated. I cant seem to find the issue as to why it wont invoke the specific method and return the string for hello world.
Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service.

Getting Error "This collection already contains an address with scheme http" with WCF on local machine

I'm trying out WCF for the first time and getting the following error when I try to instantiate the host:
This collection already contains an address with scheme http...
I have found a lot of other references to this and tried some of the solution to no avail. One fairly common thread that does not apply to me is that the problem is on a web server of some sort. I'm just running everything from my local machine.
One interesting symptom I found is that I'm developing a c# Forms app. Originally my top level form object inherited my service interface instead of a separate Service class. When I implement this way, there is no error on the host side but I have been having trouble on the client side.
Based on this solution:
How to solve "The ChannelDispatcher is unable to open its IChannelListener" error?
...I decided to separate the service host into a separate object. That's when I start seeing the problem.
The ServiceContract is simple enough:
[ServiceContract]
public interface ISSAService
{
[OperationContract]
void CreateSpaMonitor();
}
I instantiate the service like this:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAService), baseAddr);
Where SSAService is the implementation of the Service interface.
If I change the second line to the following (and implement the interface...) the error goes away:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAManager), baseAddr);
Where SSAManager is my top level Forms class...
Then I run into a client side problem which is where I started....
I have tried changing the port number and that doesn't seem to affect anything.
I'm new to WCF so maybe I'm missing something obvious.
Thanks.
I was getting this error:
This collection already contains an address with scheme https. There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' to true or specifying 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.
Parameter name: item
I resolved it by doing the following to my web.config. Perhaps something changed in the .NET Framework 4 which is requiring this line, since I didn't need it before:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<!-- Rest of the system.serviceModel content omitted for brevity--->
<system.serviceModel>
This can also occur if you have multiple bindings on the same IIS site with different domain names/ports. I resolved the issue by removing the extra named binding.
One of the solution I found previously was to add something like this:
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://localhost:8000"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
And then specifying the endpoint address absolutely. This didn't seem to have an effect but I was still using baseAddr in the constructor as shown above.
The solution for me was to remove baseAddr from the constructor.

WCF and FluentNHibernate

I've hit a wall on this one. I have a WCF library with a respective WCF web service. A sandbox web application attempts to fire one method from this service.
The service, however, will log requests as they are made. The persistence layer here is built with FluentNHibernate. Session management in a web application has been pretty straight forward in the past(ie HttpModules), but in WCF it got a bit tricky for me.
I followed the notes and examples with the IglooCommons library and added the following line to my global.asax(residing in the web service directory).
protected void Application_Start(object sender, EventArgs e)
{
NHibernateFactory.Initialize(new SessionFactory().BuildSessionFactory());
}
BuildSessionFactory returns the following:
public class SessionFactory
{
public SessionFactory() { }
public ISessionFactory BuildSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration
.MsSql2005
.ConnectionString(x =>
x.FromConnectionStringWithKey("myConnection"))
.ShowSql()
.CurrentSessionContext<WebSessionContext>())
.Mappings(m =>
m.FluentMappings
.AddFromAssemblyOf<OneClass>()
.AddFromAssemblyOf<AnotherClass>()
.Conventions.Add(
PrimaryKey.Name.Is(x => x.EntityType.Name + "ID"),
ForeignKey.EndsWith("ID"),
Table.Is(x => Inflector.Net.Inflector.Pluralize(x.EntityType.Name))))
.BuildSessionFactory();
}
}
The service page(*.svc) loads up with its soothing stock blue "to generate classes use this wsdl" page, with no issue.
When the web application that references this attempts to call a service method,
NHibernateContext.Current().Session
is unable to find any live session. After stepping through the application, the app start method in global.asax is being fired, however seems to be dying(this is a guess) prior to any action requiring it.
I realize IglooCommons may be a bit specific as NHibernateContext is a proprietary library, however, WCF with a persistence layer isn't uncommon. Any thoughts on what I've missed or another direction to take are greatly appreciated.
Additional Note:
For the web application using this service, I've created an "interop" library which was based on the wsdl, auto-generated using svcutil. There isn't a web reference between the web app and the web service, just the web app using the auto-gen classes.
Have you enabled the ASP.NET service hosting environment for your WCF service? This requires that you:
Apply the AspNetCompatibilityRequirementsAttribute to your service with an AspNetCompatibilityRequirementsMode of Required.
That you configure the hosting environment in WCF web.config like so:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<!-- rest of config here -->
</system.serviceModel>
More information about WCF Service hosting with ASP.NET is available here in the MSDN documentation.
This resolution in particular was a misunderstanding of the IglooCommons lib. The "NHibernateContext" attribute in the example was used to decorate the interface, when in reality it needed to decorate the implementation. By moving this alone, the sample on the Igloo site was able to function normally.
As a side note, the other solutions provided here were excellent in expanding the little knowledge I have of inner workings with WCF and its interaction with NHibernate.
Your WCF service svc.cs file should look like this:
[NHibernateContext(Rollback.Automatically)]
public class YourWcfService : IYourWcfService

Forcing WcfSvcHost.exe to use my custom service host

Is it possible to force WcfSvcHost (which is executed automatically when I do an F5 or when I am debugging another project in the solution) to use a custom ustom service?
I have my custom service host working great in my asp.net Host container by using a service factory which in turn calls the Custom Service Base.
But when WcfSvcHost executes it's not using my custom ustom service.
Is this possible?
If not, what are my alternatives? I presume I must uncheck "Start WCF service host when debugging a project in another solution" which is in the WCF Options in app properties but then I must create a console Host container?
And I can't get the console host container to automatically execute each time I am debugging something else?
I notice this under DEBUG in app properties (maybe I can use something like this to force the loading of the custom servicehost)
/client:"WcfTestClient.exe"
The problem being is that I have my custom ServiceHost inject some UNITY (IOC) stuff, here the overriden method ... so it must execute otherwise it fails.
protected override void InitializeRuntime()
{
Bootstrapper.ConfigureUnityContainer();
base.InitializeRuntime();
}
I was trying exactly the same thing for exactly the same purpose (;-)
I thought I found a solution by not using physical .svc files anymore (which contain the custom host factory when hosting in IIS), but moving this info to the .config file instead:
<serviceHostingEnvironment aspNetCompatibilityEnabled="false">
<serviceActivations>
<add relativeAddress="~/Services/NaisTime/NaisTimeService.svc" service="Nais.Time.Services.NaisTime.NaisTimeService"
factory="Nais.Time.Services.NaisServiceHost.NaisServiceHostFactory, Nais.Time.Services" />
<add relativeAddress="~/Services/Northwind/NorthwindService.svc" service="Nais.Time.Services.Northwind.NorthwindService"
factory="Nais.Time.Services.NaisServiceHost.NaisServiceHostFactory, Nais.Time.Services" />
</serviceActivations>
</serviceHostingEnvironment>
It works for IIS, but putting the same entries in the app.config file of my Service Library project does not make SvcWcfHost use this.
I guess I am not getting my relativeAddress right.
Anybody any experience with this?
kr,
Michel Liesmons.
I don't think you can do that - you'll need to host in IIS or create your own, customized service host.

Categories

Resources