ASP.NET MVC - проверка существования маршрута - PullRequest
1 голос
/ 25 октября 2009

В моем приложении ASP.NET MVC есть сценарий, в котором пользовательский ввод может напрямую влиять на цель вызова RedirectToAction () (посредством строки), и есть вероятность, что пользователь может создать ошибку времени выполнения, если неправильный ввод приводит их к запросу о несуществующем действии. Я бы хотел полностью предотвратить эту проблему, но я бы хотел сделать это с наименьшими возможными затратами, поскольку это должно быть сделано при большом количестве запросов. При этом отражение будет жизнеспособным решением, которое можно использовать для подтверждения того, что / Controller / ActionName действительно существует, но отражение - довольно сложная операция.

Как лучше всего подтвердить, что данный URL-адрес в приложении ASP.NET MVC действительно связан с действием контроллера?

Ответы [ 3 ]

2 голосов
/ 25 октября 2009

Один из способов сделать это - получить список допустимых значений для введенных пользователем данных. Например, если пользователь ввел свой любимый цвет:

// 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");

Хотя это и не так динамично, как при просмотре таблицы маршрутизации, это будет быстро, и вы можете быть уверены, что пользователь не вводил какое-то вредоносное значение, которое мешало вашей маршрутизации.

1 голос
/ 08 января 2012

Быстрый и более грубый вариант - просто нажать на ссылку, следующий код может помочь вам быстро что-то проверить,

Примечание: вы действительно заходите на свой сайт и знаете о том, что это означает в вашем приложении.

Это было полезно для диагностики некоторых проблем среды в некоторых интеграционных тестах.

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");'
}
0 голосов
/ 29 октября 2009

Маршрут, который я здесь выбрал, - это отражение и словарь, содержащий все действительные действия в соответствующем контроллере, который хранится в приложении []. Действительное действие определяется путем проверки метода ReturnType и проверки того, что он является (или является производным от) ActionResult и не является частным. Я мог бы сделать еще несколько проверок, но пока их достаточно.

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, я вызываю его. Хотя он все еще требует отражения, он по крайней мере оптимизирован, так что это происходит только один раз во время работы приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...