C# 跳过返回视图的控制器方法

C# 跳过返回视图的控制器方法,c#,asp.net-mvc,viewmodel,C#,Asp.net Mvc,Viewmodel,我是MVC新手,第一次接触ViewModels,所以有点困难 我有一个查看页面,用户可以在其中选择是否要获取/转移/处置零件。然后,该数据将保存到ViewModel中。然后,我想向用户展示他们所选内容的摘要页面。所以我试着通过这样做来实现这一点 在我的POST方法中,我尝试调用summary get页面 [HttpPost] [ValidateAntiForgeryToken] public ActionResult SpecialOrderSelection(JobOrder job, Ite

我是MVC新手,第一次接触ViewModels,所以有点困难

我有一个查看页面,用户可以在其中选择是否要获取/转移/处置零件。然后,该数据将保存到ViewModel中。然后,我想向用户展示他们所选内容的摘要页面。所以我试着通过这样做来实现这一点

在我的POST方法中,我尝试调用summary get页面

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SpecialOrderSelection(JobOrder job, ItemViewModel model)
{               
   if (ModelState.IsValid)
   {
      JobOrder jobOrder = db.JobOrders.Find(job.ID);
      if (jobOrder == null)
      {
         return HttpNotFound();
      }
      ViewBag.JobOrderID = jobOrder.ID;
   }  

  return SpecialOrderSummary(model);
}
这正确地调用了我的summary Get方法

public ActionResult SpecialOrderSummary(ItemViewModel model)
{
   if (model == null)
   {
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
   }

   JobOrder jobOrder = db.JobOrders.Find(model.ID);
   if (jobOrder == null)
   {
      return HttpNotFound();
   }

  return View(model);
}
下面是我试图返回的视图页面的一个片段

@model PIC_Program_1._0.Models.ItemViewModel
@using PIC_Program_1._0.Models
@{
    ViewBag.Title = "SpecialOrderSummary";
}

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(x => x.ID)
    <h2>Special Order Summary</h2>
    <p style="color:red" class="noprint">Please review and verify </p>


    <h2>
        Transfers
    </h2>
    <h4><b>Components </b></h4>
    <table class="table">

        <tr>
            <th>
                IGT Component ID
            </th>
            <th>
                MFG ID
            </th>
            <th>
                Component Name
            </th>
        </tr>

        @foreach (var comp in Model.Components.Where(n => n.SelectedActionType == PartActionType.Transfer))
        {
            <tr>
                <td> @comp.ComponentId</td>
                <td> @comp.MFGNumber</td>
                <td> @comp.ComponentName</td>
            </tr>
        }
    </table>
}
@model PIC\u Program\u 1.\u 0.Models.ItemViewModel
@使用PIC_程序_1._0.0模型
@{
ViewBag.Title=“SpeciallorderSummary”;
}
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(x=>x.ID)
特别订单摘要

请检查并验证

转移 组件 IGT元件ID 制造商ID 组件名称 @foreach(Model.Components.Where(n=>n.SelectedActionType==PartActionType.Transfer)中的var comp) { @comp.ComponentId @公司编号 @组件名称 } }
这是我的视图模型

 public class ItemViewModel
    {
        [Required]
        public int ID { get; set; }
        public string ItemId { get; set; }
        public string ItemName { get; set; }
        public string MFGNumber { get; set; }
        public IList<ItemPartViewModel> Parts { get; set; }
        public IList<ItemComponentViewModel> Components{ get; set; }
        public IList<ComponentPartViewModel> ComponentParts { get; set; }
        public IList<ComponentSubCompViewModel> ComponentSubComps { get; set; }
        public IList<SubCompPartViewModel> SubCompParts { get; set; }

        public IList<SubCompSubCompViewModel> SubCompSubComps { get; set; }
        public IList<SubCompSubCompPartViewModel> SubCompSubCompParts { get; set;}

    }
公共类ItemViewModel
{
[必需]
公共int ID{get;set;}
公共字符串ItemId{get;set;}
公共字符串ItemName{get;set;}
公共字符串MFGNumber{get;set;}
公共IList部分{get;set;}
公共IList组件{get;set;}
公共IList组件部件{get;set;}
公共IList组件子组件{get;set;}
公共IList子组件{get;set;}
公共IList子comps{get;set;}
公共IList子compparts{get;set;}
}
模型被适当地传递给GET,但它跳过了my
return View(model)
,而是返回“Selection”视图页面,而不是“Summary”视图页面


我该如何解决这个问题?

这不是你的解决方法:

return SpecialOrderSummary(model);
虽然这最终将从另一个方法调用
返回视图(模型)
,但最终您将从
speciallorderselection
中返回
视图
,框架将使用它来确定要渲染的视图

不要试图欺骗框架调用其他操作,而是将用户重定向到该操作:

return RedirectToAction("SpecialOrderSummary", new { ID = jobOrder.ID });

这将告诉浏览器向
speciallordersummary
发出新的GET请求,传递
ID
值,该值为
jobOrder.ID
包含的任何内容。(我假设这就是你想要的ID,如果不是用你想要的替换它的话。)

你只是把它和视图模型混淆了。视图模型没有特殊意义。它只是一个POCO(普通的旧CLR对象),只包含您需要在视图上显示的信息,而不是操作,不是事件。它充当控制器和视图之间的容器

再说一次,我不知道您正在处理的域,因此以下只是我的猜测:


您可能已经从数据库获取了数据,并在GET方法上构造了这个视图模型。如果要持久化JobID,例如,需要在视图模型中声明一个属性,并将其放在视图中的隐藏表单中,以便表单发回时持久化

公共类ItemViewModel
{
[必需]
public int JobId{get;set;}
公共字符串ItemId{get;set;}
...
}
您还需要指定表单发回的方法和控制器:

@using (Html.BeginForm("specialOrderSelection", "WhatEverController", new { area = "" }, 
    FormMethod.Post))
{
    @Html.AntiForgeryToken()

    @Html.HiddenFor(x => x.JobId)
    <h2>Special Order Summary</h2>
最后,它会重定向到同一控制器内具有作业id(或标识对象的任何关键标识符)的操作“摘要”。使用id再次获取数据:

public ActionResult摘要(int-jobId)
{
//使用ID再次获取数据,并填充视图模型
// ...
var vm=新的SpecialOrderServiceWModel
{
...
};
返回视图(vm);
}

这里应该有另一个视图模型和一个仅用于摘要页面的视图。

我认为问题在于
view
通过函数名暗示了视图的名称(cshtml),它可能选择
speciallordersummary.cshtml
作为视图名称,而不是
speciallorderselection.cshtml
@Neil-hmm如果发生这种情况,我如何修复它?在控制器函数中返回视图,而不是在子函数中。应该很容易证明这就是问题所在。如果没有,我就看看能不能想出别的办法。@Neil,你是什么意思?那看起来怎么样?很抱歉,我对这一点还很陌生,所以我还在学习,但我感谢您的帮助。谢谢David,但这会返回我的viewmodel数据吗?我已经在试图返回的视图页面中添加了,因为视图页面接受“itemViewModel”作为模型,所以它就是这样expecting@JoshFontaine:这是退一步检查控制器操作实际执行情况的好时机
speciallordersummary
接受模型实例,根据该实例中的ID从数据中获取记录,然后忽略该记录并返回最初发送给它的内容。这没什么意义。我怀疑
SpecialLorderSummary
应该只接受一个ID值,根据该ID值从数据中获取一条记录,然后返回该记录。是的,我只是对如何使用ViewModel数据感到困惑,就像我说的,这是我第一次使用ViewModels,所以我不知道它在这种情况下是如何工作的。因为当我没有传递整个viewmodel时,我会收到一个错误,说它需要一个model@JoshFontaine分别考虑每个控制器动作。您希望操作
speciallordersummary
执行什么操作,请指定