1. How to transfer data from
controllers
By : Eng. Mahmoud Hassouna
Email : M.hassuna2@gmail.com
2. Now, this chapter presents more details about how that
works. In addition, it presents several new ways to transfer
data from a controller to a view or to another controller.
3. How to use ActionResult objects
The apps you’ve seen so far in this book have transferred data from a
controller to a view by passing a model object to the View() method.
This method returns a ViewResult object, which is a subtype of the
ActionResult class. Now, this chapter presents more details about how
you can use the ActionResult class to transfer data from a controller to
a view.
4. An introduction to ActionResult subtypes
The ActionResult type provides information to MVC about the type
of HTTP response an action method should return. The response can
be content, like HTML or JSON, or it can be an HTTP status code such
as 404 Not Found.
5. The ActionResult hierarchy:
Figure 8-1 begins by presenting the hierarchy of the
ActionResult class. Here, the abstract ActionResult class
implements the IActionResult interface. Then, several subtypes
inherit and extend the ActionResult class. The table in this
figure lists some of the most common subtypes of the
ActionResult type. Each subtype has a specific purpose. For
instance, the ViewResult class renders a view and sends the
resulting HTML to the browser. The JsonResult class sends JSON
to the browser. The FileResult class sends a file to the browser.
The RedirectToActionResult class uses HTTP to instruct the
browser to redirect to a URL that corresponds to the specified
action method. And so on.
6. Common ActionResult subtypes:
Class Description
ViewResult
RedirectResult
RedirectToActionResult
JsonResult
FileResult
StatusCodeResult
ContentResult
EmptyResult
Renders a specified view as HTML and sends it to the browser
Performs an HTTP redirection to the specified URL
Performs an HTTP redirection to a URL that’s created by the routing system
using specified controller and action data
Serializes an object to JSON and sends the JSON to the browser
Returns a file to the browser
Sends an HTTP response with a status code to the browser
Returns plain text to the browser
Returns an empty response to the browser
7. A URL that provides a full list of the ActionResult subtypes
https://docs.microsoft.com/en-us/dotnet/api/
microsoft.aspnetcore.mvc.actionresult
Description
• Within a controller, an action method can return any type of
ActionResult object. The ActionResult class is an abstract class that
implements the IActionResult interface.
• Since the ActionResult class has many subtypes, an action method
can return many different types of result objects
8. How to return ActionResult objects
The ActionResult object returned by an action method tells MVC the type of
response that should be sent to the browser.
The names of these methods correspond to the ActionResult subtype they
return. For instance, the View() method creates a ViewResult object, the
RedirectToAction() method creates a RedirectToActionResult object, and so on.
Some methods of the Controller class that return an
ActionResult object :
Method Creates
View()
Redirect()
RedirectToAction()
File()
Json()
ViewResult object
RedirectResult object
RedirectToActionResult object
FileResult object
JsonResult object
9. 1- The first overload accepts no arguments and renders the default view for
the current controller and action method. For instance, if an Index()
method in the Home controller calls the View() method with no arguments,
MVC renders the HTML for the Home/Index view.
Some of the overloads of the View() method:
Method Description
View()
View(model)
View(name)
View(name, model)
Renders the default view for that controller and action method.
Transfers a model object to the default view and renders that view.
Renders the specified view. This method starts by searching for the
specified view in the view folder for the current controller. Then, it
searches in the Views/Shared folder.
Transfers a model object to the specified view and renders that view.
10. 2- The second overload accepts a model object that’s used by the
default view. For instance, if an Index() action method in the Home
controller passes an object to the View() method, MVC transfers that
object to the Home/Index view. Then, the view uses that object to render
its HTML
3- The third overload accepts a string that tells MVC which view file to use.
MVC starts by looking for this file in the folder for the current controller.
Then, it looks in the Shared folder. For instance, if an Index() action
method in the Home controller passes the string “Error” to the View()
method, MVC looks for the Error.cshtml file in the Views/Home folder. Then,
it looks in the Views/ Shared folder.
4- The fourth overload accepts a string and a model object. Thus, if an
Index() action method in the Movie controller passes the string “Edit” to
the View() method, MVC passes the specified model object to the
Edit.cshtml file in the Views/Movie folder.
11. An action method that returns a ViewResult object:
public ViewResult List() {
var names = new List { "Grace", "Ada", "Charles" };
return View(names);
}
An action method that returns a RedirectToActionResult object:
public RedirectToActionResult Index() => RedirectToAction("List");
An action method that may return different types of result objects:
[HttpPost]
public IActionResult Edit(string id) {
if (ModelState.IsValid)
return RedirectToAction("List");
else
return View((object)id); // cast string model to object
}
12. Description:
• The Controller class provides several methods that create objects of
ActionResult subtypes. Most of these methods include several overloads
that allow you to customize the ActionResult object that’s created.
• When Visual Studio generates action methods, it uses IActionResult as
the return type.
• If an action method only returns one type of ActionResult object, it’s a good
practice to specify that subtype as the return type.
• If an action method may return multiple types of ActionResult objects, you
can specify the ActionResult abstract class or the IActionResult interface
as the return type.
• If you want to use a string as a model, you must cast it to an object first.
13. How to use the ViewData
and ViewBag properties
Up until now, you’ve seen how to use the ViewBag property of the
Controller class to transfer data from an action method to a view. In a
moment, this chapter will review the ViewBag property and explain it in
more detail. But first, it shows how to use the closely-related ViewData
property of the Controller class, which also lets you transfer data to a
view.
14. The ViewData property of the Controller class has a data type of
ViewDataDictionary. This means that the property is a collection of
key/value pairs. For this dictionary type, the key is a string and the value is
an object
The ViewData property is shared with the associated view, including the
view’s layout. As a result, any data stored in the ViewData dictionary is
available to the view and its layout.
The ViewDataDictionary class also has some properties that a view can
use. The table in this figure summarizes some of these properties. Then, the
second code example shows how a view can use these properties to
display the data in the ViewData dictionary to the user. To do that, the
code uses the Count property to display the number of items, and it uses
a KeyValuePair object to get each item and display its key and value.
15. If you just want to display a ViewData value in the browser, you don’t need
to do anything special to it. That’s because Razor automatically calls the
ToString() method of an object in the dictionary. However, if you want to
work with a value in the ViewData dictionary in code, you must first cast it to
the appropriate data type. For instance, the third code example gets the
value for the Price item, casts it to the double type, and then uses the
ToString() method to apply currency formatting to the double value.
However, before you call a method from a value, you should check to make
sure the value isn’t null. Otherwise, your app might throw exceptions. For
instance, the fourth code example shows how to check if the Price value is
null. If it is, the code sets the value to an empty string. Otherwise, it casts the
value to a double type and applies currency formatting. Since this value is of
the non-nullable double type, this code uses the conditional operator (? :) to
perform this check
16. Controller code that adds two items to the ViewData property
public ViewResult Index() {
ViewData["Book"] = "Alice in Wonderland";
ViewData["Price"] = 9.99;
return View();
}
17. Some of the properties of the ViewDataDictionary class
Property Description
Count
Keys
Values
Returns the number of key/value pairs in the dictionary.
Returns a collection of strings containing the keys in the dictionary
Returns a collection of objects containing the values in the dictionary.
18. Razor code that displays all the items in the ViewData object
<h2> @ViewData.Count items in ViewData</h2>
@foreach (KeyValuePair item in ViewData) {
<div> @item.Key - @item.Value </div>
}
The view in the browser
19. Razor code that casts a ViewData object to the double type
<h4>Price: @(((double)ViewData["Price"]).ToString("c")) </h4>
The view in the browser
Razor code that checks ViewData values for null
Non-nullable type (double)
<h4> Price: @((ViewData["Price"] == null) ? "" :
((double)ViewData["Price"]).ToString("c")) </h4>
Nullable type (string)
<h4> Book: @ViewData["Book"]?.ToString() </h4>
20. Description :
The Controller class has a ViewData property that lets you transfer data
to a view.
The ViewData property is of the ViewDataDictionary type, which is a
collection of key/value pairs where the key is a string and the value is an
object.
When you display a ViewData value in a view, Razor automatically calls
the object’s ToString() method.
If you want to work with a ViewData value in code, you must cast the
value to its data type. But first, you should check to make sure the value
isn’t null
21. How the teams of the National Football League (NFL) are organized
There are two conferences, the NFC and the AFC.
Each conference contains four divisions named North, South, East, and West.
Each division contains four teams.
23. The NFL Teams app after a conference and division are selected
24. The Home controller
public class HomeController : Controller
{
private TeamContext context;
public HomeController(TeamContext ctx) {
context = ctx;
public ViewResult Index(string activeConf = "all“
, string activeDiv = "all")
{
// store selected conference and division IDs in view bag ViewBag.ActiveConf = activeConf;
ViewBag.ActiveDiv = activeDiv;
// get list of conferences and divisions from database
List <conferences >= context.Conferences.ToList();
List <divisions> = context.Divisions.ToList();
// insert default "All" value at front of each list
conferences.Insert(0, new Conference { ConferenceID = "all“
, Name = "All" });
divisions.Insert(0, new Division { DivisionID = "all",
Name = "All" });
25. // store lists in view bag
ViewBag.Conferences = conferences;
ViewBag.Divisions = divisions;
// get teams - filter by conference and division
IQueryable query = context.Teams;
if (activeConf != "all")
query = query.Where(
t => t.Conference.ConferenceID.ToLower() ==
activeConf.ToLower());
if (activeDiv != "all")
query = query.Where(
t => t.Division.DivisionID.ToLower() ==
activeDiv.ToLower());
// pass teams to view as model
var teams = query.ToList();
return View(teams);
}
}
26. The custom route in the Startup.cs file
endpoints.MapControllerRoute(
name: "custom",
pattern: "{controller}/{action}/conf/{activeConf}/div/{activeDiv}");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
31. How to work with view models
The applications you’ve seen so far have used the View() method to
transfer a single entity object or a collection of entity objects to a view.
Sometimes, however, the data needed by a view doesn’t match the data
in an entity model.
For example, the model object for the Index view of the NFL Teams app is a
collection of Team objects. However, that view also needs a collection of
Conference objects and a collection of Division objects to build the links to
filter by conference and division. In addition, it needs the IDs of the active
conference and division.
32. How to create a view model
Typically, view models are lightweight classes that contain only data.
However, they can also contain simple helper methods for the view. For
instance, the TeamListViewModel class provide two methods named
CheckActiveConf() and CheckActiveDiv() that the view can use to
determine the active link in the conference and division sections. That’s
acceptable because this logic only impacts how the view is displayed.
However, a view model shouldn’t have logic that impacts other parts of
the app such as the entity model or controller
34. Description:
A view model is a regular C# class that defines a model of the data
that’s needed by a view.
By convention, the name of a view model class ends with a suffix of
“ViewModel”, but this isn’t required.
Most view models only provide data. However, a view model can
also contain simple methods that help the view display that data
35. Two of the HTTP status codes for redirection
The ActionResult subtypes for redirection
Code Description
302 Found
301 Moved Permanently
Directs the browser to make a GET request to another URL.
Directs the browser to make a GET request to another URL for
this and all future requests.
Subtype 302 Found method 301 Moved Permanently
method
RedirectResult
LocalRedirectResult
RedirectToActionResult
RedirectToRouteResult
Redirect()
LocalRedirect()
RedirectToAction()
RedirectToRoute()
RedirectPermanent()
LocalRedirectPermanent()
RedirectToActionPermanent()
RedirectToRoutePermanent()
36. How to know which subtype to use for redirection
Some of the overloads available for the RedirectToAction() method
Subtype Use when…
RedirectResult
LocalRedirectResult
RedirectToActionResult
RedirectToRouteResult
Redirecting to an external URL, such as https://google.com.
Making sure you redirect to a URL within the current app.
Redirecting to an action method within the current app.
Redirecting within the current app by using a named route.
Arguments Redirect to…
(a)
(a, c)
(a, routes)
(a, c, routes)
The specified action method in the current controller.
The specified action method in the specified controller.
The specified action method in the current controller with route parameters.
The specified action method in the specified controller with route parameters.
37. Code that redirects to another action method
Redirect to the List() action method in the current controller
public RedirectToActionResult Index() => RedirectToAction("List");
Redirect to the List() action method in the Team controller
public RedirectToActionResult Index() => RedirectToAction("List", "Team");
Redirect to the Details() action method in the current controller with a parameter
public RedirectToActionResult Index(string id) =>
RedirectToAction("Details", new { ID = id });
Use a shortcut when variable name and route segment name match
public RedirectToActionResult Index(string id) =>
RedirectToAction("Details", new { id });
Use a string-string dictionary to supply a parameter
public RedirectToActionResult Index(string id) =>
RedirectToAction("Details",
new Dictionary<string, string>(){ { "ID", id } } );
38. A browser message that’s displayed when you refresh a page
that’s displayed by a POST request
Two action methods that uses the Post-Redirect-Get (PRG) pattern
A Delete() action method for a POST request
39. Description
To prevent resubmission of POST data, you can use the PostRedirect-Get (PRG)
pattern. With this pattern, a POST action writes data to the server and then
redirects to a GET action to read data from the server.
How to use the TempData property
So far, this chapter has shown how to transfer data from a controller to a
view. Sometimes, though, you need to transfer data from a controller to another
controller. To do that, you can use the built-in TempData property that’s available
from controllers and views.
40. An action method that uses TempData with the Post-
Redirect-Get pattern
42. Description
The Controller class has a property named TempData that lets you transfer data to another
controller or view.
Data in TempData persists across multiple requests until it is read. By contrast, data in ViewData
and ViewBag only persists until the end of the current request.
TempData is often used with the PRG pattern because that pattern takes place across two
requests (the POST request and the subsequent GET request).
TempData can only store data that can be serialized such as primitive types.
Because TempData is a dictionary, it has normal dictionary properties like Keys and Values, which
in turn have a Contains() method you can use to check for values.
By default, ASP.NET Core 3.0 and later automatically enable TempData when you call the
AddControllersWithViews() method in the Configure() method of the
Startup.cs file.
43. Two methods of the TempDataDictionary class
Method Description
Keep()
Keep(key)
Peek(key)
Marks all the values in the dictionary as unread, even if they’ve already been
read.
Marks the value associated with the specified key as unread, even if it has already
been read.
Reads the value associated with the specified key but does not mark it as read
45. When to use the Keep() and Peek() methods
Use Peek() when you know you want the value to stay marked as unread.
Use a normal read and Keep() when you want to use a condition to determine
whether to mark the value as unread
46. The Home page after selecting a conference and division
The Details page after clicking on a team
48. Description
This version of the NFL Teams app uses two view models named TeamViewModel
and TeamListViewModel.
The TeamListViewModel inherits the TeamViewModel. That way, the ActiveConf
and ActiveDiv properties are only coded in the TeamViewModel class.
Since the overloaded Details() action method uses the PRG pattern, it uses the
TempData dictionary to transfer data from the action method that handles POST
requests to the action method that handles GET requests.
50. Description
The Home/Index view receives a TeamListViewModel object from the Index()
action method of the Home controller.
The <form> element for each team binds three hidden fields to the ActiveConf,
ActiveDiv, and Team.TeamID properties of the view model
51. Terms
dynamic type
alias
view model
idempotent
Post-Redirect-Get (PRG) pattern
open redirection attack
52. Summary
ViewBag properties use C#’s dynamic type. As a result, the data type of
each property is set at runtime.
Under the hood, the ViewBag property uses the ViewData dictionary
to store its dynamic properties. Thus, you can think of the ViewBag
property as an alias for the ViewData dictionary.
A view model is a regular C# class that defines a model of the data that’s
needed by a view.
An idempotent request has the same effect on the server whether it’s
made once or multiple times.
To prevent resubmission of POST data, you can use the
Post-Redirect-Get (PRG) pattern. With this pattern, a POST action
writes data to the server and then redirects to a GET action to read data
from the server.
Open redirection attacks attempt to redirect to a malicious external site.