Not understanding Viewmodels in mvc I am using vb.net to see if it will help me understand it better

App Dev 86 Reputation points
2022-04-21T18:53:44.52+00:00

Hi All I am having trouble wrapping my heard around view models.
I have tried lots of tutorials to try to understand them and how to use them but nothing makes any since as there in nothing that shows you how to populate your database from the view model.

Not matter what language I use c sharp or VB.net the errors do not tell you how o fix the issue.

So my issue, I have a table in the database called CODE_OPINION_TBL

195295-image.png

The Create Form used a view model called : ViewModelClass_CodeOpinions

Here is the view model:

Imports System.ComponentModel.DataAnnotations  
Imports BFR_LOCAL_DB  
  
Public Class ViewModelClass_CodeOpinions  
  
  
  
    Public Property ID() As Integer  
    Public Property Code_Reference() As String  
    Public Property Chapter() As String  
    Public Property Section() As String  
    Public Property Response_Date() As Nullable(Of Date)  
    Public Property Year() As String  
    Public Property Status() As String  
    Public Property Author() As String  
    Public Property From() As String  
    Public Property Locality() As String  
    Public Property Description() As String  
    Public Property Comments() As String  
    Public Property Attachments() As String  
  
    Public Property ATTACHMENT_LINK As String  
  
    Public Property CODE_REF_REC_ID() As Integer  
    'Public Property CODE_REF_ID() As String  
  
    Public Property CODE_REF_ID As Nullable(Of Short)  
  
    Public Property CODE_DESCRIPTION() As String  
    Public Property CODE_REF_CAT() As String  
  
    <Required>  
    <DataType(DataType.Upload)>  
    <Display(Name:="Select File")>  
    Public Property files As HttpPostedFileBase  
  
    Public Property FILE_ID As Integer  
  
    <Display(Name:="Uploaded File")>  
    Public Property FILE_NAME As String  
    Public Property FILE_CONTENT As Byte()  
    Public Property FILE_RECORD_ID As Integer  
  
    Public Property CODE_REF_LIST() As List(Of CODE_REF_LOV_TBL)  
  
    'Public Shared Widening Operator CType(v As ViewModelClass_CodeOpinions) As ViewModelClass_CodeOpinions  
    '    Throw New NotImplementedException()  
    'End Operator  
End Class  

So when I change the controller to use the view model I get this error
195322-image.png

Severity Code Description Line
Error BC30311 Value of type 'ViewModelClass_CodeOpinions' cannot be converted to 'CODE_OPINIONS_TBL'. 212

Why does the program allow us to make view models if we can't use them or populate the database with them
I understand that they are just a mask like thing that allow you to setup you view to use data but I can't find any real world example that make use of them
in an understandable way.

If I leave this as CODE_OPINION_TBL it works fine even though the create views use the ViewModelClass_CodeOpinions
I just don't get it!

195285-image.png

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,541 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Michael Taylor 55,481 Reputation points
    2022-04-21T20:48:45.047+00:00

    Viewmodels and DBs have nothing to do with each other. That's your first problem, you're trying to make them related. If you're using a viewmodel in your UI then you'll need to map your DB structures to it before passing it to the client and any models that come back from the client need to be converted back to whatever structure your data layer requires. You have to write this mapping yourself (or use a third party mapping tool like Automapper). For simple apps viewmodels may be overkill but as apps get larger viewmodels become very useful for maintainability.

    Public Class CODE_OPINION_TBL
         Public Property ID() As Integer
         Public Property Chapter() As String
         Public Property Section() As String
    End Class
    
    Public Class ViewModelClass_CodeOpinions            
         Public Property ID() As Integer
         Public Property Chapter() As String
         Public Property Section() As String
    End Class
    
    ' I prefer to use extension methods or mapper classes for conversion '
    Public Shared Class CodeOpinionMapper
        <Extension()>
        Public Shared Function ToViewModel ( data As CODE_OPINION_TBL ) As ViewModelClass_CodeOpinions
           Dim model As new ViewModelClass_CodeOpinions
           With model
              .ID = data.ID
              .Chapter = data.Chapter
              .Section = data.Section
           End With
           Return model
        End Function
    
        <Extension()>
        Public Shared Function ToData ( model As ViewModelClass_CodeOpinions ) As CODE_OPINION_TBL
           Dim data As new CODE_OPINION_TBL
           With data
              .ID = model.ID
              .Chapter = model.Chapter
              .Section = model.Section
           End With
           Return data
        End Function
    End Class
    
    Dim data As New CODE_OPIONION_TBL
    Dim model = data.ToViewModel()
    Dim newData = model.ToData()
    

    To be honest your specific example isn't complex enough to justify viewmodels so it is hard to see the benefit. The primary benefit of a viewmodel (or any mapping) is to reformat the underlying data into a structure that can be more easily processed by whoever you're handing it to (a view in this case). A more complex example may make this clearer.

    Public Class StateOrProvince
        Public Property ID() As Integer
        Public Property Name() As String
    
        'Typically a data model has an ID and the corresponding object, if any '
        Public Property CountryID() As Integer
        Public Property Country() As Country
    End Class
    
    Public Class Country
        Public Property ID() As Integer
        Public Property Name() As String
    End Class
    
    Public Class StateOrProvinceViewModel
        Public Property ID() As Integer
        Public Property Name() As String
    
        'Flatten country information '
        Public Property CountryId() As Integer
        Public Property CountryName() As String
    End Class
    
    Public Shared Class StateOrProvinceMapper
        <Extension()>
        Public Shared Function ToViewModel ( state As StateOrProvince ) As StateOrProvinceViewModel
           Dim model As New StateOrProvinceViewModel()
           With model
               .ID = state.ID
               .Name = state.Name
           End With
    
           If state.Country Is Not Nothing Then
              model.CountryID = state.Country.ID
              model.CountryName = state.Country.Name.ToUpperCase()
           End If
    
           Return model
        End Function
    
        <Extension()>
        Public Shared Function ToData ( model As StateOrProvinceViewModel ) As StateOrProvince
           Dim data As New StateOrProvince
           With data
              .ID = model.ID
              .Name = model.Name
              .CountryID = model.CountryID
           End With
    
           ' Often we do not need related objects when going back to DB so leave the Country off... '
           Return data
        End Function
    End Class
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.