MVC3使用路由或使用控制器逻辑?(MVC3 using routes or using contr

2019-09-17 06:08发布

我用MVC3相对较新,但我使用它,C#和EF4创建一个应用程序的网站。 我使用的路由是一样的,当我选择MVC3模式创建的默认微软的项目,没有什么特别的:

    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

...例如。 但是,客户端已要求了很多账户被预先生成并分发到选定的用户。 我已经工作了一种方法,通过SQL服务器来运行,它工作正常,所有账户得到创建(约一千)。 此外,我已经添加一个位字段(“声称”),可以帮助确定是否这些预生成的一个帐户已经被这些用户“激活”。

我的问题是,当用户被赋予一个链接来访问他们的(未激活)帐户,我应该使用测试做初始路由时,该网页上,以确定他们的帐户作为联合国要求和地方给他们别的完成进入细节到他们的帐户? 或者我应该让他们去同一个页面,其他人,并在标识此记录作为联合国声称控制器逻辑的东西,然后将它们发送到另一个页面,完成进入信息等? 是否有一个很好的理由做了另一种?

而关于人谁做了(或有印刷错误)在其ID值,像什么:

www.mysite.com/profile/40000000000

(和站点只有一千用户至今),应该是被同样处理,或完全通过不同的方式? (即,在一个场景中,我们要识别对尚未提出的现有帐户,而在另一个场景中,我们遇到弄清楚该帐户甚至不存在。)

任何帮助将不胜感激。

编辑:

我试图实现Soliah的建议解决方案,并就死在一个事实,即如果(ID!= 0)不喜欢的ID可能不是一个INT位。 我过去,现在,并试图想出一个办法做,如果有效部的检查,但可能我还没有不被视为一个INT的ID解决了这个问题? 东西肯定是不对的,即使我想其有效性我的数据库测试期间再次转换。 为什么我收到以下错误任何想法? 我在想什么?

    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值到布尔isActivated测试。 我的数据库中有一个视图(“声称”),它可以给回真/假值,取决于它被交到用户的个人资料的ID,但我没有看到添加的ID。 请问像什么Soliah编辑工作?

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((字符串)controllerContext.RouteData.Values来让他们的工作,他们似乎做(到这一点),我发现这里的格式: 绑定routevalue到属性一个对象,它是视图模型的一部分的

该生产线

var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();

在DB的错误。 部分,并显示错误消息如下:

不能访问外部类型经由嵌套类型“MySite.Controllers.HomeController”的非静态成员“MySite.Controllers.HomeController.UserAccountActivatedAttribute”

......这是一件好事,我努力试着与MSDN和堆栈搞清楚,只拿出空。 这是否环任何钟声?

Answer 1:

也有人建议多东西了,但让我把别的表在这里。

操作方法选择

为了保持你的控制器动作干净,你可以写一个动作方法选择属性,以创建两个简单的动作:

[ActionName("Index")]
public ActionResult IndexNonActivated(int id)
{
    ...
}

[ActionName("Index")]
[UserAccountActivated]
public ActionResult IndexActivated(int id)
{
    ...
}

这样,您就不会与你的行为让他们真的瘦了校验码处理。 选择过滤器将确保正确的行动将得到执行相关的用户账号激活状态。

你可以阅读更多关于动作选择属性在我的博客文章 ,但基本上你不得不写类似这样:

public class UserAccountActivatedAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }

        // get profile id first
        int id = int.Parse(controllerContext.RouteData.Values["id"] ?? -1);

        bool isActivated = // some code to get this state 

        return isActivated;
    }
}

而这基本上它。

这将有可能使无论用户访问他们的个人资料自己的帐户是否已经激活。 或者甚至停用一段时间以后......它会在后台无缝运行。

一个重要的优点

如果你有不同的名称,两个动作(如尤拉伊建议),一个用于主动型材等激活,你必须做两个检查,因为即使活跃用户将能够访问赋活作用:

profile/4 > for active profiles
profile/activate/4 > for inactive profiles

这两个动作应该是检查状态和情况下的状态不会“适合”重定向到对方。 这也意味着,每一个可能发生重定向时,配置文件将得到检查两次。 在每个动作。

操作方法选择将检查配置文件只有一次 。 不管是什么状态的用户配置文件在不在。



Answer 2:

我宁愿让我的控制器薄,把这个在行为过滤器,你可以在注释Index中的作用Profile控制器。

public class ValidProfileIdAttribute : ActionFilterAttribute {
  public override void OnActionExecuting(ActinExecutingContext filterContext) {
    int id;

    if (int.TryParse(filterContext.ActionParameters["Id"], id) && id != 0) {
        // Check if valid and behave accordingly here.
        var profile = db.Profiles.Where(q => q.ProfileId == id).FirstOrDefault();
    }
    base.OnActionExecuting(filterContext);
  }
}

OnActionExecuting方法将你的控制器的动作之前被调用。

在你的控制器:

[ValidProfileId]
public ActionResult Index(int id) {
  ...  
}


Answer 3:

我会建议有逻辑控制器,因为一旦他/她被激活,他们可以使用相同的链接来访问他们的个人资料。



Answer 4:

检查帐户是否被激活与否是应用逻辑的一部分,并且应所述控制器(或更深)的内部来实现。 在控制器,你可以未激活的用户重定向到任何其他控制器/动作完成激活。 URL的路由机制应路线简单地根据本发明的传入的URL的形状,并且不应联系数据库。



文章来源: MVC3 using routes or using controller logic?