Hi I need to create a class for return the data in WCF service. I followed the web at 5 simple steps to create your first RESTful service. However I get the error for . I searched the web and add the System.Runtime.Serialization.DataContractSerializer, Would someone tell me what should do. I am using VS2015 as the tool to build it. Thanks.
Imports System.Runtime.Serialization
Imports System.Collections.Generic
Imports System.Runtime.Serialization.DataContractSerializer
<DataContract>
Public Class Locations
<DataMember>
Public Property LocationName As String
<DataMember>
Public Property LocationID As Integer
End Class
Could you please share the error details with me?
As you know, we usually use the datacontract to transmit the complex data type which could be recognized by the client-side and server-side. so that the data could be serialized and transmitted normally between different platforms.
For the restful web service in WCF, we need to use the Webhttpbinding build the data channel and add the Webhttpbehavior to the service endpoint.
I have made a demo, wish it is useful to you.
Server-side.
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
Module Module1
Sub Main()
Dim uri As New Uri("http://localhost:900")
Dim binding As New WebHttpBinding()
binding.CrossDomainScriptAccessEnabled = True
binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
Using sh As New ServiceHost(GetType(MyService), uri)
Dim se As ServiceEndpoint = sh.AddServiceEndpoint(GetType(IService), binding, uri)
se.EndpointBehaviors.Add(New WebHttpBehavior())
sh.Open()
Console.WriteLine("Service is ready")
Console.ReadLine()
sh.Close()
End Using
End Sub
<ServiceContract([Namespace]:="mydomain")>
Public Interface IService
<OperationContract>
<WebGet(ResponseFormat:=WebMessageFormat.Json)>
Function SayHello() As List(Of Product)
End Interface
Public Class MyService
Implements IService
Public Function SayHello() As List(Of Product) Implements IService.SayHello
Dim result = New List(Of Product)() From {
New Product With {
.Id = 1,
.Name = "Apple"
},
New Product With {
.Id = 2,
.Name = "Pear"
}
}
Return result
End Function
End Class
<DataContract([Namespace]:="mydomain")>
Public Class Product
<DataMember>
Public Property Id() As Integer
<DataMember>
Public Property Name() As String
End Class
End Module
Client.
$(function(){
$.ajax({
type:"GET",
url:"http://10.157.18.188:900/sayhello",
dataType:"jsonp",
success:function(d){
$.each(d,function(i,o){
console.log(o.Id);
console.log(o.Name);
})
}
})
})
Result.
Here is an official sample
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-wcf-web-http-service
Related
I have a class module in my App_code folder.
Private _connection As MySqlConnection
Private _connStr As String
Public Function Connect(dbName As String) As Boolean
Try
_connStr = "Database=" & dbName & ";" & _
"Data Source=192.16.0.1;" & _
"User Id=user;Password=pass"
_connection = New MySqlConnection(_connStr)
_connection.Open()
_connection.Close()
Return True
Catch ex As Exception
_connection = Nothing
Return False
End Try
Return False
End Function
I usually program in webform apps. Why can't I access this function from my aspx code behind pages? I added the import statement for the class. If i make that function shared I cant have those private variables.
I call the function in my aspx lik so;
If Connect(dbName) then....
That gets me an error "non shared member requires an object reference"
You need to add the keyword "Shared" to the method signature, like so:
Private Shared _connection As MySqlConnection
Private Shared _connStr As String
Public Shared Function Connect(dbName As String) As Boolean
This is because otherwise you have instance class members, not static members. The compiler error message is quite self-explanatory.
if you look at this example works:
Public Shared Function example123(ByVal USER As Integer, ByVal Section As String, ByVal ACTION As String) As Boolean
you assign a function shared so you can see it from outside the class
I hope you work
I'm not sure if this is possible but I would like to associate a class name reference to a shared member method / property / variable. Consider:
Public Class UserParameters
Public Shared Reference As Object
Public Shared Function GetReference() As Object
Return Reference
End Function
End Class
In another part of the program I would like to simply call UserParameters and have it return Reference either by aliasing GetReference or the variable directly.
I am trying to emulate the Application, Request, or Session variable:
Session(0) = Session.Item(0)
Any suggestions would be greatly appreciated.
You can't return an instance member from a static method directly (the static method can't access instance members because it isn't instantiated with the rest of the class, only one copy of a static method exists).
If you need to setup a class in such a way that you can return an instance from a static method you would need to do something similar to the following:
Public Class SampleClass
Private Sub New()
'Do something here
End Sub
Public Shared Function GetSample() As SampleClass
Dim SampleClass As SampleClass
SampleClass = New SampleClass
SampleClass.Sample = "Test"
Return SampleClass
End Function
Private _SampleString As String
Public Property Sample As String
Get
Return _SampleString
End Get
Private Set(ByVal value As String)
_SampleString = value
End Set
End Property
End Class
Public Class SampleClass2
Public Sub New()
'Here you can access the sample class in the manner you expect
Dim Sample As SampleClass = SampleClass.GetSample
'This would output "Test"
Debug.Fail(Sample.Sample)
End Sub
End Class
This method is used in various places in the CLR. Such as the System.Net.WebRequest class. where it is instantiated in this manner in usage:
' Create a request for the URL.
Dim request As WebRequest = WebRequest.Create("http://www.contoso.com/default.html")
In my ASP.NET Web Service I've included a module in which their are Public declared variables. Will they be thread-safe? Will they get mixed up upon simultaneous calls?
Those variables are mostly DatsSet, DataTable and SQLDataAdapter..
Partial code of the module:
Imports System.Data.OleDb
Imports System.Diagnostics
Module modCommon
Public bDoLog As Boolean
Public sCurrentODBC As String
Public cn As SqlConnection
Public Query1ds As DataSet
Public Query1 As DataTable
Public Query1adapter As SqlDataAdapter
#scripni
Thanks, as I'm not familiary with your suggestions, I will move everything locally.
Additionally, will the following variables be thread-safe?:
[ToolboxItem(False)]_
Public Class Service1
Inherits System.Web.Services.WebService
Dim sName As String
Dim sCurrentPath As String
[WebMethod()]_
Public Function Capture(ByVal sPath As String) As String
sName = "Joe"
End Function
End Class
If you're using web services than yes, you will have concurency problems when multiple services will try to access the same resource, and SqlConnection is definetly a resource you don't want shared.
You should make sure that you don't have simultaneous calls to the properties (for ex. by wrapping the fields with getters / setters and implementing locks in those methods) or by moving the code to a class and instantiating that class whenever you need it.
I grabbed an example off of this SO question, and built my own custom Google Maps object used for deserializing the json object.
Now the code works like a champ, but I just need an explanation on why/how it works. Does the serializer "try" to match up names, or is something else going on.
What exactly is this doing?
Here's the working code.
Imports System.Net
Imports System.Web
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Web.Script.Serialization
Namespace Utilities.Apis
Public NotInheritable Class GoogleGeolocate
Private Const googleUrl As String = "http://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false"
Private Sub New()
End Sub
Public Shared Function GetLatLon(ByVal address As String) As String
''# This is just here to prevent "placeholder" data from being submitted.
If address = "6789 university drive" Then
Return Nothing
End If
address = HttpUtility.UrlEncode(address)
Dim url = String.Format(googleUrl, address)
Dim request = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate")
request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
Dim serializer As New DataContractJsonSerializer(GetType(GoogleResponse))
Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), GoogleResponse)
Dim resources As GoogleResponse.Result = res.results(0)
Dim point = resources.geometry.location.lat
Dim latlon As New GeolocationLatLon
With latlon
.latitude = resources.geometry.location.lat
.longitude = resources.geometry.location.lng
End With
Dim jsonSerializer = New JavaScriptSerializer
Return jsonSerializer.Serialize(latlon)
End Function
End Class
<DataContract()>
Public Class GoogleResponse
<DataMember()>
Public Property results() As Result()
<DataContract()>
Public Class Result
<DataMember()>
Public Property geometry As m_Geometry
<DataContract()>
Public Class m_Geometry
<DataMember()>
Public Property location As m_location
<DataContract()>
Public Class m_location
<DataMember()>
Public Property lat As String
<DataMember()>
Public Property lng As String
End Class
End Class
End Class
End Class
End Namespace
And here's the GeolocationLatLon Poco
Public Class GeolocationLatLon
Public latitude As String
Public longitude As String
End Class
When I call the code, it's really quite simple.
note, this is an MVC controller, that has nothing to do "really" with the question other than to show what I'm doing
Function GeoLocation(ByVal address As String) As ContentResult
Return New ContentResult With {.Content = GoogleGeolocate.GetLatLon(address),
.ContentType = "application/json"}
End Function
And the final result is
{"latitude":"50.124300","longitude":"-114.4979990"}
Internally, DataContractJsonSerializer maps JSON name/value pairs to an XML infoset. In fact, DataContractJsonSerializer is built on top of the XML-based DataContractSerializer and processes every JSON input and JSON output as if it were dealing with XML. There is a higher-level abstraction layer (a JSON writer and a JSON reader, as exposed via JsonReaderWriterFactory) that actually translates this XML to JSON and JSON back to internal XML.
See this excellent overview (Mapping Between JSON and XML) to see what happens to DataContractJsonSerializer internally and how it pulls all this off.
I have had several occasions recently to access a specific class several times over a relatively small time frame.
So I've been storing the value of the class in Session and trying to access it on page load, if it's not available creating a new instance and storing that in session.
So instead of constantly replicating the same code for different classes on different pages I'm trying to create an extension method to do this for me.
I want to use it like this
Dim objName as MyClass
objName.SessionSingleton()
So far this is what I have for my extension method:
<Extension()> _
Public Sub SessionSingleton(ByRef ClassObject As Object)
Dim objType As Type = ClassObject.GetType
Dim sessionName As String = objType.FullName
If TypeOf HttpContext.Current.Session(sessionName) Is objType And HttpContext.Current.Session(sessionName) <> "" Then
ClassObject = HttpContext.Current.Session(sessionName)
Else
Dim singleton As Object = New objType???????
HttpContext.Current.Session(sessionName) = singleton
ClassObject = singleton
End If
End Sub
I'm stuck on what to do when I make my new instance of my class (it would have to have a New() sub)
I'm not sure where to go from here... or even if this is the best way to do it.
I figured it out and am posting my code for reference. While digging thru pages about Class/Object Factories (thanks RBarry) I found several references to Activator.CreateInstance() in the System.Reflection Class I came up with this.
Imports Microsoft.VisualBasic
Imports System.Runtime.CompilerServices
Imports System.Reflection
Public Module enviornmentUtilities
<Extension()> _
Public Function SessionSinglton(ByVal objType As Type) As Object
Dim sessionName As String = objType.FullName.ToString
If Not HttpContext.Current.Session(sessionName) Is Nothing Then
HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString)
Return HttpContext.Current.Session(sessionName)
Else
Dim ss = Activator.CreateInstance(objType)
HttpContext.Current.Session(sessionName) = ss
Return ss
End If
End Function
End Module
This will let you create a session based singleton from any class that does not require parameters in the new method (which isn't required for this to work)
To test I made a simple Class:
Public Class HasNew
Public FreshInstance As Boolean = True
Public Sub New()
HttpContext.Current.Trace.Warn("This Class has a new method")
End Sub
Public Sub CheckFreshness()
If FreshInstance Then
HttpContext.Current.Trace.Warn("Fresh HasNew Instance")
FreshInstance = False
Else
HttpContext.Current.Trace.Warn("NotFresh HasNew Instance")
End If
End Sub
Public Shared Function type() As Type
Return GetType(HasNew)
End Function
Public Shared Function SessionSinglton() As HasNew
Return GetType(HasNew).SessionSinglton
End Function
End Class
You'll notice the two Public Shared Methods type() and SessionSinglton which calls the above extension method.
With those two functions added we have three ways to initiate the Session Singlton demonstrated here:
Dim HN As HasNew
HN = HasNew.SessionSinglton
HN.CheckFreshness()
HN = HasNew.type.SessionSinglton
HN.CheckFreshness()
HN = GetType(HasNew).SessionSinglton
HN.CheckFreshness()
The Trace Output for this file is as follows:
This Class has a new method
Fresh HasNew Instance
NotFresh HasNew Instance
NotFresh HasNew Instance
The classes new() method is accessed on the first call to the SessionSinglton method and subsequent calls reflect that the instance is in fact being pulled from memory.
I hope this helps someone else in the future.
If you used generics you could just do New T(). Also your SessionSingleton returns "object" type, requiring casting. I did not test this but it should work.
Imports Microsoft.VisualBasic
Imports System.Runtime.CompilerServices
Imports System.Reflection
Public Module enviornmentUtilities
<Extension()> _
Public Function SessionSinglton(Of T As {Class, New})(ByVal obj As T) As T
Dim sessionName As String = obj.GetType.Name
If Not HttpContext.Current.Session(sessionName) Is Nothing Then
HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString)
Return HttpContext.Current.Session(sessionName)
Else
Dim ss = New T()
HttpContext.Current.Session(sessionName) = ss
Return ss
End If
End Function
End Module