2013-08-19 74 views
6

我需要創建一些幫助控制器操作和相關的視圖,我希望能夠(有條件地)禁用生產。ASP.NET MVC如何禁用生產中的調試路線/視圖?

單程圍繞RegisterRoutes()正文中的特定路線的編譯指示,但這根本不靈活。

web.config中的設置會一樣好,但我不確定如何掛鉤。

如何建立「插件」項目如Glimpse或菲爾哈克的老Route Debugger做到這一點?

我寧願做一些不是一些簡單的YAGNI ...

回答

2
@if (HttpContext.Current.IsDebuggingEnabled) 
{ 
} 

public class UrlInformation 
{ 
    [XmlElement(ElementName = "ActionName")] 
    public string ActionName { get; set; } 

    [XmlElement(ElementName = "ControllerName")] 
    public string ControllerName { get; set; } 

    [XmlElement(ElementName = "AreaName")] 
    public string AreaName { get; set; } 
} 

班XML Serializaion

[XmlTypeAttribute(AnonymousType = true)] 
public class clsUrlInformation 
{ 
    [XmlElement("Files")] 
    public List<UrlInformation> Url { get; set; } 

    public clsUrlInformation() 
    { 
     Url = new List<UrlInformation>(); 
    } 
} 

示例XML(這裏定義你的調試操作方法/控制/地區名稱)

<?xml version="1.0" ?> 
<Url> 
    <Files> 
    <AreaName></AreaName> 
    <ControllerName>Home</ControllerName> 
    <ActionName>Index</ActionName> 
    </Files> 
    <Files> 
    <AreaName></AreaName> 
    <ControllerName></ControllerName> 
    <ActionName></ActionName> 
    </Files>      
</Url> 

行爲過濾

public class MyActionClass : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(
             ActionExecutingContext filterContext) 
    { 

比方說,你有XML。 XML包含有關區,操作方法名稱和控制器名稱

var xml = 
@"<?xml version=""1.0"" ?> 
<Url> 
    <Files> 
    <AreaName></AreaName> 
    <ControllerName>Home</ControllerName> 
    <ActionName>Index</ActionName> 
    </Files> 
    <Files> 
    <AreaName></AreaName> 
    <ControllerName></ControllerName> 
    <ActionName></ActionName> 
    </Files>      
</Url>"; 

做XML序列化信息和轉換XML類的列表。

 var serializer = new XmlSerializer(typeof(clsUrlInformation), 
           new XmlRootAttribute("Url")); 
     using (var stringReader = new StringReader(xml)) 
     using (var reader = XmlReader.Create(stringReader)) 
     { 
      clsUrlInformation result = 
        (clsUrlInformation)serializer.Deserialize(reader); 
      RouteData Route = 
        filterContext.Controller.ControllerContext.RouteData; 
      String controller = Convert.ToString(Route.Values["controller"]); 
      String action = Convert.ToString(Route.Values["action"]); 
      String area = Convert.ToString(Route.DataTokens["area"]); 

比較XML當前的動作,以顯示404個

  foreach (var item in result.Url) 
      { 
       if (HttpContext.Current.IsDebuggingEnabled && 
          controller == item.ControllerName && 
           action == item.ActionName  && 
            area == item.AreaName) 
       { 
        filterContext.Result = new HttpNotFoundResult(); 
        return; 
       } 
      } 
     } 

     base.OnActionExecuting(filterContext); 
    } 
} 

@CristiDiaconescu:提的XML文件中的調試網址將更加靈活。爲什麼?因爲,稍後您可以在XML中進行修改,以增加/減少/更新url信息,而無需更改代碼,也無需部署dll。不是嗎?

+0

你的前兩種方法看起來像剃刀代碼,此時它可能已經太晚了 - 我寧願有一個(列表)「調試URL(S )',可以禁用 - 即擊中他們將返回404,而不是一個ustom(空?)頁面。然而,+1對於HttpContext.Current.IsDebuggingEnabled –

+0

@CristiDiaconescu:** [不要在代碼文件中提及路由,您可以在本文中提到的XML文件中提及](http://stackoverflow.com/a/ 18362259/2015869)** –

+0

@CristiDiaconescu:提及XML文件中的調試URL會更加靈活。爲什麼?因爲,稍後您可以在XML中進行修改,以增加/減少/更新url信息,而無需更改代碼,也無需部署dll。不是嗎? –

9

你也可以使用一個過濾器,例如某處拋出這個類:

public class DebugOnlyAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(
              ActionExecutingContext filterContext) 
     { 
      #if DEBUG 
      #else 
       filterContext.Result = new HttpNotFoundResult(); 
      #endif 
     } 
    } 

然後,你可以只下降到控制器和裝飾作用的方法(或整個控制器),你需要不與[DebugOnly]一起在生產中出現。

你也可以使用的filterContext.HttpContext.IsDebuggingEnabled而不是醜陋#if DEBUG我只是傾向於使用預編譯器指令,因爲決定是絕對不會採取任何CPU週期的方式。

相反,如果你想有一個全局篩選器來檢查一切針對幾個網址,註冊爲在Global.asax中的全局過濾器:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 

    filters.Add(new DebugActionFilter()); 
} 

然後,你可以查詢的網址或任何你想反對列表(此處顯示應用程序相關的路徑):

public class DebugActionFilter : IActionFilter 
{ 
    private List<string> DebugUrls = new List<string> {"~/Home/", 
                 "~/Debug/"}; 
    public void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (!filterContext.HttpContext.IsDebuggingEnabled 
      && DebugUrls.Contains(
         filterContext 
        .HttpContext 
        .Request 
        .AppRelativeCurrentExecutionFilePath)) 
     { 
      filterContext.Result = new HttpNotFoundResult(); 
     } 
    } 

    public void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
    } 
} 
+0

這看起來很乾淨。謝謝! –