Asp.net MVC3适当的模型传递VB.net

时间:2012-05-24 20:48:44

标签: vb.net asp.net-mvc-3 html-helper

我对MVC很陌生,虽然我一直在努力遵循最佳实践,但我相信我可能无法理解其中的某些基本原理

-a。适当地使用模型和视图模型 -b。将模型传递到控制器以进行验证。

我的程序的一般目的是从存储过程列表中选择一个存储过程,创建一个表单,用户可以填写所有相应的输入变量,然后执行该存储过程。该工具适用于非技术人员,因此我最终将不得不进行大量的输入验证。

因此我有四个模型:脚本模型,参数模型,参数枚举模型和查询模型,以及两个视图模型:生成要填写的表单的paramviewmodel,以及创建填充的列表框的scriptviewmodel可能的脚本选择。我正在使用预先编写的数据库系统在我的控制器的init方法中填写我的viewmodel(我不确定这是正确的方法吗?)。

视图模型如下:

Imports System
Imports System.Collections.Generic

Public Class ScriptViewModel

    Public Property SelectedItemId As Integer
    Public Property Scripts As DataTable
    Public Property ScriptList As List(Of ScriptModel)

    Sub InitScriptData()
        ' Fills the data from an outside database.  
        ' And fills out the properties above.  Does nothing else
    End Sub

End Class

其他一个

Imports System
Imports System.Collections.Generic

Public Class ParamViewModel

    Public Property Params As DataTable
    Public Property ParamEnums As DataTable
    Public Property ParameterList As List(Of ParameterModel)
    Public Property ParamEnumList As List(Of ParamEnumModel)
    Public Property ParamEnumDictionary As Dictionary(Of Integer, List(Of ParamEnumModel))

    Sub InitParamData(ByVal Script_Index As String)
        ' Uses an outside database
        ' Fills out all the above variables    
    End Sub
End Class

他们的相关观点如下:

脚本:

@ModelType Scripter.ScriptViewModel
@Html.ValidationSummary("Please correct the errors and try again.")
@Using (Html.BeginForm("ParamChoice", "Parameter", FormMethod.Post))
    @<div>
    @Html.ListBox("ScriptListBox", New SelectList(Model.ScriptList, "Script_Index", "CustomerScriptName"), New With {.class = "LargeListBox", .title = "LargeListBox"})
    </div>
    @<input type="submit" value="Execute Script" />
End Using 

ParamChoice:

@ModelType Scripter.ParamViewModel
@Code
    ViewData("Title") = "ParamChoice"
End Code

<h2>ParamChoice</h2>

<!-- Helper Method defined in App_Code that creates a form with a dynamic number of fields of appropriate input types -->
@HelperMethods.CreateVariableInputParameterFields(Model.ParameterList, Model.ParamEnumDictionary)

说好帮手(这是我的主要困惑所在)(注意,继承helperpage是指允许我在app_code中的@helper中使用htmlhelpers的类)

@inherits Scripter.HelperPage

@Imports System.Web.Mvc
@Imports System.Web.Mvc.Html

@helper CreateVariableInputParameterFields(ByVal ParamList As List(Of Scripter.ParameterModel), ByVal EnumDictionary As Dictionary(Of Integer, List(Of Scripter.ParamEnumModel)))
    Dim item As Scripter.ParameterModel

    @Html.ValidationSummary("Please correct the errors and try again.")

    Using (Html.BeginForm("QueryServer", "Query", FormMethod.Post))

    Dim iterator As Integer = 0
    Dim ParamValue(ParamList.Count) As String
    Dim ParamName(ParamList.Count) As String
    Dim ParamType(ParamList.Count) As String

    For Each item In ParamList
        If (String.Compare(item.ParamType, "Int") = 0 Or String.Compare(item.ParamType, "String") = 0) Then
            @<br />
            @Html.Label(item.ParamName)
            @Html.TextBox("ParamValue", Nothing, New With {.class = "text-box", .id = CStr(iterator)})
            @Html.Hidden("ParamName", item.ParamName, New With {.id = CStr(iterator)})
            @Html.Hidden("ParamType", item.ParamType, New With {.id = CStr(iterator)})
            iterator += 1
        ElseIf (String.Compare(item.ParamType.ToString, "Enum") = 0) Then
            Dim tlist = EnumDictionary.Item(item.Param_Index)
            @<br />
            @Html.Label("label", item.ParamName, New With {.class = "display-label"})
            @Html.DropDownList("ParamValue", New SelectList(tlist, "EnumValue", "EnumValue"), New With {.id = CStr(iterator)})
            @Html.Hidden("ParamName", item.ParamName, New With {.id = CStr(iterator)})
            @Html.Hidden("ParamType", item.ParamType, New With {.id = CStr(iterator)})
            iterator += 1
        Else
            @<br />
            @Html.Label("label", item.ParamName, New With {.class = "display-label"})
            @Html.CheckBox("ParamValue", Nothing, New With {.id = CStr(iterator)})
            @Html.Hidden("ParamName", item.ParamName, New With {.id = CStr(iterator)})
            @Html.Hidden("ParamType", item.ParamType, New With {.id = CStr(iterator)})
            iterator += 1
        End If
    Next

    @Html.Hidden("Script_Index", ParamList.Item(0).Script_Index)

    @<div>
        <input type="submit" value="Query Server"/>
    </div>
    Html.EndForm()
End Using
End helper

脚本控制器作为我一直在做的事情的一个例子:

Namespace Scripter
    Public Class ScriptController
        Inherits System.Web.Mvc.Controller

        Function Index() As ActionResult
            Dim Test As New ScriptViewModel
            Test.InitScriptData()

            Return View(Test)
        End Function

    End Class
End Namespace

抱歉,以上所有内容都是如此难看哈哈,我正在努力解决这个问题。另外,我认为这可能是视图中的代码太多,尽管其中大部分都是显示代码。

无论如何,我有两个主要问题。一,在我的控制器中创建模型,在其上调用init方法,然后将其传递给视图在mvc上下文中是否有意义(如果没有,我将如何继续?)。二,如果我想在我的htmlhelper输出的表单上执行验证,但我想使用我的查询模型验证(而不是我的paramviewmodel),我该怎么做?我见过的大多数例子都涉及一个接收适当模型变量的控制器,并且绑定是在控制器本身之外执行的。然后他们只检查模型状态。我有什么方法可以在这里做类似的事情吗?

请随时在此处搜索我的代码。我对此非常陌生(包括vb.net和mvc)并且还没有机会拿起一本书。我一直在网上拼凑来源,但我确信我做错了很多。

编辑:有什么方法可以让语法突出显示不那么糟糕吗?

1 个答案:

答案 0 :(得分:2)

通常,视图模型不具有将从数据库获取数据的Init方法。视图模型是标准POCO类,在大多数情况下包含将保存特定视图需要使用的数据的属性。

另一方面,您可以拥有一个或多个域模型,负责从各种数据源检索信息。

控制器操作将负责查询域模型及其各种方法,以便最终构建一个特定的视图模型,该模型将被处理到视图以进行显示。视图模型可以表示从多个域模型和各种数据源聚合的数据。

所以基本上这里是标准GET控制器动作的伪代码:

Function Index() As ActionResult
    Dim model1 As DomainModel1 = ... fetch the domain model from somewhere
    Dim model2 As DomainModel2 = ... fetch the domain model from somewhere

    Dim vm As ViewModel = ... map all the domain models to a single view model specifically designed for the view

    Return View(vm)
End Function

此处域模型负责从您使用的各种数据源(数据库,文件,远程Web服务......)中提取数据。视图模型只是以适应的方式对视图进行投影。