Contract attribute is invalid - wcf

I have been reaching this for a few hours now. I am getting this error message:
The 'contract' attribute is invalid - The Value 'AddressService.IAddressVerificationService' is invalid according to it's datatype 'clientContractType' - The Enumeration constraint failed.
and the config file looks like this:
<endpoint address="http://www.verifythisaddress.com/AddressVerification/AddressVerificationService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAddressVerificationService"
contract="AddressService.IAddressVerificationService" name="BasicHttpBinding_IAddressVerificationService" />
My Service beginning looks like:
namespace AddressVerificationWCF
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IAddressVerificationService
{
[OperationContract]
Address VerifyThisAddress(string stuff);
}
}
I have tried numerous things like changing the names, deleting files, etc. but am scratching my head AGAIN.
Thanks.

The contract needs to be the fully-qualified name of the interface - usually the namespace that contains the interface, plus the interface name. Looking at your posted code this should be:
AddressVerificationWCF.IAddressVerificationService
So your config would look like:
<endpoint address="http://www.verifythisaddress.com/AddressVerification/AddressVerificationService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IAddressVerificationService"
contract="AddressVerificationWCF.IAddressVerificationService"
name="BasicHttpBinding_IAddressVerificationService" />

The value is invalid according to its datatype 'clientcontracttype'
In above Vincent Van Den Berghe suggested below that solved my issue. Credits to Vincent...
The same error occurs when you're missing a reference [in the project
with the .config] to the actual project/library containing the
interface/service contract...

I was having a similar issue. I ran my VS 2012 in administrator mode and it solved it.

Related

WCF Service Reference Error in WIndows Service

I have a windows service with a base namespace of XXXX. I have a number of WCF services with a base namespace of WebServices. These are hosted in IIS.
When I add one of the WCF services (DataManagement) as a service reference to my windows service, I get the following errors when I build the service:
Error 162 The type name 'WebServices' does not exist in the type 'XXXX.XXXX'
Reference.cs Line 200 Col 61
Error 163 The type name 'WebServices' does not exist in the type 'XXXX.XXXX'
Reference.cs Line 205 Col 94
Error 164 The type name 'WebServices' does not exist in the type 'XXXX.XXXX'
Reference.cs Line 205 Col 134
Reference.cs is an automatically generated file, The lines of code created are:
Error 1:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IDataManagementChannel : XXXX.WebServices.IDataManagement, System.ServiceModel.IClientChannel {
}
Errors 2 & 3:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class DataManagementClient : System.ServiceModel.ClientBase<XXXX.WebServices.IDataManagement>, XXXX.WebServices.IDataManagement {
I have been struggling to resolve these without much success. None of the suggestions I have found that appear to be related to this issue work for me. There was one issue with the same problem, but there were no answers. Any ideas?
I'm pretty certain your issue is as demonstrated by the following code
namespace XXXX
{
class XXXX
{
}
}
namespace XXXX.WebServices
{
class A
{
}
class B : XXXX.WebServices.A // compiler error : CS0426 The type name 'WebServices' does not exist in the type 'XXXX'
{
}
}
The compiler is attempting to find a nested type within the class XXXX called WebServices and not the XXXX.WebServices namespace hence the error "does not exist in the type".
You can be explicit about the fact that you're referring to a namespace by prefixing the namespace with global::. It's not ideal to do this on a generated file like Reference.cs. If possible maybe consider generating your proxy in a different namespace.
See the help for compiler error CS0426 here
A bit late, but in case someone stumbles upon this...
Steps to reproduce:
Create a windows service project "TestService".
Rename the Service1 class to TestService.
Compile - it works.
Add reference to a WCF service.
Compile - it no longer works.
error CS0426: The type name 'SomeWCFService' does not exist in the type 'TestService'
Solution: Change the name of the TestService class to something else, as it conflicts with the TestService namespace.

The server encountered an error processing the request. See server logs for more details

I have a simple problem.
I've created a WCF Data Service 5.6 in visual studio 2013, and in its *.svc.cs file, modified line
public class CustomdataService : DataService< /* TODO: put your data source class name here */ >
to connect my entities
public class CustomdataService : DataService< SchedulerEntities >
But when I want to see the service in browser it gives me following error
Request Error
The server encountered an error processing the request. See server logs for more details.
The entity framework is nothing but a single table...
The actual error can be different. In my case I got the same general error message when starting with AdventureWorks2012 database.
So the actual problem can be seen by appending an attribute to the service class as described at here:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WcfDataServiceAW : EntityFrameworkDataService<AdventureWorks2012Entities> { ... }
Hope it helps someone.
PS. My error is:
The exception message is 'The property 'SpatialLocation' on type 'Address' is of type 'Geography' which is not a supported primitive type.'.
It seems that Entity Framework 6 and WCF Data Services 5.6.0 need some provider to work together, read more on Using WCF Data Services 5.6.0 with Entity Framework 6+.
You can download the provider simply by using NuGet Package Console Manager:
Install-Package Microsoft.OData.EntityFrameworkProvider -Pre
Its version is alpha 2, so in future, search for final release. it worked for me however.
Final thing is, instead of using DataService<T>, you need to use EntityFrameworkDataService<T>. T is the name of your entities.
According to this post, you have to change inherited type of CustomdataService.
Replace the base type of your DataService. For EF 5 or below, your data service should inherit from DataService where T is a DbContext or ObjectContext. For EF 6 or greater, your data service should inherit from EntityFrameworkDataService where T is a DbContext. See What’s the difference between DataService and EntityFrameworkDataService below for more details.
go to edmx, in the diagram, remove all the tables until the only one you want is remain,
then should be okay, cannot have all the tables, this is what I found,
KT Wong

Using appsettings, but "ConfigurationSettings" method is obsolete

I've trying to access an appsettings key value in my vb.net 2.0 web application.
I've put the key in the app.config file:
<appSettings>
<add key="DownloadURL" value="http://<myURL>/" />
</appSettings>
I've followed the instructions here, and it says that I need to access this key like so:
URL = System.Configuration.ConfigurationSettings.AppSettings("DownloadURL")
But I get the following message:
Public Shared Readonly property
AppSettings() As
'System.Collections.Specialized.NameValueCollection'
is obsolete: 'This method is obsolete,
it has been replaced by
System.configuration!System.configuration.configurationmanager.AppSettings'
I tried to replace the old method with the new one, but it does not exist.
Strange, since I've done a similar thing with a web app and it did exist there.
Add a reference to System.Configuration.dll.
Here's an explanation.

How to use current datetime for FindByTimeValid value in WCF ServiceCertificate config

How do I use current date & time as the value for the findValue attribute in the ServiceCertificate config when using "FindByTimeValid" for the x509FindType? Using DateTime.Now as below obiously doesn't work but neither does "2010-10-20 14:35:28Z". I have two certificates on the server with the same details as one of them has expired which is why I'm using this find type value.
For example:
<serviceCredentials>
<serviceCertificate findValue="DateTime.Now" x509FindType="FindByTimeValid" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
Edit: I fixed this by removing the expired certificate but I'm still curious if this is possible.
Thanks
Keith
As no-one seems slightly interested in this question (2 views in a month and I think at least one of them was me) I decided to break out Reflector and have a look at the process and have found the following.
In the X509Certificate2Collection.FindCertInStore(SafeCertStoreHandle safeSourceStoreHandle, X509FindType findType, object findValue, bool validOnly) method of the System.ServiceModel assembly we have the following code
case X509FindType.FindByTimeValid:
if (findValue.GetType() != typeof(DateTime))
{
throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue"));
}
As you can see from the signature the findValue comes in as an object which I think is in turn loaded by the config parser as a string which means this will never work.
So the answer is you can't do this though the xml config but you can if you do it programmatically.

Change Address/Port of WSDL EndPointAddress at runtime?

So I currently have 2 WSDLs added as Service References in my solution. They look like this in my app.config file (I removed the "bindings" field, because it's uninteresting):
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/query-service/jse" binding="basicHttpBinding" bindingConfiguration="QueryBinding" contract="QueryService.Query" name="QueryPort" />
<endpoint address="http://localhost:8080/dataimport-service/jse" binding="basicHttpBinding" bindingConfiguration="DataImportBinding" contract="DataService.DataImport" name="DataImportPort" />
</client>
</system.serviceModel>
When I utilize a WSDL, it looks something like this:
using (DataService.DataClient dClient = new DataService.DataClient())
{
DataService.importTask impt = new DataService.importTask();
impt.String_1 = "someData";
DataService.importResponse imptr = dClient.importTask(impt);
}
In the "using" statement, when instantiating the DataClient object, I have 5 constructors available to me. In this scenario, I use the default constructor:
new DataService.DataClient()
which uses the built-in Endpoint Address string, which I assume is pulled from app.config. But I want the user of the application to have the option to change this value.
1) What's the best/easiest way of programatically obtaining this string?
2) Then, once I've allowed the user to edit and test the value, where should I store it?
I'd prefer having it be stored in a place (like app.config or equivalent) so that there is no need for checking whether the value exists or not and whether I should be using an alternate constructor. (Looking to keep my code tight, ya know?)
Any ideas? Suggestions?
EDIT
Maybe I should ask about these Alternate constructors as well.
For example, one of them looks like this:
new DataService.DataClient(string endPointConfigurationName,
string remoteAddress)
What values could get passed for "endPointConfigurationName" and "remoteAddress"?
EDIT2
Answering my own questions here, the "endPointConfigurationName" appears to be the same as the "name" in the app.config XML and the "remoteAddress" is formatted the same as "endpoint address" in the app.config XML.
Also! The answer to my first question about getting the EndPointAddresses is the following:
ClientSection clSection =
ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
ChannelEndpointElementCollection endpointCollection =
clSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;
Dictionary<string, string> nameAddressDictionary =
new Dictionary<string, string>();
foreach (ChannelEndpointElement endpointElement in endpointCollection)
{
nameAddressDictionary.Add(endpointElement.Name,
endpointElement.Address.ToString());
}
EDIT3
Ok, I think I've figured out the 2nd half (and thus, full solution) to my problem. I found this on another website and I modified it to meet my needs:
Configuration configuration;
ServiceModelSectionGroup serviceModelSectionGroup;
ClientSection clientSection;
configuration =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
serviceModelSectionGroup =
ServiceModelSectionGroup.GetSectionGroup(configuration);
clientSection = serviceModelSectionGroup.Client;
foreach (ChannelEndpointElement endPt in clientSection.Endpoints)
{
MessageBox.Show(endPt.Name + " = " + endPt.Address);
}
configuration.Save();
With this code, we have access to the clientSection.Endpoints and can access and change all the member properties, like "Address". And then when we're done changing them, we can do configuration.Save() and all the values get written out to a user file.
Now here's the catch. In debug mode, the "configuration.save()" does not appear to actually persist your values from execution to execution, but when running the application normal (outside of debug mode), the values persist. (Which is good.) So that's the only caveat.
EDIT4
There is another caveat. The changes made to the WSDLs do not take effect during runtime. The application needs to be restarted to re-read the user config file values into memory (apparently.)
The only other thing that I might be interested in is finding a way (once the values have been changed) to revert the values to their defaults. Sure, you can probably delete the user file, but that deletes all of the custom settings.
Any ideas?
EDIT5
I'm thinking Dependency Injection might be perfect here, but need to research it more...
EDIT 6
I don't have comment privileges but you need to run
ConfigurationManager.RefreshSection("client");
to have the cache updated so that changes happen immediately.
If you're using Microsoft Add Web Reference to create your service reference, then I think you may have trouble changing the connection programmatically. Even if you did change the auto generated code, as soon as you did an Update Service Reference it'd be overwritten.
You're best bet is to scratch Microsoft's auto generated code and build your own WCF classes. It's not difficult, and offers lots of flexibility / scalability.
Here's an excellent article on this very subject.
As for storing the custom addresses, it would depend on your app whether it's a Silverlight, Windows or web app. My personal choice is the database.