简体   繁体   中英

Pass ViewModel from HttpGet Action to HttpPost Action

I'm trying to initialize a ViewModel in my Action Get then pass it to View, use some data, then get all that data back to use in my Action Post like this:

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; }
    }

Controller:

[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");
        }

View:

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

Is there anyway to do it? Because when I try to use the "model.request" in the Post method he comes "null"

Binding will only occur for fields that are actually used. If you are not using the request property in your view, might be better to just have the ID in a hidden input and load again on server in your POST. For the state, just add bool property to your model.

You can't bind a single field like a hidden input to an entire object. If you pass it the object, it's just going to call ToString on it to get a representation, which will most likely end up being something like "{Namespace.To.Requests}" , rather than the actual data contained within that object.

You can either explicitly create inputs for each property of the object, ie:

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

Or you can use EditorFor to let MVC do this for you by convention:

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

When fed an entire object, EditorFor will actually dig in and generate fields for each public property on that object according to the information it can get from the class, such as the property type and attributes applied ( DataType , UIHint , etc.)

That means, it likely won't choose hidden fields. You could annotate the properties in the class with the HiddenInput attribute:

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

However, you wouldn't want to do that on something like an entity class, since it will effect every use of this class for a form. View models are often utilized in these cases as you can create a separate view model representing the entity for as many views as you need without effecting other areas of your application.

You can also utilize editor templates to define the set of fields EditorFor should render for the object. By simply adding the view Views\\Shared\\EditorTemplates\\Requests.cshtml , whenever you call EditorFor with an instance of Requests , it will render that template. You could then, inside that view, render the fields for Requests any way you like. However, again, this is a global change that would affect any usage of EditorFor with an instance of Requests .

More likely than not, your best bet is to simply manually call Html.HiddenFor for each property on the class as described above directly in your view.

您可以将对象作为模型传递给视图,但是当您想要将对象的数据发送回控制器而无法发送对象时,您必须使用具有相同属性对象名称的原始变量

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM