【问题标题】:ActionMethodSelectorAttribute unable to access types?ActionMethodSelectorAttribute 无法访问类型?
【发布时间】:2012-05-26 22:51:01
【问题描述】:

我对 MVC3 比较陌生,并且正在开发一个网站,该网站需要使用 SQL Server、EF4 等处理默认 Microsoft 会员提供程序中的预加载帐户。已经取得了一些进展,并在SO上的某个人,我已经让 ActionMethodSelectorAttribute 正常工作来帮助我。

即,当我们看到某人的 ID 作为他们尝试加载个人资料页面 (www.mysite.com/profile/4) 的一部分时,我们将查看该 ID/帐户是否已被“认领”。 (我的原贴在这里:MVC3 using routes or using controller logic?

不幸的是,在 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.UserAccountActivatedAttribute”访问外部类型“MySite.Controllers.HomeController”的非静态成员

...在 db 下突出显示错误。

有谁知道为什么在 ActionMethodSelectorAttribute 中,我似乎无法进行此调用? (注意:在同一个 Home 控制器中,我在 Public ActionResult 和 ViewResult 类中进行了许多类似的调用,没有任何错误。)

编辑

我的 HomeController.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;
    }
    }

...肯定属于 Home Controller。

编辑 #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;
    }
}

声称的.Claimed1.Value != null;给我一个警告:表达式的结果始终为“真”,因为“布尔”类型的值永远不会等于“布尔”类型的“空”?

但是,我必须有一些东西来处理 NULL 值,对吧?

【问题讨论】:

  • bool 永远不能为空。只有bool? 可以为空。是claim.Claimed1.Value 是bool 还是bool? 类型..?如果是bool,则不需要空检查,因为它永远不能为空。另一方面,如果它是 bool?,请使用以下命令检查 null:bool isActivated = claimed.Claimed1.Value.HasValue;
  • 不知何故我错过了这个,但我也会使用它。

标签: asp.net-mvc-3 entity-framework class controller asp.net-membership


【解决方案1】:

我认为您的代码实际上看起来更像这样,对吗?

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 来解决这个问题。

【讨论】:

  • 啊哈!我不知道。我将编辑我的问题以显示它的实际外观,然后尝试对此进行调查。谢谢,丹!
  • 我必须确保我的一些仍在 HomeController 中但依赖于 ActionMethodSelectorAttribute 的 ActionResult 仍然可以工作。 [ActionName("Profile")] public ActionResult IndexNonActivated(int?id) { return RedirectToAction("Claimed", new { id = id }); }
  • ActionMethodSelectorAttribute 不必与控制器位于同一类或文件中。您可以在操作方法上使用[UserAccountActivated] 语法将属性应用于控制器。返回并重新阅读:stackoverflow.com/a/10613782/304832
  • 啊,我去看看。谢谢丹。
  • 我仍然没有让它正常工作,但我更接近了;感谢您的所有帖子,丹。
猜你喜欢
  • 2022-07-28
  • 2020-09-09
  • 2021-04-08
  • 2023-03-21
  • 2021-09-19
  • 2020-08-02
  • 2017-08-16
  • 2017-01-22
  • 1970-01-01
相关资源
最近更新 更多