Как обработать ошибку словаря нулевых параметров для маршрутов MVC3? - PullRequest
4 голосов
/ 15 марта 2012

Большинство маршрутов, которые я использую, основаны на маршруте по умолчанию, определенном в стандартном приложении MVC3:

 routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Однако, если у меня есть маршрут "/ Book / Update / 1" и1 'пропущено, потому что пользователь набрал адрес вручную без 1, выдается ошибка с нулевыми параметрами.Очевидно, мой маршрут требует этого 1 и не является обязательным, но я не буду определять собственный маршрут для каждого из моих действий.Если я включаю пользовательские ошибки, я не уверен, что это за тип ошибки, чтобы перенаправить на соответствующую страницу ошибки html.

Вопрос: Как мне обработать эту ошибку, как 404?Я не вижу никаких проблем с этим подходом, потому что реальность такова, что опускание номера Id на маршруте такое же, как 404 не найдено.

Или я что-то упускаю при разработке моих маршрутов?Кажется, довольно прямо вперед.

Спасибо.

Обновление: Я ценю ответы, приведенные ниже.Они оба разумные подходы.Для большей ясности в моем вопросе позвольте мне остановиться подробнее.Маршрут "/ Book / Update / 1" должен, на мой взгляд, иметь только одну единственную цель.Книга обновлений 1. Любое другое отклонение от этого должно дать сбой и перенаправить на 404. Я не вижу в этом никакого отличия от статической HTML-страницы, которая не существует.Я могу поспорить о функции, которая просто не включена в .net, я просто подумал, что может быть более простой способ.

Update2: Должен был вырыть немного глубже.Вот замечательный пример . Я нашел второй ответ наиболее полезным.

Ответы [ 3 ]

2 голосов
/ 15 марта 2012
public ActionResult Update(int? id)
{
    if (!id.HasValue) return HttpNotFound();

    //Debug.Assert(id.Value != null);
    ...
}
0 голосов
/ 21 сентября 2018

Опоздал на вечеринку, которую я знаю, но, надеюсь, это может помочь кому-то еще. Я взял ответ Джейми выше и расширил его, чтобы упростить его использование, чтобы вам не нужно было перечислять все параметры по отдельности, разрешать различные перенаправления от разных действий и автоматически учитывать параметры типа Nullable.

public class RequiredActionParametersAttribute : ActionFilterAttribute
{
    private readonly string _redirectUrlConfigKey;

    public RequiredActionParametersAttribute(string redirectUrlConfigKey)
    {
        _redirectUrlConfigKey = redirectUrlConfigKey;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (string.IsNullOrWhiteSpace(_redirectUrlConfigKey))
            return;

        var redirectUrl = ConfigurationManager.AppSettings[_redirectUrlConfigKey];
        if (string.IsNullOrWhiteSpace(redirectUrl))
            return;

        var actionDescriptor = filterContext.ActionDescriptor;
        var parameterDescriptors = actionDescriptor.GetParameters();

        foreach (var parameter in filterContext.ActionParameters)
        {
            if (parameter.Value == null)
            {
                var parameterDescriptor = parameterDescriptors.First(p => p.ParameterName == parameter.Key);
                if (!IsNullableType(parameterDescriptor.ParameterType))
                {
                    filterContext.Result = new RedirectResult(redirectUrl);
                    break;
                }
            }
        }
    }

    private static bool IsNullableType(Type type)
    {
        return Nullable.GetUnderlyingType(type) != null;
    }
}

Тогда на действии

    [RequiredActionParameters("DetailsPageExceptionRedirect")]
    public ActionResult Details(int param1, int param2, bool param3, int? param4)

Вы можете добавить различные перенаправления для различных действий в файл конфигурации и передать ключ конфигурации в фильтр действий. Затем он проверит существование каждого параметра и, если он имеет значение null, проверит, является ли он обнуляемым типом, а затем, если нет, перенаправит в указанное вами местоположение.

0 голосов
/ 30 мая 2015

У меня тоже была эта проблема, я создал фильтр действий многократного использования, в котором я указал необходимые параметры.

Фильтр действий:

  public class RequiredActionParameters : ActionFilterAttribute
{
    private readonly IEnumerable<string> _parameters;

    public RequiredActionParameters(params string[] parameters)
    {
        _parameters = parameters;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.IsChildAction && !filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            foreach (var parameter in _parameters)
            {
                if (filterContext.ActionParameters[parameter] == null)
                {
                    filterContext.Result = new RedirectResult("/Error/NotFound");
                    break;
                }
            }
        }
    }
}

О действии в контроллере:

 [RequiredActionParameters("restaurantId", "testId")]
 public ActionResult Details(long restaurantId, long testId)
 {
        View();
 }

Я протестировал его с помощью инструмента журнала ошибок elmah, и он не сообщил об ошибках.

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