Как перенаправить на действие с параметрами из другого действия без передачи параметров?

Ниже, в CreateTest, в случае успеха я хочу перенаправить на тесты из CreateTest.

Я хочу сделать что-то вроде следующего:

    public ActionResult Tests(int ID, string projectName)
    {
        TestModel model = new TestModel (ID, projectName);
        return View(model);
    }

 [HttpPost]
    public ActionResult CreateTest(TestModel model)
    {
        try
        {
            return RedirectToAction("Tests");
        }
        catch (Exception e)
        {
            ModelState.AddModelError("Error", e.Message);
            return View(model);
        }
    }

person learning    schedule 24.02.2011    source источник


Ответы (3)


Вам может потребоваться предоставить аргументы при перенаправлении:

return RedirectToAction("Tests", new { 
   ID = model.ID, 
   projectName = model.ProjectName 
});

и URL-адрес, на который вы будете перенаправляться, теперь будет выглядеть примерно так:

/Foo/Tests?ID=123&projectName=abc

person Darin Dimitrov    schedule 24.02.2011
comment
Спасибо, а как вернуть сообщения об ошибках? public ActionResult CreateTest (модель TestModel) { попробуйте { return RedirectToAction (тесты); } catch (Exception e) { ModelState.AddModelError(Error, e.Message); вернуть представление (тесты); } } - person learning; 24.02.2011
comment
@ user281180, вы также можете передать их в строке запроса: new { ID = model.ID, projectName = model.ProjectName, errorMessage = "Some error message" }. Но из того, что я вижу, в случае ошибки, которую вы не перенаправляете, вы просто визуализируете представление, что является правильным способом сделать это, поэтому вы можете напрямую получить доступ к сообщению об ошибке внутри представления, поскольку оно добавляется к состоянию модели. - person Darin Dimitrov; 24.02.2011
comment
@Darin Its not working, im с сообщением об ошибке: элемент модели, переданный в словарь, имеет тип «f__AnonymousType1`2[System.Int32,System.String]», но для этого словаря требуется элемент модели типа «MvcUI.Models.TestModel». '. - person learning; 24.02.2011
comment
при использовании return RedirectToAction(Tests, new {ID = model.ID, projectName = model.ProjectName}); - person learning; 24.02.2011
comment
@Darin У меня также появляется сообщение об ошибке: словарь параметров содержит нулевую запись для параметра «ID» необнуляемого типа «System.Int32» для метода «System.Web.Mvc.ActionResult Tests (Int32, System.String) ' в 'MvcUI.Controllers.ProjectController'. Необязательный параметр должен быть ссылочным типом, типом, допускающим значение NULL, или быть объявленным как необязательный параметр. Имя параметра: параметры - person learning; 24.02.2011
comment
@ user281180, я не знаю, откуда взялся этот анонимный тип. Сначала попробуйте жестко закодировать значения: return RedirectToAction("Tests", new { ID = "123", projectName = "abc" });. Убедитесь, что параметр ID не пуст, поскольку в действии целевого контроллера он не может принимать значение NULL. При необходимости вы можете сделать его целым числом с нулевым значением. - person Darin Dimitrov; 24.02.2011
comment
@Darin Фрагмент кода public ActionResult CreateTest (модель TestModel) { try { return RedirectToAction (Tests); } catch (Exception e) { ModelState.AddModelError(Error, e.Message); вернуть представление (тесты); } } тоже не работает. - person learning; 24.02.2011
comment
@Darin, its with the above code that I am having the eror message : he model item passed into the dictionary is of type '<>f__AnonymousType12[System.Int32,System.String]», но для этого словаря требуется элемент модели типа «MvcUI.Models.TestModel». - person learning; 24.02.2011

Я знаю, что это немного старо, но...

Что я делал в прошлом, так это то, что класс «MessageArea» выставлялся как свойство на моем базовом контроллере, от которого в конечном итоге наследуются все мои контроллеры. Свойство фактически хранит экземпляр класса в TempData. MessageArea имеет метод Add(), который принимает строковое сообщение и тип перечисления (например, Success, Error, Warning, Information).

Затем у меня есть партиал, который отображает любые сообщения в MessageArea с соответствующим стилем в соответствии с типом сообщения.

У меня есть метод расширения HTMLHelper RenderMessageArea(), поэтому в любом представлении я могу просто сказать @Html.RenderMessageArea(), метод и партиал заботятся о нулях, и ничего не выводится, если нет сообщений.

Поскольку данные, хранящиеся в TempData, выдерживают только 1 запрос, это идеально подходит для случаев, когда вы хотите, чтобы ваше действие перенаправляло, но на целевой странице отображалось 1 или более сообщений, например. ошибка, неавторизованная страница и т. д. Или если вы добавляете элемент, но затем возвращаетесь на страницу индексного списка.

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

РЕДАКТИРОВАТЬ, ПРИМЕР:

public class MessageAreaModel {
   public MessageAreaModel() {
       Messages = new List<Message>();
   }

   public List<Message> Messages { get; private set; }

   public static void AddMessage(string text, MessageIcon icon, TempDatadictionary tempData) {
       AddMessage(new Message(icon, text), tempData);
   }

   public static void AddMessage(Message message, TempDataDictionary tempData) {
       var msgArea = GetAreaModelOrNew(tempData);
       msgArea.Messages.Add(message);
       tempData[TempDataKey] = msgArea;
   }

   private static MessageAreaModel GetAreaModelOrNew(TempDataDictionary tempData) {
       return tempData[TempDataKey] as MessageAreaModel ?? new MessageAreaModel();
   }

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

Затем добавьте расширение HtmlHelper следующим образом:

public static void RenderMessageArea(this HtmlHelper html) {
    html.RenderPartial("MessageArea", 
        (MessageAreaModel)html.ViewContext.TempData[MessageAreaModel.TempDataKey] ?? MessageAreaModel.Empty);
    html.ViewContext.TempData.Remove(MessageAreaModel.TempDataKey);
}

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

person Peter    schedule 16.04.2013
comment
Добавил небольшой пример кода в ответ на мой вопрос. - person Peter; 27.02.2017

Сделайте int обнуляемым:

public ActionResult Tests(int? ID, string projectName){
    //...
}
person Rob    schedule 24.02.2011