2

It might be a noob question or an architectural misunderstanding, but I ask it anyhow because I am out of ideas and search terms: The goal is to implement a controller CountriesController() which is supposed to concatenate the (JSONish) results of two endpoints.

Assume I have two endpoints api/allowedCountriesToSell and api/allowedCountriesToBuy which are implemented as CountriesSellController() and CountriesBuyController() respectively. Both of them give back data as JSON which I want to merge and offer as a new endpoint. I am aware that this architecture is not ideal, but I am not allowed to do it architecturally different. Furthermore, I actually have to POST two different files to those endpoints - both existing controllers contain something like

[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file, string selectBox)
{ // ...

My new endpoint compiles all these two required parameters, let's call them myFileX, and mySelectBox. Here what I have have so far:

var myOtherContoller1 = new CountriesSellController();
var list1 = myOtherContoller1.FileUpload(myFile1,mySelectBox);

var myOtherContoller2 = new CountriesSellController();
var list2 = myOtherContoller1.FileUpload(myFile2,mySelectBox);

my result = list1.asEnumerable().Concat(list2.asEnumerable()); // Pseudocode. Here I am lost.

return Ok(result);

The problem is that both list1 and list2 are of type IHttpActionResult and I am not sure how to extract the data inside that. Ideally, result would be of type IEnumerable<UploadStatusDto> where I define the respective data transfer object as

namespace API.Models
{
    public class UploadStatusDto
    {
        public int UploadId { get; set; } // contained in the response of both controllers 
        public string FileName { get; set; } // myFileX - parameter for calling the 2 existing controllers
        public int UploadStatus { get; set; } // coming back within listX
        public int Type { get; set; } // whether it is a buy or a sell, i.e. which controller I called
    }

Any guidance is appreciated.

B--rian
  • 5,578
  • 10
  • 38
  • 89
  • A controller action is supposed to be called by making a HTTP request to it - hence why it returns a HttpActionResult (which the ASP.NET pipeline would then turn into a HTTP response containing headers and body). You wouldn't normally expect to call it from another part of a C# program. What exactly is your setup here? – ADyson Dec 05 '19 at 15:18
  • 1
    Why not move the actual logic in those 2 controller methods into a separate class and return just the data? Then the existing controllers can call those methods, wrapped in a `IHttpActionResult`, and your new endpoint can call them and have access to just the data. You really shouldn't be calling your controller methods directly. – jtate Dec 05 '19 at 15:20
  • @ADyson: That's exactly the issue - I am not supposed to touch the other code base, so I have to actually invoke two controllers via HTTP request (with name of the file which should be uploaded) from my new controller. – B--rian Dec 05 '19 at 15:23
  • @jtate: Well, on the one hand, I should not duplicate code, on the other hand, I should not touch existing controllers/ endpoints, so the only way around I could come up with is to actually call the corresponding functions within the existing controllers via HTTP-request. Not clean, but in principle working. So the main question is: **How do I extract the JSON from the `IHttpActionResult`?** I am probably only missing a search term here.. – B--rian Dec 05 '19 at 15:25
  • if you can't touch the existing controller methods, [does this answer your question](https://stackoverflow.com/a/30002975/1745913)? – jtate Dec 05 '19 at 15:28
  • "I have to actually invoke two controllers via HTTP request"...ok, but right now you don't appear to be doing that, you seem to be calling those methods directly, as if they're part of the same assembly – ADyson Dec 05 '19 at 15:29
  • @jtate Thanks for the link. It might be solution, I do not fully understand it yet. – B--rian Dec 05 '19 at 15:30
  • 1
    The idea is that you can't directly get content from a `IHttpActionResult` interface, because not all http response codes contain content. So you have to cast it to an "OK" response type, then get the content. I'm assuming your existing controller methods are doing something like `return Ok(data)` – jtate Dec 05 '19 at 15:32

1 Answers1

1

You need to do something line this.

var response = await myOtherContoller1.FileUpload(myFile2,mySelectBox).ExecuteAsync();

This will return HttpResponseMessage and you can get the content from it

You can get your content like this: Getting content/message from HttpResponseMessage.

My suggestion though, would be to extract the logic of your other controllers to a service class, and call both in this and the other two, the logic that is now in the original controllers.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • I will try your suggestion rsn. The idea with the service class is cool, but it (again) contradicts the client's idea of not touching any existing architecture. Both endpoints contain quite a bit of logic (which ideally belong in a service class) - but my hands are tied, and I cannot clean that up. – B--rian Dec 05 '19 at 15:28