параметр идентификатора маршрутизации MVC asp.net - PullRequest
16 голосов
/ 30 апреля 2010

Я работаю над сайтом в asp.net mvc. У меня есть маршрут

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

, который является маршрутом по умолчанию. И у меня есть метод

public ActionResult ErrorPage(int errorno)
{
    return View();
}

Теперь, если я хочу запустить этот код с http://something/mycontroller/Errorpage/1 это не работает Но если я изменю имя параметра на id с errorno оно работает.

Обязательно ли иметь одинаковое имя параметра для этого метода? Или мне нужно создавать отдельные маршруты для таких ситуаций?

Ответы [ 6 ]

16 голосов
/ 29 ноября 2010

Итак, у вас есть параметр с именем errorno, и вы хотите, чтобы он имел значение из параметра id. Это, очевидно, проблема связывания.

Как ее решить:

  1. создать класс для подшивки модели:

    public class ParameterBinder : IModelBinder
    {
        public string ActualParameter { get; private set; }
    
        public ParameterBinder(string actualParameter)
        {
            this.ActualParameter = actualParameter;
        }
    
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            object id = controllerContext.RouteData.Values[this.ActualParameter];
            return id;
        }
    }
    
  2. создать пользовательский атрибут для привязки пользовательской модели:

    [AttributeUsage(AttributeTargets.Parameter)]
    public class BindParameterAttribute : CustomModelBinderAttribute
    {
        public string ActualParameter { get; private set; }
    
        public BindParameterAttribute(string actualParameter)
        {
            this.ActualParameter = actualParameter;
        }
    
        public override IModelBinder GetBinder()
        {
            return new ParameterBinder(this.ActualParameter);
        }
    }
    
  3. применить новый атрибут к параметрам вашего действия по мере необходимости:

    public ActionResult ErrorPage(
    [BindParameter("id")]
    int errorno)
    {
        return View();
    }
    

Теперь ваш errorno будет иметь значение, которое было передано как id для вашего URL.

Примечание: вы можете удалить параметр id из приведенного выше примера, если вы уверены, что он нужен только для id.

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

16 голосов
/ 30 апреля 2010

Вариант 1

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

public ActionResult ErrorPage(int id)
{
    return View();
}

Вариант 2

routes.MapRoute(
    "Default",
    "{controller}/{action}/{errorno}",
    new { controller = "Home", action = "Index", errorno = UrlParameter.Optional }
);

public ActionResult ErrorPage(int errorno)
{
    return View();
}

Вариант 3

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

public ActionResult ErrorPage(int id)
{
    int errorno = id;
    return View();
}
6 голосов
/ 19 ноября 2016

использовать префикс атрибута bind:

public ActionResult Customer([Bind(Prefix = "id")]string cname) {}
1 голос
/ 01 февраля 2012

@ Parminder Маршрут по умолчанию может обрабатывать все действия с одним параметром «id». И я думаю, что не каждому действию нужен этот параметр. Поэтому я меняю свой маршрут по умолчанию

routes.MapRoute(
    "Default", 
    "{controller}/{action}", 
    new { controller = "Home", action = "Index"} 
);

и вы можете добавить новый маршрут:

routes.MapRoute("errorpage", "yourcontroller/errorpage/{errorno}",
    new {controller="controllername", action="errorpage"});

это просто обработать ваше имя контроллера "имя контроллера". Если вы хотите обработать все контроллеры, вы можете добавить это:

routes.MapRoute("errorpage", "{controller}/errorpage/{errorno}",
    new {controller="controllername", action="errorpage"});

Этот метод создаст очень много кода в global.asax, если вам нужно много пользовательских маршрутов.

0 голосов
/ 30 апреля 2010

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

global.asx

routes.MapRoute(

                        "Default", // Route name
                        "{controller}/{action}/{id}", // URL with parameters
                        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults

                );

myController

public ActionResult ErrorPage(int id)

    {
        return View();
    }
0 голосов
/ 30 апреля 2010

Вы можете переименовать параметр в корне по умолчанию (что, вероятно, не очень хорошая идея) или переименовать его в методе действия. Добавление другого корня не поможет, потому что он будет таким же, как и по умолчанию, и при наличии URL-адреса механизм маршрутизации не сможет различить два и всегда будет занимать первое место в списке.

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