Still hacking away with extreme persistence at WF services hosted outside of IIS. I'm now having issues with my WF service publishing metadata. Can someone take a look at my code and see what step I'm missing? The few tutorials that I've stumbled across for my scenario make it look so easy, and I know it is. I'm just missing something ridiculously simple. Here's my current trial code:
const string serviceUri = "http://localhost:9009/Subscribe";
WorkflowServiceHost host = new WorkflowServiceHost( new Subscribe(), new Uri(serviceUri) );
host.AddDefaultEndpoints( );
host.Open();
Subscribe() is an activity that is coded in an xaml file and contains simple receive and sendreply activities to test out my hosted workflow service. It is NOT a xamlx (WF service) file. Seems like this should be simple enough to work but when I start the application and the service fires I get this message in my browser when navigating to the URI:
"Metadata publishing for this service is currently disabled."
Shouldn't adding the default endpoints provide enough metadata and description to satisfy the service init and then go into its wait for message state?
For any future newbies, this also can be caused by not having your app.config setup correctly.
Add the below to your app.config and then open your service location in your browser:
<system.serviceModel>
<bindings />
<client />
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="True"
httpHelpPageEnabled="True"/>
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Well it appears that the debug instance process hung on my machine. I just used task manager to locate the executable and terminate the zombie process.
Related
I can get xml content of service via browser
but somehow cant add as service referance in Visual Studio same link with ?wsdl extension.
The error message in visual studio;
The document at the url
http://****?wsdl was not
recognized as a known document type. The error message from each known
type may help you fix the problem:
- Report from 'XML Schema' is 'The root element of a W3C XML Schema should be and its namespace should be
'http://www.w3.org/2001/XMLSchema'.'.
- Report from 'DISCO Document' is 'Discovery document at the URL http://****?wsdl could not be
found.'.
how can I fix it ?
Have you enabled metadata discovery in WCF?
First off you need to add a mex (Metadata exchange) endpoint like this to the service in web.config, if you are declaratively setting up your WCF service (you can do this also programatically):
<service name="myservice">
<endpoint contract="IMetadataExchange" binding ="mexHttpBinding" address="mex" />
<endpoing contract="SomeAssembly.SomeService" address="SomeService" binding="basicHttpBinding" ...
Note that I will not suggest you use BasicHttpBinding as it default is not set up with security, use WsHttpBinding instead for instance.
Now also add this serviceBehavior:
<serviceBehaviors>
<serviceMetadata httpGetEnabled="true" />
You will find this well documented and a good sample for example here:
WCF Service Behaviors – How to Generate Service Metadata to simplify WCF Client Application Development
Then check again if the WSDL link works of your service. You might want to check out the installed features of IIS if is still not working, maybe your IIS config and setup is not correect.
We have created a WCF service application for a customer. Since the service is used to transmit large amounts of data (which can take a long time), some changes (such as increased timeout limits or message size limits) have been made to the Web.config file to accommodate this.
Everything works fine and there are no technical issues... except the client isn't exactly happy that whenever they create a new application which consumes the WCF service they need to manually add all the changes to the client-side App.config file.
They would like to have the changes to be read from the service automatically.
I've never of WCF having such functionality, so I don't think this is possible. But I would very much like to have this confirmed... or denied, if this is actually possible.
IIRC .. in earlier releases of the stocktrader app.
How to implement Configuration Service 5.0 of the StockTrader 5.0 sample application?
mentioned in the above SOF link
There was a way to get configuration from a service.
However, the stocktrader app looks much different now then it did earlier.
So I don't know which version it become something different.
Greg Leake (Leak) was the name of the dude I met at TechEd one year....talking about this, IIRC.
IT IS NOT TRIVIAL TO IMPLEMENT.
The cost of editing some clientside config files........vs the configuration service.....you'll have to make that call.
But it sounds like you have a case of your client needing some cheese with their whine.
Here is an older video...that might get you on the right path.
http://channel9.msdn.com/Shows/Endpoint/endpointtv-High-Performance-WCF-NET-Stock-Trader-with-Greg-Leake
This PDF
http://download.microsoft.com/download/7/C/9/7C9F7B89-8AF0-4433-AB3A-B615C8EF9484/ConfigServiceVSTemplate.pdf
will give you the hints at it.
It is a lot of work to get a "configuration service" up and running.
We ended up...NOT doing it.......and using xml-manipulation in msbuild tasks.......to tweak the wcf client-side xml sections.
EDIT:
Alternate idea. Put you WCF in separate files..and distribute those.
It will make the "where to edit" much more discernable ..... or go with whole-sale replacement all of the (4) files.
app.config or web.config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors configSource="WCFBehaviors.config">
</behaviors>
<bindings configSource="WCFBindings.config">
</bindings>
<client configSource="WCFClient.config">
</client>
<services configSource="WCFServices.config">
</services>
</system.serviceModel>
Then make the 4 files.
Example WCFServices.config
<services>
<service name="MyApp.MyService">
<endpoint
address = "http://localhost:8001/MyService"
binding = "wsHttpBinding" bindingConfiguration="WSHttpBindingName1"
contract = "MyApp.MyIService" >
</endpoint>
</service>
</services>
Note, these won't be auto-voodoo-included like web.config and app.config.
You'll have to make sure they end up in your build-outputs.
Unless you create a custom method to expose these parameters, or at least the values of them, they are not visible to the consumer.
Config files are supposed to be private which is why you are not able to browse to them in a standard installation.
It sounds to me like your client needs to accept that perhaps when adding a new service, there is a little bit of work that needs to be done. They could in theory cut and paste the servicemodel configuration, or sections of it, from an existing application to save 'some' time.
I am trying to add service reference.
There was an error downloading metadata from the address
this is the error which is being displayed again and again?
Please help
You may also just need to build / rebuild the project.
There are atleast 4 possibilities:
The metadata exchange mex endpoint is not defined
metadata exchange is not enabled
You are using the wrong address
You are being blocked by some security setting
Try the url in a browser to see that it returns a wsdl
It was happening the same to me and I found that I've had forgotten to add the "Service Contract" and the "Operation Contract" annotations on the interface of my WCF service
Just try to Build the project without any error and give service reference again.
In Web.config file I changed :
<endpoint address="" binding="pollingDuplexHttpBinding"
contract="IAsyncTaskService"/>
to this :
<endpoint address="" binding="pollingDuplexHttpBinding"
contract="DuplexService.Web.IAsyncTaskService"/>
and error was removed.
Zeni
Try rebuilding the project first, if that does not fix it, try changing the property httpGetEnabled from FALSE to TRUE in your web.config.
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
Check IIS is serving the service URL. In my case, I had changed my Windows password, but had forgotten that these credentials were being used by IIS in both the application and the app pool.
I know this is an oldie, but I thought I would add what worked for me so that I can find it again down the road ;)
In my case, the AppPool user didn't have access the %Windir%\temp, which apparently is necessary in order for the MEX data to be generated.
Shout out to Amy Peng in this thread for her tip!
Another possibility in this situation is that there is no endpoint listening. I.e., the service you are trying to add isn't "up". I made this mistake when trying to add a reference to a WCF service I was working on, but I forgot to Open it.
I had an issue like this one : Adding a service reference failed with a message "Method not allowed".
The wsdl worked fine in my browser..
The reason was that I configured the endpoint to listen on http://0.0.0.0:6000/mex, which the "Add Service Reference" tool doesn't seem to like. Changing it to a real IP address made it work (e.g. http://127.0.0.1:6000/mex)
I have a simple service that I deployed to Azure. It is accessible via:
http://xxxxxxxxxxxxxxxxxxxxxxx.cloudapp.net/MyTestService.svc
The URL to the WSDL uses the internal machine name instead of a public DNS:
svcutil.exe http://rd001520d328923a/MyTestService.svc?wsdl
Obviously, the WSDL is not accessible from outside the machine with this.
I am aware of a few things that can be changed if you are running this in IIS, or if you do know the url of the service. For example changing the <serviceMetadata> config to specify the httpGetUrl property, but this will not work as I would have to include the absolute URL. Using a relative URL, it still uses the internal machine name. The real issue is that the WSDL includes URL references with the machine name, therefore rendering it useless.
There are two substandard workarounds:
It has been suggested that I could grab the WSDL, edit it to fix the URLs and then upload it so it is accessible from a different URL.
I found a hotfix from early 2010 was available, but there's got to be a better way.
How can this be solved to have the public facing DNS used instead of the machine name?
Ok. I have been looking at this for almost a week. I finally found the answer, since it is not easily available I hope this gets indexed and save the time for others.
Basically this overall behavior as a known issue with WCF 3.0/3.5, for which they released a hotfix. You can find out more here: FIX: URIs in a WCF WSDL document refer to inaccessible internal instances instead of to the load balancer...
I had come across this a few times during my research but never gave it a 2nd thought, mostly because I had no idea how I would deploy a hotfix into Azure.
Fortunately, a Microsoft moderator at the MSDN forums pointed out that this had been fixed in .net 4.0. What this meant was that the "fix" recommended in the KB article above, still applied, with the exception that no hotfix had to be applied. So what is the solution?
Simple, add the following to the config file:
<serviceBehaviors>
<behavior name="<name>">
<!-- Other options would go here -->
<useRequestHeadersForMetadataAddress>
<defaultPorts> <!-- Use your own port numbers -->
<add scheme="http" port="81" />
<add scheme="https" port="444" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
And that was it.
This would have been a much simpler search if it had been clearer that this issue had now been fixed. Perhaps I didnt look hard enough.
The blog post Using Request Headers for Metadata Address is similar to
Victor's answer, but explains that default ports are optional
and can be omitted:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<useRequestHeadersForMetadataAddress/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
It also shows how to enable the behavior in the code.
sh.Description.Behaviors.Add(new UseRequestHeadersForMetadataAddressBehavior());
Are you generating the WSDL in order to publish it, or are you just trying to add a reference in another project?
If it's the later, my suggestion is to use the WCF ChannelFactory approach rather than "add service reference". I find it gives me more consistent controllable results.
http://msdn.microsoft.com/en-us/library/ms734681.aspx
I must add, I haven't tried this on Azure.
I've got a duplex WCF service which hangs after the magic 10 proxy instantiations. The specific error on the client is:
"System.TimeoutException: This request operation sent to net.tcp://localhost:8080/RoomService/netTcp did not receive a reply within the configured timeout (00:00:59.9960000)".
There aren't any apparent error messages on the server.
Note that this isn't the standard, obvious problem, i.e., failing to close my proxy connections, as I'm closing every instance of my proxy connection appropriately before opening the next one:
try
{
client.Close();
}
catch (CommunicationException)
{
client.Abort();
}
catch (TimeoutException)
{
client.Abort();
}
catch (Exception)
{
client.Abort();
throw;
}
And I've set my throttling behavior to 500 simultaneous everything:
ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
MaxConcurrentCalls = 500,
MaxConcurrentSessions = 500,
MaxConcurrentInstances = 500
};
I've set the ConcurrencyMode of my service to Multiple, and I've tried all three possible values for InstanceContextMode.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
I've tried self-hosting the service, and hosting it within IIS, and I get the same results on each.
I've tried the NetTcpBinding, the WSDualHttpBinding, and the PollingDuplexBinding (on Silverlight), with the same results on each. I can't try the BasicHttpBinding or the WSHttpBinding, as this is a duplex service.
There was one place in my code where I was launching multiple threads (to execute multiple callbacks simultaneously), but for troubleshooting purposes I've commented that bit out, and it hasn't made a difference.
On the client, I've tried using new proxies for each test, and reusing the same proxy across all tests, but without any luck. I've tried creating a new InstanceContext for each proxy, and reusing the same InstanceContext across all proxies, and again, no luck.
Whatever I do, after the 10th test executed in my test harness, the next call to the service hangs.
Any thoughts on what I might be doing wrong?
OK, so I made at least one stupid mistake: I was creating the throttling behavior, but was neglecting to add it to the service proper. It's now added correctly:
ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
MaxConcurrentCalls = 500,
MaxConcurrentSessions = 500,
MaxConcurrentInstances = 500
};
base.Description.Behaviors.Add(throttlingBehavior);
And now I can run more than 10 tests, and hence my immediate problem is solved.
But I'm still puzzled as to why I'm running into this problem at all, since I'm specifically closing one proxy before moving on to the next. A MaxConcurrentXXX of 2 ought to be working in this scenario; I shouldn't need a MaxConcurrentXXX of 500. I'm a tad worried about scalability if every client that connects to the server continues to chew up a connection beyond the time that it's actually connected.
Maybe I'm making a stupid mistake somewhere else -- it wouldn't be the first time -- but I've specifically stepped through the code that's closing the proxy, and it's definitely getting called.
I've had this happen when I had a semaphore on the server-side which wasn't being released after a client was done being serviced.
Are any server-side resources or locks not being released properly? Since your service instance is per session, I'd suspect that the server object is hanging around and holding a lock. What if you change the behavior to per call?
I don't have an answer but I do have some debugging advice.
1) Attach the visual studio debugger to the service process and see if it can catch whatever is going on.
2) Configure the service behavior to pass exception information back to the client and see if the service is throwing an exception that isn't being reported:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
3) Turn on service logging with ActivityTracing enabled and use the Service Trace Viewer (from Windows SDK) to analyze the log and see if anything pops up
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Service.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
4) Isolate the service wrapper from the functional code and see if the service still hangs. If it doesn't then incrementally add functionality back until you figure out what is making it hang
5) If you are using an HTTP binding, proxy the service with fiddler and log the http traffic.
6) Try Hosting the WCF service in a Managed Windows Service and attach a debugger to the service process after you start it up.
Take a look at ServiceBehavior.AutomaticSessionShutdown.
At the begining of the Callback function in the client use
OperationContext.Current.Channel.Close();
This will solev the problem.