我对 MVC3 相对较新,并且正在开发一个网站,该网站需要使用 SQL Server、EF4 等处理默认Microsoft成员资格提供程序中的预加载帐户。 已经取得了一些进展,在SO上某人的帮助下,我已经让ActionMethodSelectorAttribute正常工作以帮助我。
也就是说,当我们看到某人的ID作为他们尝试加载个人资料页面(www.mysite.com/profile/4(的一部分时,我们将查看该ID/帐户是否已被"认领"。 (我的原始帖子在这里:MVC3 使用路由还是使用控制器逻辑?
不幸的是,在ActionMethodSelectorAttribute中,我花了很长时间进行相对简单的数据库调用来确定该帐户是否已声明/未声明。
这是我当前的代码状态:
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;
}
}
该行
var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();
"数据库"部分上的错误,错误消息如下:
无法通过嵌套类型"MySite.Controllers.HomeController.UserAccountActivated Attribute"访问外部类型"MySite.Controllers.HomeController"的非静态成员
。错误在数据库下突出显示。
有谁知道为什么在ActionMethodSelectorAttribute中,我似乎无法进行此调用? (注意:在同一个家庭控制器中,我在 Public ActionResult 和 ViewResult 类中进行了许多类似的调用,没有任何错误。
编辑
我的主控制器.cs如下所示:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MySite.Models;
namespace MySite.Controllers
{
public class HomeController : Controller
{
private MySiteEntities db = new MySiteEntities();
public ActionResult Index()
{
ViewBag.Message = "Welcome to MySite.com!";
return View();
}
//several other ActionResults - create, delete, etc.
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;
}
}
。它绝对属于家庭控制器。
编辑#2:
更接近,但值始终为 TRUE 的小问题。
public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
private MySiteEntities db = new MySiteEntities();
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
int id = int.Parse((string)controllerContext.RouteData.Values["id"]);
var data = new MySiteEntities();
var claimed = db.Claimeds.FirstOrDefault(c => c.ProfileId == id);
bool isActivated = claimed.Claimed1.Value != null;
return isActivated;
}
}
该称。声明1.值 != 空;给我一个警告:表达式的结果总是"true",因为类型"bool"的值永远不会等于类型"bool"的"null"。
但是,我必须有一些东西来处理 NULL 值,对吧?
我认为你的代码实际上看起来更像这样,对吗?
public class HomeController : Controller
{
public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
...
}
}
您需要使属性类成为第一级类,而不是嵌套在控制器中。然后,您需要为其提供自己的数据库实例。
public class HomeController : Controller
{
...
}
public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
private readonly CustomDbContext db = new CustomDbContext();
public override bool IsValidForRequest(ControllerContext controllerContext,
MethodInfo methodInfo)
{
// original code here
}
}
这样做的原因是,当属性类嵌套在控制器类中时,它无法访问db
实例变量,因为它不是静态变量。您的属性实际上不应该是嵌套类,而应该有自己单独的实例变量。换句话说,不要试图通过使控制器的db
变量static
来解决此问题。