This project is read-only.

WCF Client - Attempt to parse version number from Action failed exception

Nov 4, 2008 at 2:28 AM
Hi,

I have imported a WCF service hosted in IIS into MSE.  I have checked that the end point works by typing the address in IE, I can even get back the WSDL.  In my client application (an ASP.Net app) I create the client using WCF to auto-gen the proxy, but when it goes to call a method it gets an MSE exception.  The error looks similar to http://www.codeplex.com/servicesengine/Thread/View.aspx?ThreadId=30143, but because I am using the WCF auto-gen'd proxy there doesn't seem to be a way to strip the namespace from the action.

Error messages

Communication error trying to call GetOperationVersionsForEndpointAndActionResult

to catalog at address: [net.pipe://localhost/ServiceCatalog/Pipe] due to error [Attempt to parse version number from Action failed: Input string was not in a correct format.] with Action [http://tempuri.org/IUsers/FindUsers] EndPointId [0ea05ae4-8b64-467d-ba20-34aef461e4cf] EndPointUri[http://iagam-dev02.iagam.net:8095/Users]

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

---
Communication Error in IsRequestValidForOperationVersion : Failed to validate Request Message Schema due to error [The 'http://www.w3.org/2001/XMLSchema:schema' element is not declared.]

 

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

This is the code for auto-gen'ing the proxy
protected virtual IUsers UsersService

 

{

 

get { return ChannelFactory<IUsers>.CreateChannel(Binding, new EndpointAddress(new Uri(UsersServiceUrl), EndpointIdentity.CreateUpnIdentity(UsersServiceUser))); }

 

}

 

 

private static WSHttpBinding Binding

 

{

 

get

 

 

 

 

 

{

 

WSHttpBinding binding = new WSHttpBinding();

 

binding.MaxReceivedMessageSize =

int.MaxValue;

 

binding.ReaderQuotas.MaxArrayLength =

int.MaxValue;

 

binding.ReaderQuotas.MaxStringContentLength =

int.MaxValue;

 

binding.ReaderQuotas.MaxDepth =

int.MaxValue;

 

binding.Security.Mode =

SecurityMode.None;

 

 

return binding;

 

}

}


I attempted to add a line when creating the WSHttpBinding to set the  binding.Namespace = ""; but that didn't work either.

Any help would be appreciated.  If you need one, I could probably whip up a repo pretty quickly.

I suppose one solution is to modify the proxy on the client to remove the schema from the action, or in the MSE somewhere put the schema in the action name (but I couldn't find anywhere to do this).

Cheers,
Chris

 

Nov 4, 2008 at 2:34 AM
Found this in the Dispatch Moniker for the Operation, so it looks like the Action should be matching, which makes me think it is not picking up the correct version number from somewhere.

<ChannelModel Address="http://iagam-dev02.iagam.net:8090/Users.svc" Action="http://tempuri.org/IUsers/FindUsers" xmlns="http://microsoft.com/mse/2007/runtime/channelModel" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

</ChannelModel>

Nov 4, 2008 at 5:18 AM
I have a feeling that it may be because I have two service contracts which have the same method names in them.

[

ServiceContract]

 

[

ServiceKnownType(typeof(RoleEntity))]

 

[

ServiceKnownType(typeof(UserEntity))]

 

[

ServiceKnownType(typeof(UsersInRolesEntity))]

 

 

public interface IUsers

 

{

[

OperationContract]

 

 

EntityCollection<UserEntity> GetUsers(bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract]

 

 

EntityCollection<UserEntity> FindUsers(Guid id, string login, string name, bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract]

 

 

UserEntity GetUser(Guid id, bool withRoles);

 

}

and

 

[

ServiceContract]

 

[

ServiceKnownType(typeof(RoleDTO))]

 

[

ServiceKnownType(typeof(UserDTO))]

 

[

ServiceKnownType(typeof(UsersInRolesDTO))]

 

 

public interface IUsersDTO

 

 

 

 

{

[

OperationContract]

 

 

UserDTO[] GetUsers(bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract]

 

 

UserDTO[] FindUsers(Guid id, string login, string name, bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract]

 

 

UserDTO GetUser(Guid id, bool withRoles);

 

}

I am going to try changing the IUsersDTO interface to use different method names...we'll see how that goes.

Nov 4, 2008 at 5:55 AM
Ok, the issue is solved (more tidy up work required though...)

In the service contract, for each operation contract you can specify an action.  This caused the auto-gen'd proxy of the ChannelFactory<> class to populate that action instead for each operation.  So instead of the SOAP action being "http://tempuri.org/IUsers/FindUsers" the action is just "FindUsers".

This is what the class now looks like

[

ServiceContract]

 

[

ServiceKnownType(typeof(RoleEntity))]

 

[

ServiceKnownType(typeof(UserEntity))]

 

[

ServiceKnownType(typeof(UsersInRolesEntity))]

 

 

public interface IUsers

 

{

[

OperationContract(Action="GetUsers")]

 

 

EntityCollection<UserEntity> GetUsers(bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract(Action = "FindUsers")]

 

 

EntityCollection<UserEntity> FindUsers(Guid id, string login, string name, bool onlyEnabled, bool withRoles, bool minimal);

 

[

OperationContract(Action = "GetUser")]

 

 

UserEntity GetUser(Guid id, bool withRoles);

 

}

This just gets me wondering, if this will cause problems later on if I continue using the ChannelFactory so I can use strongly typed WCF services in my client apps?  Especially with respect to all the advantages that MSE gives with versioning, etc should I just put the version info into the OperationContract attribute _now_.