开发者

Call action of another controller and return its result to View

I have a scenario where I need the following functionality:

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开发者_如何学C"] = some_value;

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

I need JsonResult in the View Page, but the problems are as:

  1. As RedirectToAction returns redirecttorouteresult I can't directly return the JSonResut
  2. As I need the Session in ActionC I can't instantiate Controller and call the action.


This may not be the best approach...

Its hard to tell, but drying up the controllers, and moving out the business logic may help. It looks like you want to maintain the functionality of Actions B, and 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");
}

BTW, you should check out Ninject, Castle Windsor, Structure Map, or any other DI/IOC container, to help you test this logic (and make it dryer). Try searching for ninject asp.net mvc 2 tutorial


Can you not refactor you controller actions to extract the Some manipulation and calculations into another class or service layer function call.

As I need the Session in ActionC I can't instantiate Controller and call the action.

There is nothing stopping you from using the Session in ControllerA.ActionA . The following is not exact, but may help you ..

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");
    }   
}

Edit: Have a look at the source code from here http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/07/23/mvcconf-slides-and-code-posted.aspx. I think that Jimmy Boggard's, approach may be useful and provide you with a way to call 'other controller' actions. You comment ' I can't change the behavior of the action. And to refactor it will take time which I do not have.' to me indicates the journey on the road to unmaintainable code. Refactor, Refactor, Refactor - the benefits of doing it now will save you hours of heart ache at a later stage. And based on the question, I think it has already started.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜