ActionResult с разными параметрами

1

У меня есть простой вопрос о поведении ActionResult в ASP.NET MVC.

Мне нужно иметь два результата действия с тем же именем, но с разными параметрами. В частности, я хочу:

public class CarController : Controller
{
    [AuthorizeUser(AccessLevel = "New")]
    public ActionResult New()
    {
       return View("New");
    }

    [AuthorizeUser(AccessLevel = "New?type=2")]
    public ActionResult New(string type)
    {
       return View("NewCarType2");
    }
}

Я знаю, что я могу переименовать второй результат действия с другим именем, но если я хочу сохранить его в "новом"?

Я пробовал с route.maps без успеха. Я решил сделать это:

 public class CarController : Controller
{
    public ActionResult New (string type) {
        if(!string.IsNullOrEmpty(type) && type.Equals("2")) {
            return NewCarType2()
        else
            return New()
        }
    }
    [AuthorizeUser(AccessLevel = "New?type=2")]
    private ActionResult NewCarType2()
    {
        return View("NewCarType2");
    }
    [AuthorizeUser(AccessLevel = "New")]
    private ActionResult New()
    {
        return View("New");
    }
}

но атрибут авторизации пользователя игнорируется.. также с общедоступной сигнатурой метода и атрибутом [NoAction].

Единственный способ, который я нахожу делать, что хочу, - это наследование класса:

public class CarController : Controller
{
    public virtual ActionResult New(string type)
    {
        if (!string.IsNullOrEmpty(type) && type.Equals("2"))
            return RedirectToAction("NewCarType2", "CarOverride");
        else
            return RedirectToAction("New", "CarOverride");
    }
}  
public class CarOverrideController : CarController
{
    [AuthorizeUser(AccessLevel = "New?type=2")]
    public ActionResult NewCarType2(string type)
    {
        return View("NewCarType2");
    }
    [AuthorizeUser(AccessLevel = "New")]
    public override ActionResult New(string type)
    {
        return View("New");
    }
 }

Но это правильный способ справиться с этой ситуацией (часть записывает имя ActionResults все разные)?

  • 0
    На самом деле это концепция перегрузки метода stackoverflow.com/a/436935/3354492 Этот пост ответит на ваши вопросы.
  • 0
    Другим способом управления этим может быть определение одного как действия [HttpGet], а другого как примечания о действии [HttpPost]: не уверен, что это то, что вам нужно, но это работает таким образом (в любом случае параметры должны быть разными)
Показать ещё 3 комментария
Теги:
asp.net-mvc
asp.net-mvc-4
actionresult

2 ответа

1

Есть 2 возможности делать то, что вы хотите.

Как ответил Пунеет в комментарии, вы можете перегрузить метод в контроллере, как указано в этом сообщении.

[ActionName("MyOverloadedName")]

или

Вы можете определить атрибут Route для метода контроллера и перенаправить действие с другого URL на этот метод. Для дальнейшего объяснения обратитесь к учебнику ASP.NET.

 [Route("URL")]
public ActionResult New(string type) { ... }
  • 0
    Но при первой возможности я должен вызвать 2 разных URL ("new" и "newOverloaded"), верно? Могу ли я иметь тот же URL («новый»), и выбор будет сделан относительно наличия или отсутствия параметра?
  • 1
    Другая возможность - определить 1 метод с необязательным параметром. Таким образом, у вас есть только 1 действие в вашем контроллере, и либо ваш параметр равен нулю, либо установлен по умолчанию (если пользователь не предоставляет данных). Это то, что вы хотите? msdn.microsoft.com/en-us/library/dd410269%28v=vs.100%29.aspx
Показать ещё 2 комментария
0

Я бы спросил, почему вам нужны два маршрута с тем же именем, которые делают две разные вещи?

Если все ваши атрибуты AuthorizeUser выполняет проверку роли пользователя, почему бы не сделать что-то похожее на:

public ActionResult New(string type)
{
    if (!string.IsNullOrWhiteSpace(type) && User.IsInRole("YOUR-ROLE-HERE"))
    {
        // Display NewCarType2 view if type requested and user is in correct role
        return View("NewCarType2");
    }

    // Default to New view if no type requested or user not in role
    return View("New");
}

Это вызовет как /new и /new?type=foo запросы.

  • 0
    Два маршрута делают почти одно и то же: например, визуализация контента различна. Ваш ответ - то, что я думаю сделать, но единственное отличие состоит в том, что атрибут AuthorizeUser не только проверяет роль пользователя с IsInRole. Я возьму логику этой авторизации в методе и буду использовать ее в ActionResult.
  • 0
    Если они делают почти одно и то же, то вы, вероятно, можете утверждать, что они должны идти по одному и тому же маршруту. Вы говорите, что это отвечает на ваш вопрос, или вам нужна дополнительная информация?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню