私はMVC3に比較的慣れていませんが、MVC3、C#、およびEF4を使用してアプリケーションWebサイトを作成しています。私が使用しているルーティングは、MVC3パターンを選択したときに作成されたデフォルトのMicrosoftプロジェクトと同じですが、特別なことは何もありません。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "MySite.Controllers" }
);
}
そして、すべてが正常に機能しています。デフォルトのメンバーシッププロバイダーを使用しており、ユーザーはアカウントを識別するINT値も取得します。これにより、次のような単純なルーティングを使用して、プロファイルを非常に簡単に確認できます。
www.mysite.com/profile/4
...例えば。ただし、クライアントは、多くのアカウントを事前に生成して、選択したユーザーに配布するように要求しています。私はSQLServerを介してそれを実行する方法を考案しましたが、それは正常に機能し、すべてのアカウントが作成されました(約1,000)。さらに、これらの事前生成されたアカウントの1つがこれらのユーザーによって「アクティブ化」されているかどうかを識別するのに役立つビットフィールド(「Claimed」)を追加しました。
私の質問は、ユーザーが(アクティブ化されていない)アカウントにアクセスするためのリンクを与えられた場合、そのページで最初のルーティングを行うときにテストを使用して、アカウントが未請求であることを識別し、別の場所に送信して終了する必要があるかどうかです。アカウントに詳細を入力しますか?または、他のすべての人と同じページに移動させ、このレコードを未請求として識別するコントローラーロジックに何かを入れてから、別のページに送信して詳細などの入力を完了する必要がありますか?どちらか一方を実行する正当な理由はありますか?
そして、次のように、Id値を構成する(または誤植がある)人々はどうでしょうか。
www.mysite.com/profile/40000000000
(そしてサイトにはこれまでのところ1000人のユーザーしかいません)、それは同じように扱われるべきですか、それとも完全に異なる手段で扱われるべきですか?(つまり、あるシナリオでは、まだ請求されていない既存のアカウントを特定し、別のシナリオでは、アカウントが存在しないことを把握する必要があります。)
どんな助けでも大歓迎です。
編集:
私はSoliahの提案した解決策を実装しようとしていますが、if(id!= 0)がIDがINTにない可能性があることを気に入らなかったという事実に少し行き詰まりました。私は今それを過ぎて、有効な部分であるかどうかをチェックする方法を見つけようとしていますが、おそらくIDがINTとして扱われないという問題を解決していませんか?データベースの有効性テスト中に再度変換しようとしていますが、間違いなく正しくありません。以下のエラーが発生する理由について何かアイデアはありますか?私は何が欠けていますか?
public class ValidProfileIdAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var id = (Convert.ToInt32(filterContext.ActionParameters["Id"]));
if (id != 0)
{
// Check if valid and behave accordingly here.
Profile profile = db.Profiles.Where(q => q.ProfileId == (Convert.ToInt32(id))).FirstOrDefault();
}
base.OnActionExecuting(filterContext);
}
}
Cannot implicitly convert type 'System.Linq.IQueryable<Mysite.Models.Profile>' to 'Mysite.Models.Profile'. An explicit conversion exists (are you missing a cast?)
編集#2:
私はロバートの提案に取り組んでおり、部分的に進歩しています。私のコードは現在次のようになっています:
public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
bool isActivated = // some code to get this state
return isActivated;
}
}
ブログエントリを読んだ後に私が得たもの、そして(信じられないかもしれませんが)この投稿:http://pastebin.com/Ea09Gf4B
物事を再び動かすために、ActionSelectorAttributeをActionMethodSelectorAttributeに変更する必要がありました。
ただし、方法がわからないのは、Id値をboolisActivatedテストに取り込むことです。私のデータベースには、渡されたユーザーのプロファイルIDに応じて、true / false値を返すことができるビュー('Claimed')がありますが、IDを追加する場所がわかりません。ソリアが編集したもののようなものはうまくいくでしょうか?
if (int.TryParse(filterContext.ActionParameters["Id"], id) && id != 0) {
bool isActivated = db.Claimed.Where(c => c.ProfileId == id).FirstOrDefault();
編集#3:
これが私の現在のコードの状態です:
public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
// get profile id first
int id = int.Parse((string)controllerContext.RouteData.Values["id"]);
var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();
bool isActivated = profile;// some code to get this state
return isActivated;
}
}
私にとっては、それらを機能させるためにint.Parse((string)controllerContext.RouteData.Valuesに変更する必要がありました。これは(その時点で)機能しているようです。)ここでフォーマットすることを発見しました:routevalueをプロパティにバインドするビューモデルの一部であるオブジェクトの
この線
var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();
dbのエラー。セクション、次のようなエラーメッセージが表示されます。
ネストされたタイプ「MySite.Controllers.HomeController.UserAccountActivatedAttribute」を介して外部タイプ「MySite.Controllers.HomeController」の非静的メンバーにアクセスできません
...これは私がMSDNとStackで熱心に理解しようとしたものですが、空になってしまいました。これはベルを鳴らしますか?