0

私はMVC3に比較的慣れておらず、SQL Server、EF4などを使用して、デフォルトのMicrosoftメンバーシッププロバイダーで事前に読み込まれたアカウントを処理する必要があるWebサイトを開発しています.SOの誰かの助けを借りて、いくつかの進歩がありました. 、それを支援するために ActionMethodSelectorAttribute が正しく機能しています。

つまり、プロファイル ページ (www.mysite.com/profile/4) をロードしようとする試みの一部として誰かの ID を確認すると、その 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' の非静的メンバーにアクセスできません

...データベースの下でエラーが強調表示されています。

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;
    }
    }

...間違いなくホームコントローラーの中に落ちます。

編集#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;
    }
}

claim.Claimed1.Value != null; 警告が表示されます。「bool」型の値は「bool?」型の「null」と決して等しくないため、式の結果は常に「true」になります。

ただし、NULL値を処理するために何かが必要ですよね?

4

1 に答える 1

1

あなたのコードは実際にはもっとこのように見えると思いますよね?

public class HomeController : Controller
{
    public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
    {
        ...
    }
}

属性クラスを、コントローラー内にネストされていない第1レベルのクラスにする必要があります。次に、独自のdbインスタンスを指定する必要があります。

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場合、静的変数ではないため、インスタンス変数にアクセスできないためです。属性は実際にはネストされたクラスであってはならず、独自の個別のインスタンス変数を持っている必要があります。つまり、コントローラーの変数を作成してこれを解決しようとしないでください。dbstatic

于 2012-05-19T22:24:35.803 に答える