2015-03-25 4 views
1

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

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

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

На самом деле это концепция перегрузки методов http://stackoverflow.com/a/436935/3354492 Это сообщение ответит на ваши вопросы. – Puneet

+0

Другим способом управления этим может быть определение одного как действие [HttpGet], а другое как действие [HttpPost] примечание: не уверен, что это то, что вы хотите здесь, но оно работает таким образом (во всяком случае, параметры должны быть разными) –

+2

Определенно предлагайте НЕ использовать наследование здесь – timothyclifford

ответ

1

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

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

[ActionName("MyOverloadedName")] 

или

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

[Route("URL")] 
public ActionResult New(string type) { ... } 
+0

Но с первой возможностью я должен позвонить по 2 различным URL («новый» и «новый загруженный»)), правильно? Могу ли я иметь один и тот же URL-адрес («новый»), и будет сделан выбор относительно присутствия или меньше параметра? –

+1

Другая возможность - определить 1 метод с необязательным параметром. Таким образом, у вас всего 1 действие в вашем контроллере, и либо ваш параметр имеет значение null, либо установлен как значение по умолчанию (если пользователь не предоставляет никаких данных).Это то, что вы хотите? https://msdn.microsoft.com/en-us/library/dd410269%28v=vs.100%29.aspx – greenhoorn

+0

Да, я думаю, это способ. Я сделаю один метод с дополнительным параметром, и если значение будет пустым. Я проверю авторизацию для одной роли, иначе для другой. Если результат проверки будет правдой, я покажу страницу. Вместо этого [Маршрут («URL»)] Я могу указать URL-адрес, например «Car/New? Type = 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

Если они делают почти то же самое, то вы, вероятно, можете утверждать, что они должны быть в одном и том же маршруте. Вы говорите, что это отвечает на ваш вопрос или вам нужна дополнительная информация? – timothyclifford

Смежные вопросы