Anajrob
Anajrob

Reputation: 577

How to hide foreign key values from forms

I have a table in my database called Review and I have made ReviewController with read/write actions and views using Entity Framework. So it's all scaffolded code.

This is my Edit page.

@model UniversityApp.Models.Review
@{
    ViewBag.Title = "Edit";
}

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>Review</legend>

    @Html.HiddenFor(model => model.ReviewID)

    <div class="editor-label">
        @Html.LabelFor(model => model.MovieID, "Movie")
    </div>
    <div class="editor-field">
        @Html.DropDownList("MovieID", String.Empty)
        @Html.ValidationMessageFor(model => model.MovieID)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.UserID, "User")
    </div>
    <div class="editor-field">
        @Html.DropDownList("UserID", String.Empty)
        @Html.ValidationMessageFor(model => model.UserID)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Rating)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Rating)
        @Html.ValidationMessageFor(model => model.Rating)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Description)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

As you can see the scaffolding mechanism added editors for foreign value keys. I don't want users to be able to change manually user ids or movie ids after they've already made a review, so I removed this code. But upon editing review entries I get this error on database SaveChanges():

A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = Review_User ]

What should I do in my Edit actions in order to preserve old user id and movie id values?

Here's the code for Edit actions in ReviewController:

public ActionResult Edit(int id)
{
    Review review = db.Reviews.Find(id);
    ViewBag.MovieID = new SelectList(db.Movies, "MovieID", "Title", review.MovieID);
    ViewBag.UserID = new SelectList(db.Users, "UserID", "UserName", review.UserID);
    return View(review);
}

[HttpPost]
public ActionResult Edit(Review review)
{
    if (ModelState.IsValid)
    {
        db.Entry(review).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    ViewBag.MovieID = new SelectList(db.Movies, "MovieID", "Title", review.MovieID);
    ViewBag.UserID = new SelectList(db.Users, "UserID", "UserName", review.UserID);
    return View(review);
}

EDIT :

I have tried the methods described, but I am still having problems. Now the error message I get is this: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship. I don't know what am I doing wrong. The error is trigered on this line of code:

db.Entry(review).State = EntityState.Modified;

Upvotes: 1

Views: 1478

Answers (2)

jim tollan
jim tollan

Reputation: 22483

in addition to cd smith's very good suggestion, you can also add a hidden field if you don't want to decorate your viewmodel in this way, this would look something like:

@Html.HiddenFor(x => x.Review_UserID)

etc, etc for each FK you want to have on the form, but not be visible. Of course, this is similar to how the [ScaffoldColumn(false)] decorator works of course, tho adding the [HiddenInput(DisplayValue = false)] attribute does this explicitly for you.

Upvotes: 2

CD Smith
CD Smith

Reputation: 6607

Annotate your property with this in your ViewModels that you don't want to have the template auto-generate the column in the view

[ScaffoldColumn(false)]
public int ReviewID;

Upvotes: 2

Related Questions