Bind Details view with class object - vb.net

How can I bind the details view and return a class object?
Dim _obj As New NewRequestDetailsBL
_obj = NewRequestDetailsBL.SelectRequestDetails(Session("requestid"),
Session("contactid"))
dvAdmin1.DataSource = _obj ' this line is giving the error
dvAdmin1.DataBind()
Error:
System.InvalidOperationException: Data source is an invalid type.
It must be either an IListSource, IEnumerable, or IDataSource.

The error contains every information you need!
It must be either an IListSource, IEnumerable, or IDataSource.
Your class has to implement at least one of these interfaces and then you'll be able to set DataSource to an instance of NewRequestDetailsBL class.

Related

Error - 'Unable to cast object of type 'System.Collections.Generic.List`1[]' to type 'System.Collections.Generic.IEnumerable`[]'.'

I am new to API's and I am developing one (trying to) in VB.net and have followed this video - https://www.youtube.com/watch?v=nMGlaiNBbNU. although I am using Visitors instead of employees.
I have translated the code to this - (From C# To VB)
Namespace Controllers
Public Class VisitorsController
Inherits ApiController
Public Function [Get]() As IEnumerable(Of Visitor)
Using entities As SignInSystemLiveEntities = New SignInSystemLiveEntities()
Return entities.pa_Visitors_GetOnSite.ToList()
End Using
End Function
End Class
End Namespace
although when i execute this i get the following error message:
System.InvalidCastException: 'Unable to cast object of type 'System.Collections.Generic.List1[VisitorsDA.pa_Visitors_GetOnSite_Result]' to type 'System.Collections.Generic.IEnumerable1[VisitorsDA.Visitor]'.'
Please Help
Many Thanks,
The List<T> class does implement the IEnumerable<T> interface, so that's not the problem. The issue is the item type. As the error message says, the method is supposed to return a list of VisitorsDA.Visitor objects but you're actually trying to return a list of VisitorsDA.pa_Visitors_GetOnSite_Result objects. Either get different objects to return or change the return type of the method, or else map the data between those two types somehow.

How to access properties of a class using Object type variable?

I have declared a "variable" of type OBJECT. I have also declared a class named TEST which has a property "name". My understanding is that in the statement variable = New test() the compiler is creating a new instance of the class TEST and storing the reference/memory address of that newly created instance in "variable". The idea is that an object type of variable should be able to store any type of data or its reference. By that logic using the member accessor operator I should be able to access the property "name" using "variable". But I am unable to. Can someone please explain why and how to access the property when the reference to the instance is being stored in an object type variable?
Module Program
Sub Main()
Dim variable As Object
variable = New test()
Console.WriteLine("Value: {0} Type: {1}", variable, variable.GetType())
'Output is Type: Object_Data_Type.test --> Works
'However we cannot access the property name of the class TEST through "varibale"
Console.ReadLine()
End Sub
End Module
Public Class test
Public Property name As String
End Class
Because an Object doesn't have a name property, and (on the outside) your variable looks like Object. If you want it to look like Test you'll have to cast it:
Console.WriteLine("Value: {0} Type: {1}", DirectCast(variable, Test).name, variable.GetType())

Entity Framework errors while saving base class if there is any inheritance

I am using EF 6.1. I have a model "Request" built from the wizard directly from my database. In my context file (EMContext.vb) I have
Public Overridable Property Requests As DbSet(Of Request)
When I type in
Dim db As New EMContext
Dim req As New Request()
With req
.RequestedBy = "bar"
.EventName = "Goo"
.RequestedOn = Now
.RequestStatusID = 1
End With
db.Requests.Add(req)
db.SaveChanges()
everything works exactly as expected. No problems. It saves.
However, if I add a class (anywhere in the app)
Class foo
Inherits Request
Public Property s As String
End Class
and then run the exact same code I get
{"An error occurred while updating the entries. See the inner exception for details."}
Looking at the inner exception:
{"Invalid column name 's'.
Invalid column name 'Discriminator'."}
Why in the heck is it even looking at the inherited class properties?
BTW, if I remove all the properties from the inherited class, I still get the Invalid Column 'Discriminator' error.
Then create a custom class that the json parses to and then you can call the Entity and make it from this class.
<Serializable()>
Public Class jSonParsedObject
'properties that match the Entity object
'custom properties you need for other work
End Class
Usage:
Dim jsonObj As jSonParsedObject = SomeMethodThatParsesAndReturnsData()
Dim req As New Request()
With req
.RequestedBy = jsonObj.RequestedBy
.EventName = jsonObj.EventName
.RequestedOn = jsonObj.RequestedOn
.RequestStatusID = jsonObj.RequestStatusID
End With
...

Why is this Entity Framework association not loading lazily?

I'm using a Code First Entity Framework approach, and in my OnModelCreating function I have the following code:
With modelBuilder.Entity(Of FS_Item)()
.HasKey(Function(e) e.ItemKey)
.Property(Function(e) e.ItemRowVersion).IsConcurrencyToken()
.HasMany(Function(e) e.ItemInventories) _
.WithRequired(Function(e) e.Item).HasForeignKey(Function(e) e.ItemKey)
End With
Elsewhere I have a Web API Get implementation with some diagnostic code I'm looking at in a debugger:
Public Function GetValue(ByVal id As String) As FS_Item
GetValue = If(data.FS_Item.Where(Function(i) i.ItemNumber = id).SingleOrDefault(), New FS_Item())
Dim c = GetValue.ItemInventories.Count
End Function
I expect that c should get a non-zero value by looking up rows in the FS_Inventory view where ItemKey matches the retrieved FS_Item row's ItemKey. But I'm getting 0 even though there are matching rows. Am I calling .HasMany, .WithRequired and .HasForeignKey properly?
Note that .WithRequired is operating on the return value from the previous line whereas the other lines are operating on the With block expression.
Edit This model for FS_Item has been requested. Here it is:
Partial Public Class FS_Item
Public Property ItemNumber As String
Public Property ItemDescription As String
Public Property ItemUM As String
Public Property ItemRevision As String
Public Property MakeBuyCode As String
' Many many more properties
Public Property ItemRowVersion As Byte()
Public Property ItemKey As Integer
Private _ItemInventories As ICollection(Of FS_ItemInventory) = New HashSet(Of FS_ItemInventory)
Public Overridable Property ItemInventories As ICollection(Of FS_ItemInventory)
Get
Return _ItemInventories
End Get
Friend Set(value As ICollection(Of FS_ItemInventory))
_ItemInventories = value
End Set
End Property
End Class
Edit Learned something interesting. If I change Dim c = GetValue.ItemInventories.Count to this:
Dim c = data.FS_ItemInventory.ToList()
Dim correctCount = GetValue.ItemInventories.Count
Then correctCount gets the value of 3. It's like it understands the association between the objects, but not how to automatically query them as I'm used to coming from LINQ-to-SQL. Is EF different somehow in this regard?
Edit I have determined that I can make the associated objects load using this explicit loading code:
data.Entry(GetValue).Collection(Function(e) e.ItemInventories).Load()
What I want to understand now is what exactly determines whether an entity will load lazily or not? From all indications I can find, it should have loaded lazily. I even tried changing the declaration of ItemInventories to this, but then I got a NullReferenceException when trying to access it:
Public Overridable Property ItemInventories As ICollection(Of FS_ItemInventory)
It turns out that code which I thought was unrelated had disabled lazy loading. I have this in the constructor of FSDB:
DirectCast(Me, IObjectContextAdapter).ObjectContext.ContextOptions.ProxyCreationEnabled = False
Thanks to EF 4 - Lazy Loading Without Proxies I see that this will also disable lazy loading. The reason that code had been added was due to another error:
Type
'System.Data.Entity.DynamicProxies.FS_Item_64115A45C642902D6044AFA1AFD239E7DCB82FD000A10FE4F8DE6EA26A2AB418'
with data contract name
'FS_Item_64115A45C642902D6044AFA1AFD239E7DCB82FD000A10FE4F8DE6EA26A2AB418:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies'
is not expected. Consider using a DataContractResolver or add any
types not known statically to the list of known types - for example,
by using the KnownTypeAttribute attribute or by adding them to the
list of known types passed to DataContractSerializer.
And according to Serialization of Entity Framework objects with One to Many Relationship, the easy solution for that was to disable proxies.

Adding Properties to WCF DataContract

I've added a service reference to my WCF webservice which generated all of my datacontract objects. I'm using BasicHttpBinding. Using a partial class, I've made one of these objects inherit from another class that adds some properties to it. Now it throws an error when making a call to the service:
Test method CP.Exg2010.Tests.UnitTest1.TestWCF threw exception:
System.ServiceModel.Dispatcher.NetDispatcherFaultException: The
formatter threw an exception while trying to deserialize the message:
There was an error while trying to deserialize parameter
http://tempuri.org/:RunResult. The InnerException message was 'Error
in line 1 position 283. 'Element' 'CommandResult' from namespace
'uri://mycomp.corp/line/exg2010' is not expected. Expecting element
'_EngineTracingData'.'. Please see InnerException for more details.
---> System.Runtime.Serialization.SerializationException: Error in
line 1 position 283. 'Element' 'CommandResult' from namespace
'uri://mycomp.corp/line/exg2010' is not expected. Expecting element
'_EngineTracingData'.
CommandResult is a property that is part of the WSDL. _EngineTracingData is the private field used by a property in a base class.
<XmlIgnore()> <SoapIgnore()> <Newtonsoft.Json.JsonIgnore()> _
Private _EngineTracingData As String = String.Empty
<XmlIgnore()> <SoapIgnore()> <Newtonsoft.Json.JsonIgnore()>
Public Property EngineTracingData As String Implements Interfaces.ICPMasterBaseInfo.EngineTracingData
Get
Return Me._EngineTracingData
End Get
Set(ByVal value As String)
Me._EngineTracingData = value
End Set
End Property
I read something about the deserialization happening in alphabetic order, which would explain why _EngineTracingData is first. But, that field/property shouldn't even be used in deserialization!
Any help would be appreciated!
Ah, I found it!
Adding
<NonSerialized()>
to the private fields in the base class fixed my issue!