1

I've created a web service , which can a method to set the user credential using Microsoft.Web.Services3.WebServicesClientProtocol. The sample code is :

<WebMethod()> _
    Public Sub ClientCredential1(Of TSecurityToken As SecurityToken)_
         (ByVal UserCred As Microsoft.Web.Services3.Security.Tokens.UsernameToken)

        Dim cProxy As New Microsoft.Web.Services3.WebServicesClientProtocol()
        cProxy.SetClientCredential(UserCred)
    End Sub

When I run the web service it gives this error:

"Microsoft.Web.Services3.Security.Tokens.UsernameToken cannot be serialized because it does not have a parameterless constructor."

Does any one know where is the problem ?

p.campbell
  • 98,673
  • 67
  • 256
  • 322
Saad
  • 1,312
  • 5
  • 17
  • 40
  • Hey! Welcome to StackOverflow! If you'd like to format you posts so they are more readable and more likely to be answered, please read the [StackOverflow Markup Guide](http://stackoverflow.com/editing-help). Good Luck with your Question! – Tyler Carter Aug 07 '10 at 05:35
  • I take it to mean that to initialize or create a new variable of type UserCred, you must send something along with the New() constructor. IE, Dim myCreds as new userCred(param1, param2). Since I don't know for sure, I am not posting this as an answer, but I would start there. – Tommy Aug 07 '10 at 06:09

3 Answers3

2

The root of the problem here is that the class Microsoft.Web.Services3.Security.Tokens.UsernameToken doesn't have a parameter-less constructor. It's got 3 of them, but they all demand a parameter. UsernameToken constructors on MSDN.

  • UsernameToken (XmlElement)
  • UsernameToken (String, String)
  • UsernameToken (String, String, PasswordOption)

The problem is that during deserialization, XmlSerializer calls the parameterless constructor to create an instance of that class. It can't deserialize a type that doesn't have a parameterless constructor.

I get the sense there's not much you can do to work around this problem. I'd only suggest creating a partial class, and implementing that zero-param constructor yourself.

'ensure namespacing is correct.
Public Partial Class UsernameToken
    Public Sub New()
    End Sub    
End Class
p.campbell
  • 98,673
  • 67
  • 256
  • 322
  • 1
    Since UsernameToken is defined in a referenced assembly, I don't think you can add a constructor using a partial class definition... I think that only works when you have the source code for all parts of the class. – Richard Beier Aug 07 '10 at 06:36
  • @Richard: I figured as much. It was a long shot. – p.campbell Aug 07 '10 at 06:48
0

p. campbell is right, it's because the XmlSerializer requires a parameterless constructor.

I don't know WSE, but from looking at this post on Aleem's Weblog, I don't think the UsernameToken is supposed to be passed as a regular argument to a web method - it's supposed to be passed in the WS-Security SOAP headers. You get the proxy to pass it in the headers by calling SetClientCredential(). Here's the example from the above blog post:

Dim oService As New WSETestService.ServiceWse

Dim U As New UsernameToken(“<User_Name>”, “<Password>”, PasswordOption.SendHashed)
oService.SetClientCredential(U)
Richard Beier
  • 1,712
  • 20
  • 25
0

You can't use a parameter of the type Microsoft.Web.Services3.Security.Tokens.UsernameToken in a web service, as it's not possible to serialise (or more specifically not possible to deserialise).

Create a class that just contains the data that you need to create a UsernameToken and use as parameter type. The client side would not create a real UsernameToken object anyway, there is a proxy class created from the WSDL information.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005