4

I'm refactoring an MVC controller into smaller pieces in different classes, and I've come to a part where I'm returning a "return StatusCode(500,"Some message")" item.

It seems as though I'm not able to do this outside of a controller as far as I can tell.

Is this possible, or must I find an alternative way to return a response, and convert it to the appropriate type back in the calling code (The MVC controller)?

A problem I can see myself having, is that the original type of the MVC action is IActionResult, so within the action I've been returning whatever is the appropriate response, sometimes view(,model), sometimes Json() and other times StatusCode(<500>,), i.e. my responses aren't consistent.

Is there a natural way for me to just pickup and move this code into another class to make it work, or will I have to hand craft my own object to represent what I would otherwise and returned in the controller, and if so, what is recommended?

In short, ideally I want to be able to return an action result such as "return View("my view name", myModel) in a class outside of a controller. How can I achieve this?

It feels quite dirty, but perhaps a single object containing a statuscode, message, object (to serve as the model), view name and a new enum called ActionResultType, with a value for "StatusCode", "Json" and "View", so I can reasonably easily map it back to it's appropriate natural state when the controller receives the response.

Perhaps I'm going a bit far and instead should just focus on getting the main parts of the logic out of the controller, rather than trying to build a more fleshed out response somewhere else?

If possible, I'd love to get each action result to about 10 lines, but unless I can figure out a nice way to return the appropriate response from somewhere else, it will probably be a struggle.

Steviebob
  • 1,705
  • 2
  • 23
  • 36
  • 3
    The logic outside of your controller shouldn't know or care about HTTP error codes, keep that stuff in your MVC actions. – DavidG Jan 22 '17 at 20:13
  • All of those have a base type of ActionResult so I'm not sure what the problem is. – Erik Philips Jan 22 '17 at 20:14
  • you can try using "return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));" – Ali Baig Jan 22 '17 at 20:14
  • @ErikPhilips after spending some more time on this (With a fresh pair of well rested eyes), it's not surprising that you don't understand what the problem is. I was being dopey in that I was using StatusCode() outside of a controller (Getting a red squiggle), when I *should* have been using new StatusCodeResult() - doh! (Not enough coffee I guess). I can't seem to populate the model of a ViewResult (And it's starting to feel like I'm going against the grain), so I think I'll use some sort of object to determine state and within the controller map it to the appropriate IActionResult type. – Steviebob Jan 23 '17 at 20:23

2 Answers2

8

You can substitute those for:

var result = new ObjectResult("Some message");
result.StatusCode = statusCode;
return result;

That's what the StatusCode helper method does anyway.

If you don't need the message, then you can do just:

return new StatusCodeResult(500);

Just add using Microsoft.AspNetCore.Mvc; at the top of the file.

juunas
  • 54,244
  • 13
  • 113
  • 149
0

If you need shared code between controllers, you can setup a base controller to hold the shared code and inherit that base controller on any other controller that needs access.

ActionResult holds all of the things you want. All the things you want in your custom object all exist as subclasses of ActionResult. JsonResult is a subclass of ActionResult. There are several subclasses for each error code. I believe HttpNotFoundResult is another one.

I would suggest keeping most things ActionResult/Redirect/View/StatusCode related inside your controllers. That is where it is typically located.

Brendan Long
  • 276
  • 1
  • 6