9

I am trying to pass hidden field value from view to controller by doing the following

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

and also tried

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

On both instances the value of ArticleId is 0 but when i use TextboxFor i can see the correct ArticleId, please help

Here it is

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

Controller

    // 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()
        };
    }

Model

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

ViewModel

public class ArticlesCommentsViewModel
{
    public Articles Articles { get; set; }
    public CommentsViewModel Comments { get; set; }
}
18
  • 2
    model.Articles it's a collection? Commented Sep 9, 2016 at 6:57
  • No its not a collection Commented Sep 9, 2016 at 6:59
  • 1
    What dou mean by On both instances the value of ArticleId is 0? Commented Sep 9, 2016 at 6:59
  • 1
    You could debug you code... Commented Sep 9, 2016 at 7:06
  • 2
    Since your view uses Articles.ArticleId but in your POST method your trying to access it with comments.ArticleId you clearly have a different model in the view. What is it? (the model in the view needs to be CommentsViewModel or if its a model that contains a property for CommentsViewModel, then you need a BindAttribute with a Prefix property) Commented Sep 9, 2016 at 7:39

7 Answers 7

7

The model in the view is ArticlesCommentsViewModel so therefore the parameter in your POST method must match. Your use of

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

is correct, but you need to change the method to

[HttpPost]
public ActionResult Create(ArticlesCommentsViewModel model)

and the model will be correctly bound.

As a side note, your ArticlesCommentsViewModel should not contain data models, and instead should contain only those properties you need in the view. If typeof Articles contains properties with validation attributes, ModelState would be invalid because your not posting all properties of Article.

However, since CommentsViewModel already contains a property for ArticleId, then you could just use

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

and in the POST method

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

to effectively strip the "Comments" prefix

Sign up to request clarification or add additional context in comments.

1 Comment

"As a side note, your ArticlesCommentsViewModel should not contain data models, and instead should contain only those properties you need in the view. If typeof Articles contains properties with validation attributes, ModelState would be invalid because your not posting all properties of Article." Implemented this point and its working as expected, thanks Stephen
2

In your controller, you need to pass the hidden value with the model, for example, if you have a userId as a hidden value, in your Page you add:
@Html.HiddenFor(x => x.UserId)

In your model of course you would already have UserId as well.
In your controller, you need the model as a parameter.
public async Task<ActionResult> ControllerMethod(YourViewmodel model) { model.UserId //this should be your HiddenValue

Comments

2

Also make sure name attribute is specified on the hidden field. Element's "id" is often used on client side but "name" on server side.

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

1 Comment

I think I love you. Thanks - that simple foundational bit a info was lost on me.
1

I guess your model have another class called Articles inside CommentsViewModel.Change your controller function for accessing the ArticleId accordingly.

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

1 Comment

And you probably need to ensure that Articles object can be created and is created...
1

In my case, I didn't put the hidden input in the form section, but out of form, so it's not send to backend. Make sure put hidden input inside the form.

Comments

0

In my case, I was passing a couple of fields back and forth between controllers and views. So I made use of hidden fields in the views. Here's part of the view. Note a controller had set "selectedTraining" and "selectedTrainingType" in the ViewBag to pass to the view. So I want these values available to pass on to a controller. On the hidden tag, the critical thing is set to the "name" attribute. "id" won't do it for you.

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

Then back on the controller:

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

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

Or can put the requests as parameters to the method: public ActionResult Index(string excel, string selectedTraining, string selectedTrainingType)

Comments

0

The reason it is not showing up is because any info to be "Posted" must be part of the form and yours is not. Declare it in a Div as a form group.

your code:

<div class="row">

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

Change to:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.