如何在ASP.NET MVC 5中从视图传递隐藏字段值到控制器?

9
我正在尝试通过以下方式将隐藏字段的值从视图传递到控制器:
@Html.HiddenFor(model => model.Articles.ArticleId) 

同时也尝试了

<input type="hidden" id="ArticleId" name="ArticleId" value="@Model.Articles.ArticleId" />

在这两个实例中,ArticleId的值都是0,但是当我使用TextboxFor时,我可以看到正确的ArticleId,请帮忙解决。
代码如下:
View
@model ArticlesCommentsViewModel
....
@using (Html.BeginForm("Create", "Comments", FormMethod.Post))
{
<div class="row">
    <div class="col-xs-10 col-md-10 col-sm-10">
        <div class="form-group">
            @Html.LabelFor(model => model.Comments.Comment, new { @class = "control-label" })
            @Html.TextAreaFor(m => m.Comments.Comment, new { @class = "ckeditor" })
            @Html.ValidationMessageFor(m => m.Comments.Comment, null, new { @class = "text-danger"})
        </div>
    </div>
</div>

<div class="row">

        @*@Html.HiddenFor(model => model.Articles.ArticleId)*@
    <input type="hidden" id="ArticleId" name="ArticleId" value="@Model.Articles.ArticleId" />
</div>

<div class="row">
    <div class="col-xs-4 col-md-4 col-sm-4">
        <div class="form-group">
            <input type="submit" value="Post Comment" class="btn btn-primary" />
        </div>
    </div>
</div>
}

控制器

    // POST: Comments/Create
    [HttpPost]
    public ActionResult Create(CommentsViewModel comments)//, int ArticleId)
    {
        var comment = new Comments
        {
            Comment = Server.HtmlEncode(comments.Comment),
            ArticleId = comments.ArticleId,
            CommentByUserId = User.Identity.GetUserId()
        };
    }

模型

public class CommentsViewModel
{
    [Required(ErrorMessage = "Comment is required")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Comment")]
    [AllowHtml]
    public string Comment { get; set; }

    public int ArticleId { get; set; }
}

视图模型

public class ArticlesCommentsViewModel
{
    public Articles Articles { get; set; }
    public CommentsViewModel Comments { get; set; }
}

2
model.Articles 是一个集合吗? - adricadar
1
你说的“On both instances the value of ArticleId is 0”是什么意思? - Adil Mammadov
1
你可以调试你的代码... - Jeroen Heier
抱歉,现在已经包含了。 - user3543878
2
由于您的视图使用了 Articles.ArticleId,但在您的 POST 方法中,您试图使用 comments.ArticleId 访问它,这表明您的视图中有一个不同的模型。那是什么?(视图中的模型需要是 CommentsViewModel,或者如果它是包含 CommentsViewModel 属性的模型,则需要使用带有 Prefix 属性的 BindAttribute)。 - user3559349
显示剩余13条评论
7个回答

7

视图中的模型是ArticlesCommentsViewModel,因此您POST方法中的参数必须匹配。您使用的

@Html.HiddenFor(model => model.Articles.ArticleId)

这是正确的,但你需要更改方法为

[HttpPost]
public ActionResult Create(ArticlesCommentsViewModel model)

同时,该模型将被正确绑定。

另外需要说明的是,您的ArticlesCommentsViewModel不应包含数据模型,而应仅包含视图中所需的属性。如果Articles类型包含带有验证属性的属性,则ModelState将无效,因为您没有发布Article的所有属性。

然而,由于CommentsViewModel已经包含了ArticleId属性,所以您可以直接使用:

@Html.HiddenFor(model => model.Comments.ArticleId)

并且在POST方法中

[HttpPost]
public ActionResult Create([Bind(Prefix="Comments")]CommentsViewModel model)

有效地去除“Comments”前缀

顺便说一句,你的ArticlesCommentsViewModel不应该包含数据模型,而是只包含视图中需要的属性。如果Articles类型包含带有验证属性的属性,那么ModelState将无效,因为你没有提交Article的所有属性。我已经实施了这个要点,并且它按预期工作了。谢谢Stephen。 - user3543878

2
同样也要确保隐藏字段的 name 属性已指定。在客户端常使用元素的"id"属性,但在服务器端使用"name"属性。
<input type="hidden" value="@ViewBag.selectedTraining" id="selectedTraining"
 name="selectedTraining" />

我想我爱你。谢谢 - 对我来说,这个简单的基础信息丢失了。 - KirstieBallance

2

在你的控制器中,你需要通过模型传递隐藏的值, 例如,如果你有一个userId作为隐藏的值,在你的页面中添加:
@Html.HiddenFor(x => x.UserId)

当然,在你的模型中,你已经有了UserId。
在你的控制器中,你需要将模型作为参数。
public async Task<ActionResult> ControllerMethod(YourViewmodel model) { model.UserId //这应该是你的HiddenValue


1
在我的情况下,我没有把hidden输入放在表单部分,而是放在表单外面,所以它不会发送到后端。请确保将hidden输入放在表单内部。

1
我猜你的模型里还有一个名为Articles的类,在CommentsViewModel内部。相应地更改你的控制器函数以访问ArticleId
[HttpPost]
public ActionResult Create(CommentsViewModel comments)//, int ArticleId)
{
    var comment = new Comments
    {
        Comment = Server.HtmlEncode(comments.Comment),
        ArticleId = comments.Articles.ArticleId,  // Since you are using model.Articles.ArticleId in view
        CommentByUserId = User.Identity.GetUserId()
    };
}

你可能需要确保可以创建 Articles 对象并且已经被创建了... - Phil1970

0
在我的情况下,我需要在控制器和视图之间传递一些字段。因此,我在视图中使用了隐藏字段。 以下是视图的一部分。请注意,控制器已经将“selectedTraining”和“selectedTrainingType”设置在ViewBag中以传递给视图。因此,我希望这些值可用于传递给控制器。在隐藏标签上,关键的是设置“name”属性。 “id”不能为您做到这一点。
@using (Html.BeginForm("Index", "ComplianceDashboard"))
{

<input type="hidden" value="@ViewBag.selectedTraining" id="selectedTraining" name="selectedTraining" />
<input type="hidden" value="@ViewBag.selectedTrainingType" id="selectedTrainingType" name="selectedTrainingType" />

if (System.Web.HttpContext.Current.Session["Dashboard"] != null)
{
    // Show Export to Excel button only if there are search results
    <input type="submit" id="toexcel" name="btnExcel" value="Export To Excel" class="fright" />
}

<div id="mainDiv" class="table">
    @Html.Grid(Model).Columns(columns =>

然后回到控制器:

        // POST: Dashboard (Index)
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(string excel)
        {
            string selectedTraining, selectedTrainingType;

            selectedTraining = Request["selectedTraining"];
            selectedTrainingType = Request["selectedTrainingType"];

可以将请求作为参数传递给方法:public ActionResult Index(string excel, string selectedTraining, string selectedTrainingType)。

0

它没有显示出来的原因是因为任何要“发布”的信息都必须是表单的一部分,而你的不是。将其声明为一个Div作为表单组。

你的代码:

<div class="row">

     @*@Html.HiddenFor(model => model.Articles.ArticleId)*@
    <input type="hidden" id="ArticleId" name="ArticleId" value="@Model.Articles.ArticleId" />
</div>

更改为:

<div class="row">
   <div class="form-group">
       @*@Html.HiddenFor(model => model.Articles.ArticleId)*@
       <input type="hidden" id="ArticleId" name="ArticleId" value="@Model.Articles.ArticleId" />
   </div>
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接