web-dev-qa-db-ja.com

MVCで編集を実行するときに、一部のフィールドの元の値を維持するにはどうすればよいですか?

ご存知のように、データを変更する場合は、編集ページに移動します。

public ActionResult EditAdmin(int UserId)
{ 
        User user = persons.Users.Find(id);
        return View(user);
}

次に、それを編集ページに送信すると、変更されます。

public ActionResult EditAdmin(User user)
{ 
        persons.Entry(user).State = EntityState.Modified;
        persons.SaveChanges();
}

しかし問題は、私がフィールドをたくさん持っていることです変更する必要はありません

public class User{
    public int UserId {get; set;} // do not need modify
    public int Password {get; set;} // do not need modify
    public string Name {get; set;}
    public bool Sex {get; set;}
    public DateTime AddTime {get; set;} // do not need modify
}

明らかに、編集ページの一部のフィールドを表示することはできませんHidden。UIに表示したくないためです。しかし、送信するとき、私はまだそれを必要としますまだ元の値を保持します。それで良いアイデアはありますか?ありがとう

Update1:​​

なぜ私は使用できません

entry.Property(e => e.Password).IsModified = false;

リンク: https://stackoverflow.com/a/18004476/1900498

しかし、それは表示されます:

1つ以上のエンティティの検証が失敗しました。詳細については、「EntityValidationErrors」プロパティを参照してください。

14
qakmak

データベースから既存のバージョンを取得し、「変更可能」フィールドのみを変更します。

public ActionResult EditAdmin(User user)
{ 
    var currentPerson = db.Persons.FirstOrDefault(p => p.id = user.id);
    if (currentPerson == null)
        return HttpNotFound();

    currentPerson.Name = user.Name;
    currentPerson.Sex = user.Sex;
    // Id and Password are not updated.

    db.SaveChanges();
}
  • 更新されるバージョンが実際に最新であることを確認するために、いくつかの楽観的同時実行検査も実行することもできます。理想的には、タイムスタンプがある場合はこれを使用します。そうでない場合は、すべてのフィールドを比較する必要があります。

編集
調整されたビューモデルの作成に関する@KrisのコメントとRicのポイントも参照してください。したがって、ORM /データ層エンティティでビューを汚染しません。また、last one winsの上書きの問題を防ぐために、ViewModelを介してタイムスタンプまたはハッシュを実行する必要があるとも主張します。

22
StuartLC

オプション1:

readonly属性を使用できます:

何かのようなもの:

@Html.EditorFor(model => model.DriverID, new { htmlAttributes = new { 
        @Value = @Html.Action("getNextDriverID"), @readonly = "readonly"} })

@Valueの部分は心配しないでください。これにより、アクションメソッドを呼び出して値を自動生成できます。

コンテキストでは、次のようになります:

@Html.EditorFor(model => model.UserId, new { htmlAttributes = new {@readonly = "readonly"} })

ご注意ください

この答えはカミソリビューエンジンの使用に言及しています。


オプション2:

別のオプションは、別のviewModelを一緒に使用することです。

public class edit User{

    public int userId {get; set;}
    public string Name {get; set;}
    public bool Sex {get; set;}
}

そして、 `Edit ActionResult 'でこれを使用してデータを「入力」します。

そこから、データベースに保存する前に(linqまたはそれ以外の方法で)[HttpPost]アクションメソッドに値を設定できます。


オプション3:ViewBagsの使用

モデルの2つの部分のみを編集することを目的としているため、ViewBagを使用することもできます。

コントローラ:

ViewBag.Item1 = xyz;
ViewBag.Item2 = xyz;

見る:

@Html.TextBox("Item1")
@Html.TextBox("Item2")

次に、postメソッドで、これらを文字列パラメーターとして追加できます。

public ActionResult Edit(string Item1, string Item2)
{
 ...
10
user3913686

あなたはあなたの編集ページのために特定のビューモデルを作ることができ、実際にすべきです。お気に入り:

public class UserViewModel
{
    public string Name {get; set;}
    public bool Sex {get; set;}
}

次に、完全なユーザーをビューとの間でやり取りする代わりに、UserViewModelを使用します。

public ActionResult EditAdmin(int userId)
{ 
        User user = persons.Users.Find(userId);
        return View(new UserViewModel 
            { 
                Id = user.Id,
                Name = user.Name, 
                Sex = user.Sex 
            });
}

[HttpPost]
public ActionResult EditAdmin(UserViewModel user)
{ 
        var dbUser = persons.Users.Find(user.Id);
        dbUser.Name = user.Name;
        dbUser.Sex = user.Sex;

        persons.Entry(dbUser).State = EntityState.Modified;
        persons.SaveChanges();
}
6
Ric .Net

ここに、データベースにデータを投稿し、他のフィールドを除外する方法を学びました。 PIVPrintedチェックボックスで私のデータベースに1つの変更を投稿したかっただけです。

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult PrintDetails([Bind(Include = "PatientID,LastName,FirstName,PatientDOB,PIVCompleted,PIVPrinted")] PIV pIV,
        string command)
    {

        if (command.Equals("Print Completed"))

        {
            pIV.PIVPrinted = false;
            db.Entry(pIV).State = EntityState.Unchanged;
            db.Entry(pIV).Property("PIVPrinted").IsModified = true;
            db.SaveChanges();

            return RedirectToAction("PrintDetails");
4
nolanfilm

Razorビューエンジンを使用して、エントリを非表示としてマークできます。

    <div class="form-group" style="visibility:hidden;height:0px;">
            @Html.EditorFor(model => model.CreationDate)
            @Html.ValidationMessageFor(model => model.CreationDate, "", new { @class = "text-danger" })
    </div>

または、これはより簡単です:-

    @Html.HiddenFor(model => model.CreationDate)
2
user2284063

ビューで非表示を使用したくない場合は、データベースからyorエンティティをロードし、次のようなyor変更を追加する必要があります

var olduser= db.Persons.FirstOrDefault(p => p.id = user.id);
olduser.Name=user.Name; 
olduser.Sex=user.Sex;
persons.SaveChanges();
1
M.Azad
 @Html.HiddenFor(model => model.UserId)
 @Html.HiddenFor(model => model.Password)
 @Html.HiddenFor(model => model.AddTime)

他に何もする必要はありません。定数値をRazor構文としてリストするだけです。

1
Emre Sevim

シンプルで簡単な解決策は、セッションを使用することです。 Edit getメソッドでは、セッションを作成して、たとえばその特定のオブジェクトの値を割り当てるだけです。

Session["ProfilePic"] = personnel.ProfilePic;

ポスト編集メソッドで値を設定します

personnel.ProfilePic = Session["ProfilePic"].ToString();

ポストメソッドの編集のoffcourseでは、特定のオブジェクト値がnullの場合の条件を確認します。

0
Hassan Raza

ほんのいくつかのフィールドを変更するために、私は次のコードを使用し、あなたもそれを利用できると思います。

if (ModelState.IsValid)
{
    var action = this.db.DbcontextName.Find(int.Parse(id));   
    db.Entry(action).Property("Status").CurrentValue = "YourString/Data";

    db.SaveChanges()          
 }
0
Rom

次のようにTempDataを使用できます。

public ActionResult EditAdmin(int UserId) { User user = persons.Users.Find(id); TempData["oldUser"] = user; return View(user); }

その後、投稿後にそれを回復できます:

public ActionResult EditAdmin(User user) { User oldUser = TempData["oldUser"] == null ? persons.Users.Find(user.UserId) : (User) TempData["oldUser"]; if (oldUser.Sex != user.Sex) doSomething(); persons.Entry(user).State = EntityState.Modified; persons.SaveChanges(); }

TempData ["oldUser"] == nullをチェックする必要があります。エラーまたはユーザーがページに戻った場合、TempDataが失われることがあるからです。

0
Guilherme Muniz