将ViewModel从HttpGet Action传递给HttpPost Action

本文关键字:Action HttpPost HttpGet ViewModel | 更新日期: 2023-09-27 18:12:02

我试图在我的Action Get中初始化ViewModel然后将其传递给View,使用一些数据,然后获得所有这些数据以在我的Action Post中使用,就像这样:

ViewModel:

public class AddResponseModel
    {
        iDeskEntities db = new iDeskEntities();
        public AddResponseModel()
        {
            RespTypeList = new SelectList(db.ResponseType.Where(e=>e.type != "Assignar" && e.type != "Reabrir"), "type", "type");
            newRespList = new SelectList(db.Users, "id", "name");
        }
        [Required]
        [DataType(DataType.Text)]
        public string response { get; set; }
        [HiddenInput]
        public Requests request { get; set; }
        [HiddenInput]
        public string newResp { get; set; }
        [DataType(DataType.Text)]
        public SelectList newRespList { get; set; }
        [HiddenInput]
        public int RespType { get; set; }
        [Required]
        [DataType(DataType.Text)]
        public SelectList RespTypeList { get; set; }
    }

控制器:

[HttpGet]
        public ActionResult AddResponse(int? id)
        {
            AddResponseModel model = new AddResponseModel();
            model.request = db.Requests.Find(id);
            return View("AddResponse", model);
        }
[HttpPost]
        public ActionResult AddResponse(Requests req, AddResponseModel model)
        {
            //Some code, where i wanna access again model.request that i //initiated on the GET action
            return RedirectToAction("Dashboard", "BHome");
        }

视图:

@using (Html.BeginForm("AddResponse", "Requests", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true)
        @if (Model.request.state != 0)
        {
            <div class="form-group">
                @Html.LabelFor(model => model.RespType, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownListFor(model => model.RespType, Model.RespTypeList)
                    @Html.ValidationMessageFor(model => model.RespType)
                </div>
            </div>
        }
        <div class="form-group">
            @Html.LabelFor(model => model.response, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.response)
                @Html.ValidationMessageFor(model => model.response)
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Adicionar Resposta" class="btn btn-default" />
            </div>
        </div>
    </div>
}

有办法吗?因为当我尝试使用"模型"时。

将ViewModel从HttpGet Action传递给HttpPost Action

绑定只发生在实际使用的字段上。如果您没有在视图中使用请求属性,最好将ID放在隐藏的输入中,然后在POST中再次在服务器上加载。对于状态,只需向模型添加bool属性。

您不能将单个字段(如隐藏输入)绑定到整个对象。如果你把对象传递给它,它只会调用ToString来获得一个表示,这很可能最终是"{Namespace.To.Requests}"之类的东西,而不是该对象中包含的实际数据。

您可以显式地为对象的每个属性创建输入,即:

@Html.HiddenFor(m => m.request.Foo)
@Html.HiddenFor(m => m.request.Bar)
@Html.HiddenFor(m => m.request.Baz)

或者您可以使用EditorFor让MVC按照约定为您完成此操作:

@Html.EditorFor(m => m.request)

当提供整个对象时,EditorFor实际上会根据从类中获得的信息(如属性类型和应用的属性(DataType, UIHint等))挖掘并生成该对象上的每个公共属性的字段

这意味着,它可能不会选择隐藏字段。您可以使用HiddenInput属性在类中注释属性:

[HiddenInput]
public string Foo { get; set; }

但是,您不会希望在实体类之类的东西上这样做,因为它将影响该类对表单的每次使用。在这些情况下,视图模型经常被使用,因为您可以创建一个单独的视图模型来表示您需要的任意多个视图的实体,而不会影响应用程序的其他区域。

您还可以使用编辑器模板来定义EditorFor应该为对象呈现的字段集。通过简单地添加视图Views'Shared'EditorTemplates'Requests.cshtml,每当您用Requests的实例调用EditorFor时,它将呈现该模板。然后,您可以在该视图中,以任何您喜欢的方式渲染Requests的字段。然而,同样,这是一个全局更改,将影响EditorForRequests实例的任何使用。

更有可能的是,您最好的选择是像上面描述的那样,直接在视图中为类的每个属性手动调用Html.HiddenFor

你可以将对象作为模型传递给视图,但是当你想将对象的数据发送回控制器时,你不能发送对象,你必须使用与对象属性同名的原始变量