0

わかりやすい名前 URL ルート スキームを使用しています。基本的に、プリンシパル ID とフレンドリ名の組み合わせを使用して、これを内部で ID (個人 ID) にマップすることができます。したがって、次のようなルートです。

    routes.MapRoute(string.Empty, "{friendlyname}/Products/{action}", new {controller = "Products", action = "List"});

次のような URL にマップします。

    Adam/Products/List

これはすべて正常に機能し、同様に必要な指定された人物の内部 ID を抽象化します。

問題は、ビューが多くの部分ビューで構成されていることです。@Html.Action メソッドを使用してレンダリングされる場合、最終的には PersonID が必要ですが、URL からは「フレンドリ名」しかわかりません。

私はしばらくこれについて考えてきましたが、私の心には2つの解決策があります。

  1. 部分ビューを返す各コントローラー アクション メソッドに「フレンドリ名」を渡します。内部的に、メソッドは現在ログインしている ID とフレンドリ名を検索する必要があります。これにより、PersonID が提供され、それ以降は効率的にクエリを実行できます。このアプローチの唯一の問題は、部分ビューが複数あるため、innefficeint である部分ビュー呼び出しごとに、現在ログインしている ID とフレンドリ名を照会することになり、このコードを 1 回だけ記述する必要があることです。

  2. 何らかの方法でビューでクエリを実行し、PersonID を取得して各 @Html.Action 呼び出しに渡すことができるようにすることで、部分的なビュー コントローラー メソッドでそのルックアップを実行する必要がなくなり、同じ共有情報についてデータベースへのラウンド トリップを節約できます。これに関する問題は、アプリケーションの残りの部分で使用する DI を使用して、ビューでこのクリーンリーを行う方法がわからないことです。

へのアプローチに関する考えは大歓迎です。

ありがとうございました、

アダム

4

3 に答える 3

1

Id をセッション変数に追加し、ビュー内から次のようにアクセスできます。

@{var personId = int.Parse(Session["PersonId"])}

次に、クライアントにヒットしたり、コントローラーにパラメーターを渡したりすることなく、親から部分ビューに直接渡すことができます。

アップデート

データベースへのラウンドトリップを行わずにそこで作業を行いたい場合は、Controller からセッション変数にアクセスすることもできます。

編集

プロパティをモデルに配置して、投稿の後ろにあるページに渡すと、モデルは投稿間で保持されません。

たとえば、コントローラーが次のことを行う場合:

[HttpPost]
public ActionResult DoSomething(ViewModel model)
{
   if(ModelState.IsValid)
   {
       // Logic Here
   }
   return View(model)
}

ページがリロードされると、モデルは ID を忘れてしまいます。

これにはいくつかの方法があります。@Html.HiddenFor(m => m.ID) を使用すると、レンダリングされた HTML にプロパティが配置されますが、これが本当に機密情報である場合は不適切です。

または、後続のポストバックごとにビュー モデルを再構築できます。

お役に立てれば

于 2012-04-13T14:36:56.557 に答える
0

属性を使用[Bind]して、モデル バインダーがバインディングに含める必要がある正確なプロパティを指定するかExclude、属性のパラメーターを使用してPersonIdを除外できます。

[HttpPost]
public ActionResult EditPerson([Bind(Exclude = "PersonId")] Person person)
{
    //do domething
}

[ReadOnly]モデル バインダーが理解してそのプロパティに割り当てない属性を使用することもできます。

[ReadOnly(true)]
public int PersonId{ get; set; }

ただし、最善の方法は、個別の ViewModel を使用することです。1 つは表示専用で、もう 1 つは編集用です。

public abstract class Person
{
   public string Name { get; set; }
   public string Surname { get; set; }

}

public class PersonCreateVM : Person
{
   //no PersonId here
}

public class PersonEditVM : Person
{
   public int PersonId{ get; set; }
}

このアプローチは「やり過ぎ」かもしれませんが、適切に使用し、AutoMapper http://automapper.codeplex.com/を使用すると、簡単に操作できます。

于 2012-04-14T10:33:32.160 に答える
0

マークが述べているように、これに対処するためにセッションを使用できますが、彼が最新情報で述べているように、私はモデルを使用しました。親View Controllerアクションがフレンドリ名を受け取る場合、ルックアップを実行でき、PersonIDをモデルに入れます。その後、部分レンダリングは、親View Controllerアクションのビューでモデル値を渡すことができます。例を以下に示します (これはデモ コードですが、うまくいけば要点が理解できると思います。実際のコードでは静的データ コンテキストを使用することはありません)。

ホームコントローラー

public class HomeController : Controller
{
    public ActionResult Index(string friendlyName)
    {
        int pupilId = Data.People.Single(x => x.Name == friendlyName).PersonId;
        HomeIndexViewModel homeIndexViewModel = new HomeIndexViewModel {PupilId = pupilId};

        return View(homeIndexViewModel);
    }
}

ホーム インデックス ビュー

@model SharingInformationBetweenPartials.Web.Models.HomeIndexViewModel
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>    
@Html.Action("DisplayPersonDetail", "Person", new {Model.PersonId})

次に、PersonController の DisplayPersonDetail メソッドは、渡された PersonId を使用して、必要なそれぞれのデータを提示できます。

public class PupilController : Controller
{
    [ChildActionOnly]
    public ActionResult DisplayPupilDetail(int pupilId)
    {
        Person person = Data.People.Single(x => x.PersonId == pupilId);
        return View(person);
    }
}

以前にこれだと思っていたことを試してみましたが、ViewModels プロパティが URL に表示されていたため、何か問題があったに違いありません。とにかく、これが同じようなことをしようとしている他の人の助けになることを願っています. ご不明な点がございましたら、お知らせください。

ありがとう、

アダム

于 2012-04-14T10:08:51.307 に答える