Several of my controller actions have a standard set of failure-handling behavior. In general, I want to:
These steps are so standardized that I want to have reusable code to implement the behavior.
My current plan of attack was to have a helper method to do something like this:
public static ActionResult HandleMyObject(this Controller controller,
Func<MyObject,ActionResult> onSuccess) {
var myObject = MyObject.LoadFrom(controller.RouteData).
if ( myObject == null ) return NotFound(controller);
if ( myObject.IsNotAllowed(controller.User)) return NotAllowed(controller);
return onSuccess(myObject);
}
# NotAllowed() is pretty much the same as this
public static NotFound(Controller controller){
controller.HttpContext.Response.StatusCode = 404
# NotFound.aspx is a shared view.
ViewResult result = controller.View("NotFound");
return result;
}
The problem here is that Controller.View() is a protected method and so is not accessible from a helper. I've looked at creating a new ViewResult instance explicitly, but there's enough properties to set that I'm wary about doing so without knowing the pitfalls first.
What's the best way to create a ViewResult from outside a particular Controller?
The shared directory is there specifically to share Views across multiple controllers. Just add your View to the Shared subdirectory and you're good to go. If you do return View("~/Views/Wherever/SomeDir/MyView. aspx") You can return any View you'd like.
The other way of passing the data from Controller to View can be by passing an object of the model class to the View. Erase the code of ViewData and pass the object of model class in return view. Import the binding object of model class at the top of Index View and access the properties by @Model.
TempData is used to transfer data from view to controller, controller to view, or from one action method to another action method of the same or a different controller. TempData stores the data temporarily and automatically removes it after retrieving a value. TempData is a property in the ControllerBase class.
Just read this post as I was having the same issue from an action filter. My solution was creating the view action explicitly. This is based on the protected View() method as per the MVC source so it should populate the required properties. Anyway, seems to work without issues.
public static NotFound(Controller controller){
controller.HttpContext.Response.StatusCode = 404;
ViewResult result = new ViewResult {
ViewName = "NotFound",
ViewData = controller.ViewData,
TempData = controller.TempData
};
return result;
}
A bit late in the day but this worked for me.
As I was writing this I thought of one way.
Rather than have the above code in a helper, I could put it into a subclass of Controller and then subclass this class for my actual controllers. This would allow me to call the protected View() method.
I don't like this particularly much because it requires inheritance to work, but it's still an option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With