【问题标题】:MVC action names as constant string?MVC动作名称作为常量字符串?
【发布时间】:2014-02-25 09:59:16
【问题描述】:

我创建了以下代码来尝试摆脱与 MVC 操作名称相关的任何魔术字符串。开发人员可能会更改访问修改器并在页面中访问它。

private const string IndexAction = "Index";
public ActionResult Index(){
    //do stuff
}
public ActionResult Other(){
    // do stuff
    if(foo)
        return RedirectToAction(IndexAction);
    //don't foo
}

我从来没有在任何地方看到过这让我觉得这不是一个好主意,在编程的世界里,我怀疑我是第一个尝试这个的人。 问题: 将操作名称命名为不好的做法是否违反了 MVC 的任何原则。

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    基本上,使用常量是一个好主意(尽管根据我的经验,这在 MVC 中并不常见 - 如果您的控制器很小,也可能不需要)。按照您的建议,您可以将必须​​更改的点数从可能的几个减少到两个。

    如果你想把它减少到一个点,你也可以使用ActionName-attribute 来分配动作的名称,也可以使用常量。这打破了 MVC 中使用的约定,因此其他人可能需要更长的时间来理解系统,但具有将更改限制在一个位置的优势:

    private const string IndexAction = "Index";
    
    [ActionName(IndexAction)]
    public ActionResult Index(){
        //do stuff
    }
    public ActionResult Other(){
        // do stuff
        if(foo)
            return RedirectToAction(IndexAction);
        //don't foo
    }
    

    有关 ActionName 属性及其用途的详细信息,请参阅此question 及其答案。

    【讨论】:

      【解决方案2】:

      有时会在给定的控制器中创建一个带有动作名称的 Enum 像这样:

      public class HomeController : Controller
      {
      
          public enum Actions
          {
              Index,
              About,
              Contact,
              Hosting,
              Hartware
          } 
      

      我在其中创建一个扩展方法并使用与我想扩展的原始类相同的命名空间,在这种情况下,我将使用 System.Web.Mvc 并创建以下类

      namespace System.Web.Mvc
      {
          public static class MvcExtentions
          {
              /// <summary>
              /// Generates a fully qualified URL to an action method by using the specified action Name.
              /// </summary>
              /// <param name="sender">used for the generate the logic</param>
              /// <param name="actionName">an enum that will be used to generate the name from</param>
              /// <returns>a fully qualified url to the action in the current controller</returns>
              public static string Action(this UrlHelper sender, Enum actionName)
              {
                  return sender.Action(actionName.ToString());
              }
          }
      }
      

      然后在我的 Razor ViewPage 中添加 Using 以到达我的页面顶部的“HomeController”,其中 ByteStream 是我的项目的名称

      @using ByteStream.Web.Controllers
      @{
          ViewData["Title"] = "Home Page";
      }
      

      生成链接我然后使用

      <a class="btn btn-default btn-default" ref="@Url.Action(HomeController.Actions.Hosting))">
       Learn More
      </a>
      

      【讨论】:

        【解决方案3】:

        C# 中的 nameof 功能使您可以轻松地做到这一点。您的 RedirectToAction 调用如下所示:

        return RedirectToAction(nameof(Index));
        

        nameof(Index) 返回字符串“Index”。如果您不小心更改了 Index 函数的名称,则此行将产生编译器错误。 另外,对 Index 进行重命名重构也会改变这一点,Find All References 命令也会指向它。但是如果你想重定向到不同控制器中的方法,那么这不会很好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-17
          • 2013-12-03
          • 2011-09-05
          • 1970-01-01
          • 2018-08-16
          • 1970-01-01
          • 2011-07-13
          • 2011-10-25
          相关资源
          最近更新 更多