1

I'm able to call this compiled dll's controller directly in a Sitecore rendering - e.g. I can create a rendering where I reference the controller, controller action, and area and the content from the compiled dll displays perfectly. However, I need to be able to create a separate rendering that calls a controller that I create, and within that controller I call the compiled dll controller action.

Another developer suggested that I try using "return RedirectToAction" for this, but this is not working (it's using the /sitecore/api route which is not a part of this compiled dll, and redirects the browser entirely to that route, which I do not want).

Any help or insight would be very appreciated!

2
  • 2
    Why do you want to call your own controller from a separate rendering? Can't you just create a controller rendering and within that call your compiled controller action?
    – Richard Seal
    Commented Jun 29, 2017 at 18:54
  • I will most likely need to be passing in parameters from data that I can call/manipulate in code. Commented Jun 29, 2017 at 19:13

2 Answers 2

1

If I'm understanding correctly, you're looking to get the result from a controller, and return that through an API controller. The problem with that is that a controller action generally returns an ActionResult object, not just a string of HTML. There are many types of ActionResult that would be hard to handle, or would have to be special-cased, such as FileStreamResult, RedirectResult, ContentResult, etc. This is also complicated by the fact that a controller transparently handles applying the returned ActionResult. It doesn't simply write the result to the response output, but actually applies the ActionResult to a ControllerContext by running the ActionResult's ExecuteResult() method. If you really needed to do this, and were willing to accept the numerous possible ActionResult subclasses and handle each one of them, I believe you could create a temporary ControllerContext and use ExecuteResult() on it, but I think you'll find that this is a lot of work for little return.

If you're looking to just return HTML (ie, not trying to embed the result in JSON/XML), then you can simply use @Html.Sitecore.Rendering() within your view pointing towards the rendering item which represents the controller in the compiled DLL, which will render that rendering (and therefore go through the other controller). See here for how to do that: https://ctor.io/specify-datasource-item-of-a-statically-binded-rendering/

Finally, I just want to bring up that you shouldn't be using /api/sitecore. This is actually a route that's configured in the Speak configuration IIRC, and is actually supposed to be disabled on CD machines if you follow Sitecore's suggestions on configuring the machines. Instead, you should register your own custom route in the initialize pipeline. This is easy to do, and is a better practice. See here for more info: https://doc.sitecore.net/sitecore_experience_platform/developing/developing_with_sitecore/mvc/use_mvc_routing

Edit

If you're able to ensure that you get a ViewResult back from the other controller, you can do something like the following to render the returned view to a string, which you can then manipulate as you wish. It's hard to give you perfect code since you're still at the planning stage, but if you need to go this route, something like this should work. Note that I took some inspiration from here: https://stackoverflow.com/questions/483091/render-a-view-as-a-string

public ActionResult MyMethod() {
    var param1 = 1;
    var param2 = "test";

    var controller = new MyOtherController{ControllerContext = ControllerContext};

    var viewResult = (ViewResult)controller.Display(param1, param2);

    var result = string.Empty;

    using (var sw = new StringWriter())
    {
        var viewData = new ViewDataDictionary(viewResult.Model);
        var tempData = new TempDataDictionary();

        var viewContext = new ViewContext(ControllerContext, viewResult.View, viewData, tempData, sw);
        viewResult.View.Render(viewContext, sw);

        result = sw.GetStringBuilder().ToString();
    }

    // Do something with result

    return Content(result);
}
8
  • I definitely wasn't trying to use /api/sitecore :) It gets automatically added to the url when you try to use RedirectToAction! Commented Jun 29, 2017 at 19:30
  • I appreciate your input - unfortunately for the most part I don't think just outputting the HTML will be sufficient in this case - and I need to be able to pass input parameters to the compiled controller as well. Commented Jun 29, 2017 at 19:31
  • It would be helpful to get an idea of what the compiled controller you're referring to does and outputs, and how you expect it to receive arguments. Are the parameters passed directly to the controller action method, pulled manually from the query string/post data, pulled from the session, etc.? Commented Jun 29, 2017 at 19:52
  • That's an excellent question, which I don't know for sure yet because the compiled controller is proprietary and built by an external company. We can request/recommend format, but I believe the inputs and outputs (once we get that far) are expected to be passed directly to the action method. But if that's not possible this other company will work with us. (edit: this is all in progress right now, they've sent over a simple controller that requires no input/output yet just to get a POC working). Commented Jun 29, 2017 at 19:56
  • In that case, I think your best bet is going to be to request that they ONLY return a ViewResult, which you can render to a string and use that. In this case, you'd want to pass through the parameters to the action method. I'll amend my answer in a bit to show how to do that. Commented Jun 29, 2017 at 20:06
0

To quote this answer by Tiesen T:

Controllers are just classes - new one up and call the action method just like you would any other class member:

var result = new ControllerB().FileUploadMsgView("some string");

Your Rendering will use your own custom Controller which will invoke the methods of the controller from the assembly you're referencing. Of course the specifics are important, but this should work with all public methods of the third party Controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.