3

我对 MVC 很陌生,虽然我一直在尝试遵循最佳实践,但我相信我可能不了解其中任何一个的某些基础知识

-一个。适当地使用模型和视图模型 -b. 将模型传递给控制器​​以进行验证。

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

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

视图模型如下:

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 

参数选择:

@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)

说助手(这是我主要的困惑所在)(注意,继承助手页面是指允许我在 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),还没有机会拿起一本书。我一直在拼凑在线资源,但我确信我做错了很多事情。

编辑:有什么办法可以使语法突出显示不那么糟糕?

4

1 回答 1

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 服务......)中获取数据。视图模型只是这些数据以适合视图的方式的投影。

于 2012-05-24T21:17:47.490 回答