【问题标题】:httppost returns nothing with complex objects in mvc3 razor vb.nethttppost 在 mvc3 razor vb.net 中不返回任何复杂对象
【发布时间】:2012-06-14 16:17:47
【问题描述】:

我的 MVC3 vb.net 应用程序出现问题。当我尝试发布对控制器所做的更改时,模型不会发送到控制器。

我尝试关注很多帖子,例如 this onethis one,但我不确定如何在我的应用程序中实现它们,因为我的模型没有发送 IEnumerable 类型。

最后,我只希望模型为每个批次返回一个值,该值是我将保存到数据库中的值。

当我发布模型并尝试发送到控制器时,页面会通过邮寄方式发送以下内容:

Client=2&Datacenters=20&BatchesForAssignation[0].CenterID=4&BatchesForAssignation[1].CenterID=20&BatchesForAssignation[1].DatacenterID=14...

但我不知道如何将此查询字符串转换为 BatchesForAssignation 对象,将其分配给模型并发送给控制器。

注意:控制器中不使用查询字符串中显示的 ClientDatacenters 的值。我需要 BatchesForAssignation[n].CenterID 部分。

您能指点我找到解决方案吗?

这是我在 MVC 应用程序中使用的对象(代码压缩):

批次:

Public class Batch
    public property ID as integer
    public property CenterID as integer
    public property name as string
end class

Centers(这个对象只是存储了所有将分配给Batch的中心列表。名称只是为了在下拉列表中显示名称):

Public class Center
    public property ID as integer
    public property name as string
end class

(还有一个 Batchlist 和一个 Centerlist 对象,它们充当从 CollectionBase 继承的集合,存储所有 Batch 和 Center 对象。如果您需要类定义,请告诉我,但非常简单)。

型号如下

Public class ProcessingModel
    public property BatchesForAssignation as BatchList
    public property Datacenters as CenterList
End class

Controller如下:

<HttpGet()>
<Authorize()> _
Public Function AssignToDataCenters() As ActionResult
    Dim model As New ProcessingModel
    Dim BatchHandler As New BatchControl

    'This line will get the list of batches without datacenter
    model.BatchesForAssignation = BatchHandler.GetBatchesAvailable(ConnectionString)

    'This method will get the list of Datacenters available
    model.Datacenters=BatchHandler.GetDatacenters(ConnectionString)
    return View(model)
End Function

HttpPost(这实际上不起作用,因为模型返回一个空模型):

<HttpPost()>
<Authorize()> _
Public Function AssignToDataCenters(ByVal Model as ProcessingModel) As ActionResult
    Dim BatchHandler As New BatchControl
    Dim SaveResult as Boolean=false

    'This line will get the list of batches without datacenter
    model.BatchesForAssignation = BatchHandler.GetBatchesAvailable(ConnectionString)

    'This method save the information returned by the model
    SaveResult=BatchHandler.UpdateBatches(model)

    ViewBag("Result")=SaveResult
    Return View(model)
End Function

视图如下(是强类型视图):

@ModelType MVCAdmin.ProcessingModel

@Code
    ViewData("Title") = "Assign Batches To centers"
End Code

@Using Html.BeginForm()
    @<table id="tblAvailableBatches">
        <thead>
            <tr>
                <th>Assign batch to:</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            @code
                For i As Integer = 0 To Model.BatchesForAssignation.Count - 1
                    Dim a As Integer = i
                    @<tr>
                        <td>@Html.DropDownListFor(Function(m) m.BatchesForAssignation(a).CenterID, New SelectList(Model.Datacenters, "ID", "name", model.BatchesForAssignation(i).CenterID), " ")</td>
                        <td>@Model.BatchesForAssignation(i).name</td>
                    </tr>        
                Next
            End Code
        </tbody>
    </table>
    <input type="button" value="Apply changes" id="btnApply" />
End Using

提前致谢

2012 年 6 月 14 日更新:

经过一些研究,我发现我可以使用request.Form解析控制器中的查询字符串,我可以解析视图发送的结果。但是查询字符串键的形式为BatchesForAssignation[0].CenterID,BatchesForAssignation[1].CenterID,BatchesForAssignation[2].CenterID 等等...

是否有更好的方法“自动”执行此操作,以便模型解析查询字符串并将解析后的对象发送到控制器?

再次...提前致谢

【问题讨论】:

  • 如果您的视图使用ProcessingModel,那么为什么不将其作为AssignToDataCenters 的参数?
  • 是因为方法是在第一次加载视图时加载的。让我包括那个失败的 HttpPost 的代码。谢谢你的观点

标签: asp.net-mvc vb.net asp.net-mvc-3 web-applications razor


【解决方案1】:

查看this question 后,我发现创建模型并将其发送到控制器的最佳方法是创建CustomModelBinder(来自IModelBinder 接口)并在BindModel 上解析表单的查询字符串使用controllerContext.HttpContext.Request.Form 属性的方法。像这样的:

Public Class ProcessingModelBinder
    implements IModelBinder

    public Function BindModel(controllerContext As System.Web.Mvc.ControllerContext, bindingContext As System.Web.Mvc.ModelBindingContext) As Object
        dim model as ProcessingModel = if(nothing.equals(bindingContext.Model),directcast(bindingContext.Model,directcast(DependencyResolver.Current.GetService(typeof(ProcessingModel))
        dim Keys as string()=controllerContext.HttpContext.Request.Form.AllKeys

        for each key in Keys
            'Fill the model required parameters
        Next

        return model
End Function

最后在 global.asax 文件中注册新的模型生成器

Sub Application_Start()
    AreaRegistration.RegisterAllAreas()
    ModelBinders.Binders.Add(typeof(ProcessingModel),New ProcessingModelBinder())
    RegisterGlobalFilters(GlobalFilters.Filters)
    RegisterRoutes(RouteTable.Routes)
End Sub

我希望这对某人有所帮助

问候

【讨论】:

  • 如果您认为您有任何其他方法,请告诉我。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多