Вызвать действие другого контроллера и вернуть его результат в View - PullRequest
0 голосов
/ 26 июля 2010

У меня есть сценарий, в котором мне нужны следующие функции:

In View I have call as:
$.ajax({
    type: "POST",
    async: false,
    dataType: 'json',
    url: "ControllerA/ActionA",
    data: { var1: some_value },
    success: function (data) {
        if (data == true) {
            form.submit();
        }
        else if (data == false) {
    }
});

// In ControllerA
public JsonResult ActionA(string var1)
{
    /*
 Some manipulation and calculations
 */
 _slist = RedirectToAction("ActionC", "ControllerB", new { var1 = some_value});
 string = _slist.First().ToString();

    return RedirectToAction("ActionB", "ControllerB", new { var1 = var2 });
}

// In ControllerB
public JsonResult ActionB(string var1)
{
    /*
 Some manipulation and calculations
 */

    return Json(false, JsonRequestBehavior.AllowGet);
}

public SelectList ActionC(string var1)
{    
 /*
 Some manipulation and calculations
 */

 Session["STRING"] = some_value;

 return new SelectList(_storeOrderTimeDictionaryList, "Value", "Key");
}

Мне нужен JsonResult на странице просмотра, но проблемы таковы:

  1. Поскольку RedirectToAction возвращает результат redirecttorouteres, я не могу напрямую вернуть JSonResut
  2. Поскольку мне нужен сеанс в ActionC, я не могу создать экземпляр Controller и вызвать действие.

Ответы [ 2 ]

1 голос
/ 27 июля 2010

Возможно, это не лучший подход ...

Трудно сказать, но подсушивание контроллеров и выведение бизнес-логики могут помочь.Похоже, вы хотите сохранить функциональность действий B и C.

$.ajax({
    type: "POST",
    async: false,
    dataType: 'json',
    url: "ControllerA/ActionA",
    data: { var1: some_value },
    success: function (data) {
        if (data == true) {
            form.submit();
        }
        else if (data == false) {
    }
});


public Class CalculationsA
{
   public void DoCalculation() {}
}

public Class CalculationsB
{
   public void DoCalculation() {}
}

public Class CalculationsC
{
   public IQueryable<somethign> DoCalculation() {}
}


//_a is declared in Controller A as CalculationsA
//_b is declared in Controller B as CalculationsB 
//_c is declared in Controller C as CalculationsC

// In ControllerA
public JsonResult ActionA(string var1)
{
  _a.DoCalculation(); 
  _slist = _b.DoCalculation().First().ToString();

  Session["STRING"] = some_value;
  _c.DoCalculation();          

  /* your other logic... */

  return Json(retval, JsonRequestBehavior.AllowGet);
}

// In ControllerB
public JsonResult ActionB(string var1)
{
    _b.DoCalculation();

    return Json(false, JsonRequestBehavior.AllowGet);
}

public SelectList ActionC(string var1)
{    
 _c.DoCalculation();

 Session["STRING"] = some_value;

 return new SelectList(_storeOrderTimeDictionaryList, "Value", "Key");
}

Кстати, вы должны проверить Ninject , Castle Windsor, Structure Map или любой другой DI /Контейнер IOC, чтобы помочь вам проверить эту логику (и сделать ее более сухой).Попробуйте найти учебник по ninject asp.net mvc 2

0 голосов
/ 27 июля 2010

Не можете ли вы выполнить рефакторинг действий вашего контроллера для извлечения Some manipulation and calculations в другой вызов функции класса или уровня обслуживания.

Поскольку мне нужен сеанс в ActionC, я не могу создать экземпляр Controller и вызватьaction.

Ничто не мешает вам использовать сессию в ControllerA.ActionA.Следующее не является точным, но может помочь вам ..

public class ControllerA{
    public JsonResult ActionA(string var1)
    {
     /*  Some manipulation and calculations    */
         SomeService service = new SomeService();
         _slist = service.ActionThatDoesStuffForActionC(var1);
         Session["STRING"] = var1;
         var firstItem = _slist.First().ToString();

         SomeOtherService service2 = new SomeOtherService();
         var service2Result = service2.ActionThatDoesStuffForActionB(firstItem);

         // convert service2Result  to a jsonresult here.

         return RedirectToAction("ActionB", "ControllerB", new { var1 = firstItem });
     }
}

public class ControllerB{
     public JsonResult ActionB(string var1)
     {
          /*    Some manipulation and calculations    */
          SomeOtherService service2 = new SomeOtherService();
          var service2Result = service2.ActionThatDoesStuffForActionB(var1);

          return Json(false, JsonRequestBehavior.AllowGet);
     }

    public SelectList ActionC(string var1)
     {    
     /*     Some manipulation and calculations     */
     SomeService service = new SomeService();
     _slist = service.ActionThatDoesStuffInActionC(var1);
     Session["STRING"] = var1;
     return new SelectList(_slist, "Value", "Key");
    }   
}

Редактировать: Посмотрите на исходный код отсюда http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/07/23/mvcconf-slides-and-code-posted.aspx. Я думаю, что подход Джимми Боггарда может быть полезным и обеспечитьВы с помощью способа вызвать действия «другой контроллер».Вы комментируете: «Я не могу изменить поведение действия.И на рефакторинг потребуется время, которого у меня нет ».для меня указывает путь на пути к неуправляемому коду.Рефакторинг, Рефакторинг, Рефакторинг - преимущества от этого сейчас сэкономят вам часы боли в сердце на более позднем этапеИ исходя из вопроса, я думаю, что это уже началось.

...