Error while serializing datetime property - vb.net

When i include datetime property in object and return it in wcf service then it gives error status 12152. Without datetime property in my object it works fine. Datetime property content is #1/22/2016 12:08:36 PM#.
How to make it work with datetime property?
wcf call
function populateEditAuditResultData(AuditID) {
CallWCFService('DataService.svc/GetAuditCase',
'{"AuditID": "' + AuditID + '"}',
function (result) { //success
},
function (jQXHR, textStatus, errorThrown) { //failure
}
);
}
wcf service
<OperationContract()> _
Public Function GetAuditCase(ByVal AuditID As Integer) As AuditCase
Return New AuditCase(AuditID)
End Function
constructor
Public Sub New(ByVal AuditID As String)
Me.AuditID = AuditID
Me.GetData()
End Sub
Public Sub GetData()
Dim conn = New DatabaseConnection()
Dim params = New List(Of SqlParameter)
If AuditID <> Nothing Then params.Add(New SqlParameter("AuditID", Me.AuditID))
Dim table = conn.RunSprocQuery(ReferenceData.prc_GetAuditCaseDetails, params.ToArray())
If table.Rows.Count > 0 Then
ReadAuditCase(table.Rows(0), Me)
End If
End Sub
Private Shared Sub ReadAuditCase(ByVal row As DataRow, ByRef AudCase As AuditCase, Optional ByVal IncludeOptionalFields As Boolean = True)
AudCase.AuditID = CInt(row("AuditID"))
AudCase.AuditTypeID = CInt(row("AuditTypeID"))
AudCase.AllocationOn = Convert.ToDateTime(row("AllocationOn"))
End Sub

Ok solved the problem by changing the time zone to UTC.
Alternatively it can be solved by using following code.
AudCase.AllocationOn = Convert.ToDateTime(row("AllocationOn")).ToUniversalTime()
Hope this help others.

Related

Custom function(s) in LINQ to Entities? How to write acceptable code?

Use of my simple function causes app to exit all the nested Using blocks and returns control to very outer End Using statement. But built-in function works fine. How to bypass this strange situation?
Public Shared ReadOnly GlobalSettingsKeyList As New HashSet(Of String)
Public Shared Function IsGlobalSetting(key As String) As Boolean
Return GlobalSettingsKeyList.Contains(key)
End Function
What doesn't work:
Using db = powerEntities.Open()
dim userID = 1
dim dbSettingsFound = (From setting In db.SETTINGS
Where setting.idUsers = If(IsGlobalSetting(setting.Name), Nothing, userID)
Where setting.Name.Contains(keyToMatch)) _
.ToDictionary(Function(x) x.Name, Function(y) y.Value)
End Using
What works fine:
Using db = powerEntities.Open()
dim userID = 1
dim dbSettingsFound = (From setting In db.SETTINGS
Where setting.idUsers = If(GlobalSettingsKeyList.Contains(setting.Name), Nothing, userID)
Where setting.Name.Contains(keyToMatch)) _
.ToDictionary(Function(x) x.Name, Function(y) y.Value)
End Using
{"LINQ to Entities does not recognize the method 'Boolean IsGlobalSetting(System.String)' method, and this method cannot be translated into a store expression."}
Done! Thanks to Jarekczek's answer here and his LinqExprHelper
So there is a way!
Private Shared Function GetDefaultKey(key As String) As String
If key.Contains("Station") Then
Return $"default{key.Substring("Station")}" 'my String Extension
Else
Return $"default{key}"
End If
End Function
Public Shared Function GetDefaultKeyAndCompareSetting(ByVal key As String) As Expression(Of Func(Of Settings, Boolean))
key = GetDefaultKey(key)
Return LinqExprHelper.NewExpr(Function(u As Settings) u.Name.Equals(key))
End Function
used like this...
Shared Sub Example(key As String)
...
Dim masterExpr = LinqExprHelper.NewExpr(Function(u As Settings, ByVal formatCompare As String) (formatCompare))
Dim isSameAsDefKey = masterExpr.ReplacePar("formatCompare", GetDefaultKeyAndCompareSetting(key).Body)
Dim result = (From def In db.Settings
Where def.idUsers Is Nothing).
Where(CType(isSameAsDefKey, Expression(Of Func(Of Settings, Boolean)))).FirstOrDefault
...
End Sub
...works like a charm

Visual Basic API returns an exception error

I am trying to build a new leg in a WebAPI that I have written in visual basic. The code I am trying to execute is this:
Public Class getDatabaseDataController
Inherits ApiController
Private product_information As getDatabaseData() = New getDatabaseData() _
{New getDatabaseData() With {
.return_response = "return response"
}}
Public Function GetCars(<FromUri> ByVal dbRequest As String) As IEnumerable(Of getDatabaseData)
Dim return_string As String = ""
Dim passedData As String = dbRequest
return_string = passedData
Dim mqResponse As getDatabaseData() = New getDatabaseData() _
{New getDatabaseData() With {
.return_response = Str(return_string)
}}
'Return product_information
Return mqResponse
End Function
End Class
I have a public class called getDatabaseData defined as follows:
Public Class getDatabaseData
Private _Return_Response As String
Public Property return_response() As String
Get
Return _Return_Response
End Get
Set(value As String)
_Return_Response = value
End Set
End Property
End Class
I call the API with this call:
http://localhost:12976/api/getDatabaseData?dbRequest=A
All I am trying to do at this point is have the API return the value A. When I debug the API and send in the request, this is what is returned:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Argument 'Number' cannot be converted to a numeric value.
</ExceptionMessage>
<ExceptionType>System.InvalidCastException</ExceptionType>
I dont see anything in the code that would indicate a 'Numeric'. What am I missing?
Thanks in advance for any assistance.

Why is this returning Index out of bound exception

When I get to the Read loop I get an index out of bounds error. I think its on the reader ordinal value, but I am not sure why I am getting it.
Private Function Create(Reader As SqlDataReader) As IEnumerable(Of MyObject)
SetOrdinals(MyObjectReader)
Dim MyObjects = New List(Of MyObject)
While MyObjectReader.Read()
Dim Temp = New MyObject() With {
.FirstValue = MyObjectReader.GetValue(Of Integer)(MyObjectReader(FirstValue_Ord)),
.SecondValue = If(MyObjectReader.GetValue(Of String)(MyObjectReader(SecondValue_Ord)), String.Empty).Trim(),
.ThirdValue = If(MyObjectReader.GetValue(Of String)(MyObjectReader(ThirdValue_Ord)), String.Empty).Trim(),
MyObjects.Add(Temp)
End While
Return MyObjects
End Function
Private Sub SetOrdinals(MyObjectReader As SqlDataReader)
FirstValueOrd = MyObjectReader.GetOrdinal("FirstValue")
SecondValue_Ord = MyObjectReader.GetOrdinal("SecondValue")
ThirdValue_Ord = MyObjectReader.GetOrdinal("ThirdValue")
End Sub
End Class
Public Module Extensions
<Extension>
Function GetValue(Of T)(rdr As SqlDataReader, i As Integer) As T
If rdr.IsDBNull(i) Then
Return Nothing
End If
Return DirectCast(rdr.GetValue(i), T)
End Function
End Module
You should just be passing in the ordinal to the GetValue calls:
While MyObjectReader.Read()
Dim Temp = New MyObject() With {
.FirstValue = MyObjectReader.GetValue(Of Integer)(FirstValue_Ord),
.SecondValue = If(MyObjectReader.GetValue(Of String)(SecondValue_Ord), String.Empty).Trim(),
.ThirdValue = If(MyObjectReader.GetValue(Of String)(ThirdValue_Ord), String.Empty).Trim()
}
MyObjects.Add(Temp)
End While
Here my version :)
Private Function Create(reader As SqlDataReader) As IEnumerable(Of MyObject)
Dim objects As New List(Of MyObject)()
Dim ordinals As New Ordinals(reader)
While reader.Read()
Dim Temp As New MyObject With
{
.FirstValue = reader.GetValueOrDefault(Of Integer)(ordinals.FirstValue),
.SecondValue = reader.GetValueOrDefault(ordinals.SecondValue, "").Trim(),
.ThirdValue = reader.GetValueOrDefault(ordinals.ThirdValue, "").Trim()
}
objects.Add(Temp)
End While
Return MyObjects
End Function
Private Class Ordinals
Public Property FirstValue As Integer
Public Property SecondValue As Integer
Public Property ThirdValue As Integer
Public Sub New(reader As SqlDataReader)
FirstValue = reader.GetOrdinal(nameOf(FirstValue))
SecondValue = reader.GetOrdinal(nameOf(SecondValue))
ThirdValue = reader.GetOrdinal(nameOf(ThirdValue))
End Sub
End Class
Public Module Extensions
<Extension>
Function GetValueOrDefault(Of T)(reader As SqlDataReader, ordinal As Integer) As T
Return reader.GetValueOrDefault(Of T)(ordinal, Nothing)
End Function
<Extension>
Function GetValueOrDefault(Of T)(reader As SqlDataReader,
ordinal As Integer,
defaultValue As T) As T
Dim value = reader(ordinal)
If value = DbNull.Value Then
Return defaultValue
End If
Return DirectCast(value, T)
End Function
End Module
Because extension method execute checking for DbNull.Value against already extracted object, we get rid from reading same value twice from SqlDataReader.
SqlDataReader.IsDbNull(index) reads value before checking for DbNull.
Extension method have two overloads:
- One which return default value of given type, if value is DbNull.Value. Nothing in vb.net is default value of type.
- And one which takes parameter for default value you want return if value is DbNull.Value. Possibility pass default value makes lines where you create new object shorter and more readable. We get rid of inline if statement.
Your extension method with name GetValue have "side effects". By name consumer of this method expect to get value from SqlDataReader. So he can expect to get DbNull.Value if database query return NULL, but instead he get null for string or 0 for integer. Name GetValueOrDefault is little bid more informative, so you don't need to go inside method to check what is doing.

Consume Equals instead of Contains

I got two following class:
Class Part:
Imports System.Collections.Generic
Public Class Part
Implements IEqualityComparer(Of Part)
Public Sub New()
End Sub
Public Property _comparisonType As EqualsComparmission
Public Sub New(ComparisonType As EqualsComparmission)
Me._comparisonType = ComparisonType
End Sub
Public Property PartName() As String
Public Property PartId() As Integer
Public Function Equals1(x As Part, y As Part) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Part).Equals
If x Is Nothing AndAlso y Is Nothing Then Return True
If x Is Nothing OrElse y Is Nothing Then Return False
Select Case _comparisonType
Case EqualsComparmission.PartId
Return x.PartId = y.PartId
Case EqualsComparmission.PartName
Return String.Equals(x.PartName, y.PartName)
Case EqualsComparmission.PartId_and_PartName
Return x.PartId = y.PartId AndAlso String.Equals(x.PartName, y.PartName)
Case Else
Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
End Select
End Function
Public Function GetHashCode1(obj As Part) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Part).GetHashCode
Select Case _comparisonType
Case EqualsComparmission.PartId
Return obj.PartId
Case EqualsComparmission.PartName
Return If(obj.PartName Is Nothing, 0, obj.PartName.GetHashCode())
Case EqualsComparmission.PartId_and_PartName
Dim hash = 17
hash = hash * 23 + obj.PartId
hash = hash * 23 + If(obj.PartName Is Nothing, 0, obj.PartName.GetHashCode())
Return hash
Case Else
Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
End Select
End Function
Public Overrides Function ToString() As String
Return "ID: " & PartId & " Name: " & PartName
End Function
End Class
Class PartCollection:
Public Class PartsCollection
Implements ICollection(Of Part)
Public Property _comparisonType As EqualsComparmission
Private myList As List(Of Part)
Public Sub New()
If myList Is Nothing Then
myList = New List(Of Part)
End If
End Sub
Public Sub New(ComparisonType As EqualsComparmission)
If myList Is Nothing Then
myList = New List(Of Part)
End If
Me._comparisonType = ComparisonType
End Sub
Public Sub Add(item As Part) Implements ICollection(Of Part).Add
myList.Add(item)
End Sub
Public Sub Clear() Implements ICollection(Of Part).Clear
myList.Clear()
End Sub
Public Sub CopyTo(array() As Part, arrayIndex As Integer) Implements ICollection(Of Part).CopyTo
End Sub
Public Function GetEnumerator() As IEnumerator(Of Part) Implements IEnumerable(Of Part).GetEnumerator
Return New PartsEnumeration(myList)
End Function
Public ReadOnly Property Count As Integer Implements ICollection(Of Part).Count
Get
Return myList.Count
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Part).IsReadOnly
Get
Return False
End Get
End Property
Public Function Remove(item As Part) As Boolean Implements ICollection(Of Part).Remove
Return myList.Remove(item)
End Function
Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
Return New PartsEnumeration(myList)
End Function
Public Function Contains(item As Part) As Boolean Implements ICollection(Of Part).Contains
Select Case _comparisonType
Case EqualsComparmission.PartId
Return myList.Exists(Function(x) x.PartId = item.PartId)
Case EqualsComparmission.PartName
Return myList.Exists(Function(x) x.PartName = item.PartName)
Case EqualsComparmission.PartId_and_PartName
Return myList.Exists(Function(x) x.PartId = item.PartId And x.PartName = item.PartName)
Case Else
Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
End Select
End Function
End Class
I would like to use Equals1 from Part class instead as code is doing right now and using Contains1 from PartsCollection. I would like to ask you what i have to do in this case? My current code is working but i would like to switch to Equals1 as i created it earlier.
This is test code:
Dim myParts As New PartsCollection
Dim John As New Part With { _
.PartName = "John", _
.PartId = 1 _
}
Dim Silva As New Part With { _
.PartName = "Silva", _
.PartId = 2 _
}
Dim Jimmy As New Part With { _
.PartName = "Jimmy", _
.PartId = 3 _
}
Dim James As New Part With { _
.PartName = "James", _
.PartId = 4 _
}
myParts.Add(John)
myParts.Add(Silva)
myParts.Add(Jimmy)
myParts.Add(James)
Console.WriteLine("SEARCHING FOR CONCRETE PART IF EXIST")
myParts._comparisonType = EqualsComparmission.PartId_and_PartName
Dim p As Boolean = myParts.Contains(New Part() With { _
.PartName = "James", _
.PartId = 45 _
})
The reason for having functionality in one place or another is usually based on where it is needed or most useful rather than when it was written. You can of course, copy the code to whereever you like.
One problem in the current state is that you are have what should be a method argument defined as a Property. The comparisonType will need to be set each time you use it so that you can be sure it is set to what it should be. Secondly, since it is critical to the compare operation, you should want to see what is being used.
Calling Equals/Contains or whatever else on the collection class does not rule out using the method on the item class. To use it from a collection class:
Public Overloads Function Contains(p As Part,
compare As EqualsComparmission) As Boolean
Dim query = Items.Where(Function(f) p.Equals(f, compare)).ToList
Return query.Count <> 0
End Function
Usage:
If myParts.Contains(newP, EqualsComparmission.PartId_and_PartName) Then
The functionality for comparing exists in the Part Item class, the collection simply calls it. This also allows you to do:
If part1.Equals(part2)
The more important thing to note is that the comparison mode to use is passed as an argument, specifying which mode to use for this comparison. The actual query used would depend on what you need to know.

Getting a "Type Error" in vb.net code converted from C#

I have this code in VB.Net 2010 and I am getting a "type Error" on New().
This code was converted from C#.
What am I doing wrong?
Public Function CredentialGet(ByVal sKey As String, ByRef sCred As String)
Dim sCredential As Element.Credential
sCredential = apiclient.SearchCredentials(sSoftwareKey, SessionID,
New() {New Element.SearchTerm() With {.FilterKey = "APK", .Value = sKey}})
sCred = sCredential.CredentialID
End Function
New() what? You are missing an object name there. You're now passing in an anonymous object.
Remove the parentheses for the anonymous type. VB.Net does not use them in that context, but looks for the With keyword instead. And functions should return a value. You don't return anything, so use a Sub:
Public Sub CredentialGet(ByVal Key As String, ByRef Cred As String)
Dim Credential As Element.Credential
Credential = apiclient.SearchCredentials(sSoftwareKey, SessionID, _
New With {New Element.SearchTerm() With {.FilterKey = "APK", .Value = Key}})
Cred = Credential.CredentialID
End Sub
I also question this design. It would be better to return a string:
Public Function CredentialGet(ByVal Key As String) As String
Return apiclient.SearchCredentials(sSoftwareKey, SessionID, _
New With {New Element.SearchTerm() With {.FilterKey = "APK", .Value = Key}}).CredentialID
End Function