web service error ' it does not have a parameterless constructor ' - asp.net

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 ?

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 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)

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.

Related

No parameterless constructor defined for an imported object type to be deserialized from JSON

Dim result = New JavaScriptSerializer().Deserialize(Of SearchResult)(Request.Cookies.Get("user").Value)
An exception of type 'System.MissingMethodException' occurred in System.Web.Extensions.dll but was not handled in user code
Additional information: No parameterless constructor defined for type of 'System.DirectoryServices.SearchResult'.
I see there have been many questions regarding this issue, but the required object types were self-defined class, so the solution would be to create a new and parameterless constructor for that class.
In my case, I am trying to use SearchResult from namespace System.DirectoryServices as the object type to be deserialized from JSON String. How can I solve it?
You can't deserialise a SearchResult object because it has no public constructor.
In theory you could write a JavaScriptConverter and use reflection to instantiate an instance of the target class in the convertor's Deserialize() method but that would be hackery of the first order.
Either serialize and deserialize a custom class of your own making, or rethink what you're doing.

MapHttpRoute vs MapRoute for basic POST WebAPI

Given the following simple Web API (not part of an MVC project, just an empty ASP.NET site) which I've taken from a tutorial:
Public Class AwesomeController
Inherits ApiController
Public Function [Get]() As String
Return "Hello. The time is " & DateTime.Now.ToString
End Function
Public Function Post(<FromBody> yourName As String) As String
Return String.Format("Hi {0}, you posted here at {1}", yourName, DateTime.Now.ToString)
End Function
End Class
I am creating the Route within global.asax like this:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
GlobalConfiguration.Configuration.Routes.Add("default", New HttpRoute("{controller}"))
End Sub
This works fine, but I've read that WebAPI Routing should preferably be created using MapHttpRoute so that the service can exist in isolation. Is this true?
If so, can anyone post the code to replace my global.asax version?
Update
I figured out the last bit, but would still appreciate knowing whether there is a 'correct' way?
RouteTable.Routes.MapHttpRoute("default", "{controller}")
The MapHttpRoute extension method is simply a convenient way to register HttpRoute instances in your routing table. It's perfectly okay to manually create and register an HttpRoute without making use of the shorthand method, though.
If you want to understand the inner workings of MapHttpRoute, take a look at the source code: HttpRouteCollectionExtensions.cs.

Why does AutoCompleteExtender WebService fail to be called when function is Shared?

I had a problem (which is now fixed) but I've no idea why...
I have an Ajax AutoCompleteExtender with a WebService method to populate like
<WebMethod()> _
Public Shared Function populateACE(prefixText As String) As List(Of String)
However this didn't work - I put a breakpoint in, and it didn't even get hit. However...
<WebMethod()> _
Public Function populateACE(prefixText As String) As List(Of String)
..does work (the only difference being not Shared).
Fair enough, but why? If you have an instance of a class then you can access Shared methods of it; if you don't have an instance of a class then you can access Shared methods of it. So what is going on behind the scenes?
If you're calling a page method then it must be Shared/static. But when calling methods attached to asmx services, accordining to John Saunders in this question,
Why are Static Methods not Usable as Web Service Operations in ASMX Web Services?, web methods can't be Shared/static by design.
I'd have to guess that both are design limitations in the pipelines that retrieve pages vs. web methods.
To quote the relevant part from John Saunders' answer..
The answer is: because you can't.
It's not designed that way. The design is that an instance of the web
service class will be created, and then an instance method will be
called.
..but still worth having a look at the full answer.

JSON From ASMX Service

I'm trying to get a VB.NET ASMX web service to return raw JSON (without the .d). I've declared a plethora of attributes but still get XML back. The signature of my method is:
<WebInvoke(BodyStyle:=WebMessageBodyStyle.Bare, RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json, Method:="GET")>
<WebGet(BodyStyle:=WebMessageBodyStyle.Bare, ResponseFormat:=ResponseFormat.Json)>
<ScriptMethod(UseHttpGet:=True, ResponseFormat:=ResponseFormat.Json)>
<WebMethod()>
Public Function TryLogin(ByVal userName As String, ByVal passwordHash As String) As LoginResult
Am I missing a declaration?
EDIT: I've tried requesting via POST, but I still get XML.
I think your web method needs to return an object type.
Use attribute ScriptService on your web-service class.
Try putting <ScriptService> attribute on the class.
Add this line, on its own line, two spaces below your Imports statements:
<System.Web.Script.Services.ScriptService()> _
and immediately above the remaining code.

ASP.Net Webservice Serialization

Could someone here point me in the right direction about how I can override the serialization that occurs when my webservice is called?
Basically the end result I am aiming for is appending a TIMESTAMP to all objects returned from my webservice but only when the JavascriptSerializer is being used in my webservice as opposed to the XML serializer.
So for example below is a method that is contained in my webservice.
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json, UseHttpGet:=True)> _
Public Function GetSettingData(ByVal Username As String, ByVal Password As String) As SettingList
When the webservice is called (As a GET request) at some point the JavascriptSerializer is invoked and my objects parsed and outputted as JSON. I am assuming that somewhere during that invokation I can insert my own version of the JavascriptSerializer and do as required?
Anyone able to guide me here?
(PS: I am well aware that I can return strings from all my webservices and perform the serialization as required in the actual webmethod call but I am looking for a 'better' solution then that (besides that would mean I would need different methods if I wanted to return XML))
You can use Stream or Message classes as return types, then you can implement your custom serialization. See for example How to set Json.Net as the default serializer for WCF REST service as an example.

Resources