Discovered WCF service can't connect - c#

I have a WCF service that I'm using to expose a data source (connected to via an EF model). My endpoint for some reason just stopped responding.
Up until my last changes I was just pulling the data at startup of my app. I'm now working on adding a subscribe/publish model on top of this so I can throw events when something hits the WCF service that results in the data changing (could do it in the client side but than I wouldn't catch other users changes).
I've been following the example from Microsoft: http://msdn.microsoft.com/en-us/library/ms752254.aspx and added the appropriate decorations to my service interface and implementations and added a subscribe/unsubscribe OperationContract etc. I than try to fire up the service and can't connect.
I than dropped the Service Reference from my client and tried to reattach. Here is the strange thing:
1) The WCF service builds and spins up in the developer host.
2) The Web.Config file wasn't touched.
3) The "Discover Services" option in the add service reference in vs 2012 sees the service but when I try to actually accept the discovered service it throws an error saying "error downloading metadata from the address.
I don't get how it can discover the service and then not be able to add it as a reference. I can see if I added the info myself but it found it.
As part of adding the publishing functionality I added the SessionMode.Required tag to the interface I'm not really sure how WCF handles sessions and haven't ever had to deal with sessions anywhere else in my coding (generally pull the data from the source and than process it locally has been the types of tools I needed to make in the past so no state needed to be persisted server side).
Any ideas?
my service web.config:
<connectionStrings>
<add name="TaskModelContainer" connectionString="metadata=res://*/TaskModel.csdl|res://*/TaskModel.ssdl|res://*/TaskModel.msl;provider=System.Data.SqlClient;provider
connection string="data source=winhacker\sqlexpress;initial
catalog=TaskDB;integrated
security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient"/>
Note: Note sure what is going on with the formating most of the file doesn't show up in the preview but sufficience it to say it is the boilerplate one that gets autogenerated other than I added a connectionStrings section to like to my EF datapoint. If you want to see the file click on "edit" seems to show the source I copied though a bit formatted weird.

In the vast majority of cases where I have encountered this error, the issue has been a serialization issue on the server side; WCF will throw an exception about this during the metadata discovery phase, but VS does not display this exception.
In order to troubleshoot this problem, you need to add a diagnostics section to your web.config to capture the WCF information into a svclog file, then use Microsoft's Service Trace Viewer to examine the log and discover the actual exception being thrown.
The web.config section should look something like this:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\log\WebTrace.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
and be added at the <configuration> level.
Once you have added the configuration and ensure that the specified directory exists, try adding the service reference again. This should cause the specified svclog file to be generated.
If you have VS installed on that machine, you should be able to just double-click the file in Windows Explorer and have the log opened automatically in the tool.
Once the log is opened, look down the list of activities in the left hand pane and click on the first one in red. Then, in the top right pane, select the first one that is red (or shows an exception, I forget which). You can then click on that to see the details, including exception information in the bottom right pane.

Related

CloudConfigurationManager doesn't overwrite settings from an external file

I've just found an obscure, yet deeply frustrating, bug with CloudConfigurationManager. I'm looking for workarounds, and also (as a side note) tips about the best forum in which to report the bug. I'm guessing it will be a relatively quick fix.
I've got an Azure app service that connects to DocumentDb with config settings called DocumentDB.Endpoint and DocumentDB.Key. These are picked up in F# with
let endpoint = config.ReadConfigSetting<string>("DocumentDB.Endpoint")
let key = config.ReadConfigSetting<string>("DocumentDB.Key")
The ReadConfigSetting method is a convenience method that performs the relevant type conversions and default assignments. Under the covers it uses CloudConfigurationManager.GetSetting. For our purposes, think of the call as
let endpoint = CloudConfigurationManager.GetSetting("DocumentDB.Endpoint")
let key = CloudConfigurationManager.GetSetting("DocumentDB.Key")
I have a webjob that performs cron jobs on my document DB collections. CloudConfigurationManager picks up the setting from the app service settings first, and if the key is not found in the app service settings, it will look at my webjob's app.config.
In my QA environment, my webjob is picking the correct endpoint, but the wrong key. This is because DocumentDb.Endpoint is listed directly in my app.config file, but DocumentDb.Key is in a separate file that is .gitignored. I don't want sensitive keys in the Git repo, even though it is private, and the credentials are only listed in app.config and my external file as a convenience that lets me run the job locally with a debugger.
So here is my setup:
App.config
<appSettings file="keys.config">
<add key="agentUserName" value="<Everyone can read this>" />
<add key="apiHost" value="<and this>" />
<add key="DocumentDB.Endpoint" value="<points to my remote develpment copy of DocumentDB -- looking forward to when I can get a local repo>" />
</appSettings>
keys.config
<appSettings>
<add key="DocumentDB.Key" value="<This is private, so it's in this gitignored file>" />
<add key="agentPassword" value="<I'm not telling you>" />
<add key="TestUserPassword" value="<I'd be an idiot to post this value in a SO question>" />
</appSettings>
You can see what's happening.
Expected behaviour of CloudConfigurationManager when looking up the value of DocumentDB.Key
Look at the underlying app serice settings for a value of DocumentDB.Key
If it exists, use that.
Otherwise, look in App.config.
If it's not there, look in keys.config.
Actual behaviour of CloudConfigurationManager
Is there a value in keys.config?
If so, use that value.
Then look at the app service settings
Then App.config.
The best workaround I have right now is to comment out the value in keys.config when I publish the web job, but that's clunky. Are there any better ways of doing this?
And where is the best place to log this issue?
Have you looked into Azure Key Vault? Here is an intro to Azure Key Vault: https://azure.microsoft.com/en-us/documentation/articles/key-vault-get-started/
If you store DocumentDB secrets in the Azure Key Vault, you can grant the access to the secrets to the application level. Here is another article that shows how to do it inside a web application: https://azure.microsoft.com/en-us/documentation/articles/key-vault-use-from-web-application/
Hope that helps.
Thanks.
Lengning

WCF custom ServiceHost on IIS

I'm trying to host my WCF service with a custom ServiceHost on IIS. I found a couple of articles on MSDN like this: Custom Service Host. Here, I'm supposed to add something to my services svc file, but I don't have one and I can't add one in visual studio either. Then I found this article: Configuration-Based Activation in IIS and WAS. This says
"The configuration-based activation feature removes the requirement to have a .svc file and therefore the associated overhead."
so I can just create a serviceHostingEnvironment entry in my Web.config (which I don't have either, but I guess App.config is equivalent since it contains my system.serviceModel configuration). However, I have to specify a relativeAddress for the service activation.
"The relativeAddress attribute must be set to a relative address such as <sub-directory>/service.svc or ~/<sub-directory/service.svc. "
So it should point to my svc file? I'm a bit confused, could you point me to the right direction?
I know documentation on MSDN is little confusing. Here is configuration that you need to put in web.confi/app.config
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="MyNonExistingServiceSVC.svc" service="MyService" factory=”MyServiceHostFactory”/>
</serviceActivations>
</serviceHostingEnvironment>
Here relative address will be just any dummy name. This name will be used to browse your service metadata. Please note that this name can be anything of your choice and it DOES NOT require same physical file to be present on disk. It just needs any name with .SVC extension.
So while accessing service metadata your URL will be
http://myserver/myservice/MyNonExistingServiceSVC.svc

Outputting to the Console in C# on IIS

We are trying to debug some web services code we're running in C# on IIS. I am new to Windows programming and have no idea how to view output to the console. We've got some write statements in the code, but I can't figure out how to view the console while this thing is running. Help?
I have found the Trace feature extremely helpful. You can get there by going to:
http://mysiteurl/trace.axd
In your web.config, place the following within the System.Web tag:
<trace enabled="true"
localOnly="false"
pageOutput="false"
requestLimit="500"
traceMode="SortByTime"
/>
Now from your code behind, you can inject some logging by doing:
HttpContext.Current.Trace.Warn("I Made It Here!");
You'll want to take a look at ASP.NET tracing
here is a handy link to get you started: http://www.asp101.com/articles/robert/tracing/default.asp
you can enable application wide tracing if you place the following in your web.config, then you will have access to your trace.axd
<trace enabled="true"
localOnly="false"
pageOutput="false"
requestLimit="500"
traceMode="SortByTime"
/>
If you're using asp.net then trace.axd should contain trace statements (as long as its turned on).
You aren't going to get a console for IIS. CLOSEST you will come is Debug.WriteLine w/ a debugger attached or using page tracing. Recommendation would be to use a logging framework that will write to debugger (when attached) as well as a file and possibly the event log (all configured via your listeners).
Some great ones are log4net and NLog.

Http modules integrated into IIS 7 processing pipeline

Q1 -IIS7 by default automatically registers FormsAuthenticationModule ( which is defined in root web.config file ), but does the term “Http module being integrated into IIS 7 processing pipeline refers” only to cases where this registered module is also configured to work with non-Asp.Net applications?
In my opinion if module is not configured to work with non-Asp.Net applications, even if it is automatically registered by IIS 7, then we can’t really claim that it is integrated into IIS 7’s processing pipeline?!
Q2
A) IIS7 automatically registers some of the modules defined in root web.config file.
If we configure ( via IIS7 manager ) UrlAuthorizationModule ( which is defined in root web.config and which IIS 7 registers by default ) to be used with non-Asp.Net apps also, then IIS7 puts the following entry into application’s root web.config file:
<modules>
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
But why did IIS 7 also include <remove name="UrlAuthorization" /> element?
B) I assume if we then change our mind and decide to use this module only with Asp.Net applications, we can safely remove the following element:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
from application’s root web.config file, since now our application can use UrlAuthorizationModule defined in root web.config?!
Q3
I realize IIS7 by default registers FormsAuthenticationModule defined in root web.config file, but assume we register another FormsAuthenticationModule in web.config contained in a root directory of some web application.
I assume when request for web page is received, two instances of FormsAuthenticationModule will be executed for that request?
thanx
EDIT:
A1.
"integrated" vs "classic" processing pipelines is a property on the application pool. It is correct that modules can be set to run only in "integrated" pipelines.
My question was referring to IIS 7 in integrated mode. Namely, my book uses the term “Http module being integrated into IIS 7 processing pipeline refers” to describe a situation where custom Http handler has been registered with IIS 7 (running in integrated mode). But it doesn’t say whether the term refers to situation when this registered handler is configured to work with non-asp.net applications also or do we also use this term when registered Http handler is configured to only work with Asp.Net applications?
A2. B. Yes, you can remove the "remove" as well as the "add" lines. This is what the GUI will do if you change it back to inherit the settings.
But in my case IIS 7 doesn’t remove
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
from application’s root web.config file,,it just changes the value of preCondition attribute back to "managedHandler"
A3. I think you'll get an error if you try to add 2 modules that have the same "name" attribute. If you really want it in there twice then change the "name" of the 2nd one.
I apologize, I should be more specific, but my question was referring to a situation where two modules would have different names.
So in that case there will be two instances of FormsAuthenticationModule running?
thanx
Just noticed that you are using Stackoverflow. Please check my latest answers at iis.net.
http://forums.iis.net/t/1157580.aspx
An important thing is that applicationHost.config and root web.config actually have different meaning still, so don't be confused if an item appears in both files. That actually has different meanings.
A1. "integrated" vs "classic" processing pipelines is a property on the application pool. It is correct that modules can be set to run only in "integrated" pipelines.
A2.
A. In order to change the "preCondition" attribute, it had to remove the first version and add it again.
A2. B. Yes, you can remove the "remove" as well as the "add" lines. This is what the GUI will do if you change it back to inherit the settings.
A3. I think you'll get an error if you try to add 2 modules that have the same "name" attribute. If you really want it in there twice then change the "name" of the 2nd one.

global.asax not being updated

We have a web application where we are using global.asax for url rewriting. We use a compiled version of the site on the live server.
As a part of modification request, we had to add some custom native AJAX code where javascript would call a webservice to update the content of the page. For being able to call the webservice with extension .asmx, we modified the url rewriting code to handle asmx requests seperately.
this arrangement works fine on the local machine, but when we publish the site and deploy it on the live server, the new code doesnt seem to get included. It still skips the condition to check the ".asmx" extension, and throws a page not found exception considering the webservice name as a page name.
We have tried looking all over and googled for such things as well.. but no avail..
any pointers on what might be going wrong.. ?
Assuming your URL rewriting is good (isn't that normally implemented as a HttpModule?) I'd check to make sure that there's an ISAPI mapping in IIS on production that sends .asmx requests to ASP.NET.
If you think your changes to the global.asax haven't been rejitted then you can always stop the application pool, go find your web applications compiled bits in c:\windows\microsoft.net\framework[version]\temporary asp.net files... and delete the jitted version. I've seen ASP.NET miss when it comes to Jitting changes before.
I'd also consider running http fiddler (IE) or tamper data (FireFox extension) on one of the pages that makes calls to the web service. It will tell you exactly how the page is calling the web service and you can validate that the called URL is correct.
There is machine.config file where you can add HttpModules. I also think that you can do that through web.config.
One reason I can think of is that in the Web.config, you might have configured the routing module in the system.web section but not in system.webServer (or at least forgot something in there).
I the similar problem before and the solution was to remove the module & add it again in the system.webServer section of the Web.config like this:
<system.webServer>
<modules>
<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, e="RoleManager" type="System.Web.Security.RoleManagerModule"/>
</modules>
</system.webServer>
It might be a different module or handler but the idea is basically the same. It's important to "remove" the module first.

Categories