【问题标题】:Passing hidden object from view to controller将隐藏对象从视图传递到控制器
【发布时间】:2018-04-30 13:20:34
【问题描述】:

我有一个控制器将由列表和对象客户端组成的视图模型发送到视图。 该视图将在网格中显示列表,但隐藏对象客户端。 这是视图:

@model .Business.BusinessModels.MatchesClientViewModel
@{
    ViewBag.Title = "SaveClient";
}

<h2>SaveClient</h2>

<h3>
    The info captured matches @Model.ClientMatches.Count()
</h3>

    @using (Html.BeginForm("SaveClient", "Client", FormMethod.Post))
    {
        @Html.AntiForgeryToken()


        WebGrid grid = new WebGrid(Model.ClientMatches);
        @grid.GetHtml(columns: new[]

                             {
                        grid.Column("Name"),
                        grid.Column("Surname"),
                        grid.Column("Email"),
                    })

        @Html.Hidden("client", Model.client)

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
            </div>
     }

我的提交按钮点击的操作是:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveClient(MatchesClientViewModel matchesClientViewModel)
{
    *some actions*
    return View();
}

但是从视图发送到控制器的视图模型是空的。知道如何正确地将视图模型的隐藏部分传递给控制器​​吗?

【问题讨论】:

  • Model.Client 是一个对象?还是只是一个 id?
  • @AnastasiosSelmanis : 它是一个对象
  • 那么我害怕你必须像这样传递对象的每个字段:@Html.HiddenFor(m => m.client.Id, Model.client.Id), @Html。 HiddenFor(m => m.client.someattribute., Model.client.someattribute) 等。它会映射到您的表单提交上。一般来说,最好只使用 client.id,因为这可能是您在后端想要的,或者如果您想要对象只需从后端再次获取客户端对象。
  • 那么我是否也必须更改我的操作 SaveClient 参数?我没有使用 MatchesClientViewModel 作为参数,而是使用了一些属性类型?
  • @tabby,不,模型绑定器应该能够找出这些字段属于模型的client 字段,并根据属性值为您创建它。但是,仅当字段是强类型时才适用。只是 object 很可能不会工作

标签: c# asp.net-mvc


【解决方案1】:

如果你想将整个对象作为隐藏传递,你必须为类的每个属性添加隐藏字段,如下所示:

假设模型 Client 是这样的

public class Client
{
    public string Id { get; set; }
    public string SomeAttribute { get; set; }
    \\ ......
}

为了将您的值传递给您的操作,您应该将每个属性作为隐藏字段添加到表单中

@Html.HiddenFor(m => m.client.Id, Model.client.Id)
@Html.HiddenFor(m => m.client.Someattribute, Model.client.Someattribute)

另一种方法是将模型更改为以下内容:

public class MatchesClientViewModel
{
    public List<ClientMatch> ClientMatches { get; set; }
    public string clientId { get; set; }
    \\ .....
}

并将您的 clientId 仅传递给您的视图并像这样返回给控制器

@Html.HiddenFor(m => m.clientId., Model.clientId)

或者,如果您不想更改 ViewModel,只需添加一个隐藏字段,就像您为您的对象所做的那样,为客户端 ID 添加一个隐藏字段,并将其作为额外参数传递给控制器​​

@Html.HiddenFor('clientId', Model.client.Id)

让你的行动像这样

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveClient(MatchesClientViewModel matchesClientViewModel, string clientId)
{
    *some actions*
    return View();
}

【讨论】:

  • 最好只发布客户端 ID 并从缓存或数据库中检索对象服务器端(并检查登录用户是否确实有权访问此客户端 ID)。不要天真地相信表单中提交的内容,即使它来自隐藏的输入。您可能还想查看防伪令牌:blog.stevensanderson.com/2008/09/01/…
  • @AlexSanséau 在我的 cmets 中提到我提到的问题,他能做的最好的事情就是你提到的。不是出于身份验证目的,但主要是为了良好的实践。我刚刚发布了一个答案,其中包括按照他的要求做的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
相关资源
最近更新 更多