[英]ASP.NET MVC - Verify the Existence of a Route
我的ASP.NET MVC應用程序有一個場景,其中用戶輸入可以直接影響對RedirectToAction()的調用目標(通過字符串),並且如果輸入不正確導致用戶有可能創建運行時錯誤。他們請求不存在的操作。 我想徹底避免此問題,但我想以最省力的方式做到這一點,因為必須對大量請求進行處理。 話雖如此,反射將是一個可行的解決方案,用於確認/ Controller / ActionName實際上存在,但是反射是一項非常繁重的操作。
確認ASP.NET MVC應用程序中的給定URL實際上與控制器操作關聯的最佳方法是什么?
一種方法是擁有用戶輸入數據的允許值列表。 例如,如果用戶輸入了她喜歡的顏色:
// userColour = the user set colour
var allowableColours = new [] { "Red", "Blue", "Green" };
if (!allowableColours.Contains(userColour))
{
// Set to a default colour.
userColour = "Red";
}
return RedirectToAction(userColour, "Colour");
盡管它不像查看路由表那樣動態,但它很快,並且您可以確信他們沒有輸入一些惡意的值來破壞您的路由。
一種快速而粗略的選擇是直接點擊網址,以下代碼可以幫助您快速進行測試,
注意:您實際上是在訪問您的網站,並意識到這在您的應用程序中意味着什么。
這有助於我們在某些集成測試中診斷一些環境問題。
var urlToExec = "http://yoursite.com/" + controllerAndAction;
var wr = (HttpWebRequest) WebRequest.Create(urlToExec);
try
{
var resp = (HttpWebResponse)wr.GetResponse();
if (resp.StatusCode != HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.NotFound)
//it was found
}
catch (Exception ex)
{
//404 or other http error
//404 and the like result in GetResponse() throwing an exception
//this was verified by having actions return via:
//'return new HttpNotFoundResult("This doesn't exist");'
}
我最終在這里采取的路線是反射和包含在Application []中存儲的相關Controller中所有有效動作的Dictionary(字典)。 通過檢查方法的ReturnType並確認它是ActionResult(或從ActionResult派生)並且它不是Private,可以確定有效的Action。 我可以再做一些檢查,但是現在這些已經足夠了。
public static bool MethodIsAction(MethodInfo method)
{
if (method == null)
throw new ArgumentNullException("Invalid Parameter: method cannot be null.");
if (method.ReturnType != typeof(ActionResult) && method.ReturnType.BaseType != typeof(ActionResult))
return false;
if (method.IsPrivate)
return false;
return true;
}
動作字典是通過Application_Start中的以下方法構建的:
public static Dictionary<string, MethodInfo> GetActionDictionary(Type controller)
{
Dictionary<string, MethodInfo> dict = null;
var methods = controller.GetMethods().Where(MethodIsAction);
if (methods.Any())
{
dict = new Dictionary<string, MethodInfo>(StringComparer.OrdinalIgnoreCase);
foreach (var action in methods)
dict.Add(action.Name, action);
}
return dict;
}
當用戶請求限定動作時,我只需將動作名稱指向“字典”即可,如果該動作名稱存在MethodInfo,則將其調用。 盡管它仍然需要反射,但至少已對其進行了優化,以使其僅在應用程序運行時發生一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.