我对 MVC3 比较陌生,但我正在使用它、C# 和 EF4 来创建应用程序网站。我使用的路由与我选择 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" }
);
}
那里一切正常。我们使用默认的 Membership Provider,用户还获得一个 INT 值来标识他们的帐户。这使他们可以通过简单的路由轻松查看他们的个人资料,例如:
www.mysite.com/profile/4
...例如。但是,客户要求预先生成大量帐户并将其分发给选定的用户。我已经想出了一种通过 SQL Server 运行它的方法,它工作正常,所有帐户都已创建(大约一千个)。此外,我添加了一个位字段(“已声明”),可以帮助确定这些预先生成的帐户是否已被这些用户“激活”。
我的问题是,当用户获得访问其(未激活的)帐户的链接时,我是否应该在该页面上进行初始路由时使用测试将其帐户标识为无人认领并将其发送到其他地方以完成在他们的帐户中输入详细信息?或者我应该让他们和其他人一样进入同一个页面,并在控制器逻辑中有一些东西将该记录标识为无人认领,然后将他们发送到另一个页面以完成输入详细信息等?有充分的理由做一个而不是另一个吗?
那些在他们的 Id 值中编造(或有印刷错误)的人呢,比如:
www.mysite.com/profile/40000000000
(并且该站点到目前为止只有一千个用户),应该以类似的方式处理,还是完全通过不同的方式处理?(即,在一种情况下,我们正在识别尚未声明的现有帐户,而在另一种情况下,我们必须确定该帐户甚至不存在。)
任何帮助将不胜感激。
编辑:
我正在尝试实施 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 值放入 bool isActivated 测试中。我的数据库有一个视图('Claimed'),它可以返回一个真/假值,具体取决于它所传递的用户配置文件 ID,但我看不到在哪里添加 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 才能让它们工作,他们似乎这样做了(到那时)。我在这里发现了格式:Bind a routevalue to a property作为视图模型一部分的对象
线
var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();
数据库上的错误。部分,错误消息如下:
无法通过嵌套类型“MySite.Controllers.HomeController.UserAccountActivatedAttribute”访问外部类型“MySite.Controllers.HomeController”的非静态成员
...这是我努力尝试用 MSDN 和 Stack 来解决的问题,但结果却是空的。这会敲响警钟吗?