5

投稿した後、モデル(EF4)のナビゲーションプロパティをnullにしない方法がわかりません。私はいくつかの基本的なページで同じ問題を抱えています。

つまり、LoginIDの外部キー(Loginテーブルから)を使用したテーブルEstimateがあります。

HTTPGet Editメソッドで、必要な特定の見積もりを見つけます。

Estimate estimate = db.Estimates.Find(id)

ここから、Loginナビゲーションプロパティと、Loginテーブルからそのレコードの任意のプロパティにアクセスできます。

強く型付けされたビューのモデルとして、この見積もりを渡します。HTTPPost Editメソッドが呼び出されると(そしてモデルがパラメーターとして渡されると)、Loginナビゲーションプロパティがnullになり、その中の何にもアクセスできなくなります。もちろん、見積もりクラスにLoginIDフィールドがあるので、それを回避することはできますが、それは本当に不格好で、エンティティフレームワークの主な利点を逃しているように感じます。

複数のページで同じ問題が発生し、ナビゲーションプロパティを持つモデルをビューに渡し、ビューがnullナビゲーションプロパティを持つモデルを返します。

以下は、私が問題を抱えていたコードの例です。

    [HttpPost]
    public ActionResult Edit(Estimate estimate)
    {

        var test = estimate.Login.CompanyProfileID;
        ...

Model.Loginとそのすべてのプロパティにビューで問題なくアクセスできるので、ビューに適切に渡されていることがわかります。フォームが送信されたときに、ナビゲーションプロパティがコントローラーに戻されないだけです。

4

4 に答える 4

6

何が起こっているのかというと、MVCは「モデルバインディング」と呼ばれるものを使用します。これは、POSTがページリクエストで渡すすべてのフィールドを、アクションのパラメーターの一致するプロパティに一致させます。

したがって、プロパティがPOSTページの入力フィールドに含まれていない場合、アクションのパラメーターにバインドされないPOSTため、nullになります。

Loginしたがって、たとえば、のすべてのプロパティに非表示フィールドを含めることができます。

@Html.HiddenFor(m => m.Login.ID)
@Html.HiddenFor(m => m.Login.Name)

または、回避策で説明したとおりに実行します。つまり、IDに基づいてデータベースを再クエリします。これは不格好に見えるかもしれませんが、これは物事を行うための完全に有効な方法です。これは、あちこちに隠されたフィールドを渡す必要がないためです。

于 2012-07-11T04:18:48.240 に答える
1

返されるEstimateオブジェクトは、ビューのフィールド(および任意のBind属性)によって制限されます。必要なプロパティの非表示フィールドを追加するか、コンテキストからオブジェクトを再読み込みします。

注意点(私がこの回答を長い間死んだ質問に投稿している理由)は、EF6の場合、部分的にEntityState.Modifiedの.SaveChangesの後にオブジェクトをコンテキストからリロードすると(賢いため)、エンティティのCACHEDおよび不完全なバージョンが提供されます。.Findまたは.Whereの代わりにcontext.Entity(estimate).Reload()を実行する必要があります

于 2015-02-26T18:02:20.150 に答える
0

MVCには、ビューステートの概念や、ビュー内のデータを自動的に永続化する概念はありません。POSTを介して返されるプロパティは、フォームフィールドとしてフォームに存在する必要があります。この場合、を格納するための非表示フィールドが必要になりLoginIDます。

@Html.HiddenFor(m => m.LoginID)
于 2012-07-10T23:48:46.607 に答える
0

私はあなたと同じようなケースを持っています。アクション後、データベースから元のアイテムをプルし、必要に応じて、編集したすべてのプロパティをプルしたアイテムにコピーし、コピーしたプロパティ(編集される可能性のあるもの)で元のアイテムを保存しますユーザーによる)、または投稿されたモデルに不足しているプロパティを入力して保存します。これが正しい方法かどうかはわかりませんが、私にとってはうまくいきます。dbから元のアイテムをプルすると、必要な任意のプロパティにアクセスできます(ユーザーがそれを変更できなかった場合)。

例:

 [Authorize]
        public ActionResult Edit(int id)
        {
            var movie = movieService.GetMovieById(id);
            if (new UserService().Current().UserId == movie.UserID)
            {
                EditMovieModel model = new EditMovieModel(id);
                return View(model);
            }
            else
            {
                throw new System.Web.HttpException(403, "403 Forbidden");
            }
        }

        [HttpPost]
        [Authorize]
        public ActionResult Edit(Movie movie)
        {
            var realMovie = movieService.GetMovieById(movie.ID);
            if (new UserService().Current().UserId == realMovie.UserID)
            {
                realMovie.Text = HtmlSanitizer.sanitize(movie.Plot);
                realMovie.CategoryID = movie.CategoryID;
                movieService.Update(realMovie);
            }
            else
            {
                throw new System.Web.HttpException(403, "403 Forbidden");
            }
            return RedirectToAction("Movie", new { id = realMovie.ID, title = realMovie.Permalink });
        }
于 2012-07-11T00:12:14.177 に答える