Brendan Enrick

Daily Software Development

Types of ASP.NET MVC 3 Action Results

This will surprise some of you that know me or the company I work for, but not all of our staff are experts with ASP.NET MVC. In fact, I am hoping that the couple who aren’t will read this post and learn a little bit more about the topic.

Since the actions of controllers in MVC are dealt with constantly, I think it is a good place to start. This post is going to briefly describe the different types of results that are available to you in ASP.NET MVC 3. I will show some of the code that makes them work, which should make all of this seem a lot less complicated.

When creating new controllers in ASP.NET MVC 3, they will come with one or more actions by default. This depends on whether you selected a template which includes extras for you. The Empty controller template comes with an Index action with a return value of type ActionResult.

ActionResult

The action result is a very generic return value for an action. This is because it is the abstract base class for other types of actions. It is actually a very simple class having only one method that needs implementing.

public abstract class ActionResult
{
public abstract void
ExecuteResult(ControllerContext context);
}

Inheriting from the ActionResult are the following classes:

  • ContentResult
  • EmptyResult
  • FileResult
  • HttpStatusCodeResult
  • JavaScriptResult
  • RedirectResult
  • RedirectToRouteResult
  • ViewResultBase

These are the classes that inherit from ActionResult indirectly:

  • FileContentResult
  • FilePathResult
  • FileStreamResult
  • HttpNotFoundResult
  • HttpUnauthorizedResult
  • PartialViewResult
  • ViewResult

ViewResultBase, ViewResult, and PartialViewResult

The ViewResult is the most common concrete type you will be returning as a controller action. It has an abstract base class called ViewResultBase, which it shares with PartialViewResult.

It is in the ViewResultBase abstract base class that we get access to all of our familiar data objects like: TempData, ViewData, and ViewBag.

PartialViews are not common as action results. PartialViews are not the primary thing being displayed to the user, that is the View. The partial view is usually a widget or something else on the page. It’s usually not the primary content the user sees.

This is the common return syntax, and it means that you’re returning a ViewResult.

return View();

That is actually a call to the base Controller.View method, which is just going to call through with some defaults.

protected internal ViewResult View()
{
return View(null, null, null);
}

 

The beauty of ASP.NET MVC is actually in its simplicity though, because all that really did was create our ViewResult for us. If we take a look at the method that is being called you can see that we’re just taking a little shortcut and keeping our action clean of this code we would otherwise repeat every time we wanted a ViewResult.

protected internal virtual ViewResult View(
string viewName, string masterName, object model)
{
if (model != null)
{
ViewData.Model = model;
}

return new ViewResult
{
ViewName = viewName,
MasterName = masterName,
ViewData = ViewData,
TempData = TempData
};
}

Notice how simple that really is. All it did was put the model data in if we specified it, give the ViewResult the Controller properties that we set already, and assign the viewName and masterName.

Keep in mind, that we already saw that the abstract method in the ActionResult was the ExecuteResult method. The last two things to look at with the ViewResultBase are the ExecuteResult method and its abstract method FindView, which is being implemented by ViewResult and PartialViewResult.

public override void ExecuteResult(
ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (String.IsNullOrEmpty(ViewName))
{
ViewName = context.RouteData
.GetRequiredString("action");
}

ViewEngineResult result = null;

if (View == null)
{
result = FindView(context);
View = result.View;
}

TextWriter writer = context.HttpContext.Response.Output;
ViewContext viewContext = new ViewContext(
context, View, ViewData, TempData, writer);
View.Render(viewContext, writer);

if (result != null)
{
result.ViewEngine.ReleaseView(context, View);
}
}

This method is also not very complicated. It checks to make sure we have context, and then if we don’t have the ViewName then we get that information from the RouteData. Remember in MVC that the name of action is included in the RouteData, so we can use that as the default view name. This means that in the Index action, if we just call View(), it will give us a ViewName of “Index”.

We then get the view we’re looking for by calling the FindView abstract method, which means we’re calling through to either ViewResult and PartialViewResult. Those I am not going to get into the guts of, but each one is going to try to find the correct view based on the name using its collection of ViewEngines.

Once we have the view, we are able to tell it to render itself using the context and the TextWriter we give to it.

That’s all there is to a ViewResult.

ContentResult

The content result lets you define whatever content you wish to return. You can specify the content type, the encoding, and the content. This gives you control to have the system give whatever response you want. This is a good result to use when you need a lot of control over what you’re returning and it’s not one of the standards.

Its ExecuteResult override is extremely simple.

public override void ExecuteResult(ControllerContext context) 
{
if (context == null)
{
throw new ArgumentNullException("context");
}

HttpResponseBase response = context.HttpContext.Response;

if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Content != null)
{
response.Write(Content);
}
}

It just puts what you specified directly into the response.

EmptyResult

There is no simpler result than the EmptyResult. All it does is override the ExecuteResult method and since that method is void, the method is empty.

I really don’t think I need that code snippet for this one.

FileResult, FileStreamResult, FilePathResult, and FileContentResult

If you want specific actions to send files as the response, then the FileResult is for you. Sadly, the FileResult is abstract, so you’ll need to use one of the inheriting classes instead. Each of these actually just overrides the WriteFile method for the abstract FileResult class.

If you want to just send the contents of the file back with the array of bytes for the file, then you want the FileContentResult. It uses the response’s OutputStream and writes those bytes directly into the stream sending it down to the user.

If you want to transmit the file using its name, you can use FilePathResult, which will call through a whole bunch of layers finally down to the HttpResponse. Once there it is going to create a new FileStream for your file and write the stream to the response allowing the file to be accessed from your action.

If you’ve already got a stream you can use the FileStreamResult, which will read all of the data from your stream and then write it into the OutputStream to be send back in the response.

These really aren’t all that complicated, but if you want to have control over the file downloads in your application, this is a great way to do it. These give you the power to put any code you want in your action before you give back the FileResult.

HttpStatusCodeResult

The HttpStatusCodeResult is as simple as the ContentResult. In fact, the two are quite similar since they both just directly modify the response object.

This one lets you return any StatusCode you want and you can include a StatusDescription for specifics.

public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}

context.HttpContext.Response.StatusCode = StatusCode;
if (StatusDescription != null)
{
context.HttpContext.Response
.StatusDescription = StatusDescription;
}
}

See how simple that is? It’s basically just two lines of code with some null checking included.

HttpNotFoundResult and HttpUnauthorizedResult

These two results are actually just implementing the HttpStatusCodeResult, which means that they are very simple and just set the StatusCode to 404 for the HttpNotFoundResult and 401 for the HttpUnauthorizedResult.

JavaScriptResult

About as simple as plenty of the others, this is just a quick way of getting JavaScript returned from a action. It’s similar to the ContentResult, but it has the ContentType hardcoded to “application/x-javascript” and just writes out the Script property.

public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}

HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "application/x-javascript";

if (Script != null)
{
response.Write(Script);
}
}

JsonResult

This one is a bit more complex, but still not very. It also has hardcoded its ContentType, but what makes it a bit more complex is that it uses a hardcoded JavaScriptSerializer to serialize the JSON data before writing it directly to the response.

public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
String.Equals(context.HttpContext.Request.HttpMethod,
"GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(
MvcResources.JsonRequest_GetNotAllowed);
}

HttpResponseBase response = context.HttpContext.Response;

if (!String.IsNullOrEmpty(ContentType)) {
response.ContentType = ContentType;
}
else {
response.ContentType = "application/json";
}
if (ContentEncoding != null) {
response.ContentEncoding = ContentEncoding;
}
if (Data != null) {
JavaScriptSerializer serializer =
new JavaScriptSerializer();
response.Write(serializer.Serialize(Data));
}
}

RedirectResult and RedirectToRouteResult

These to are a little bit more complex, but both are ways of redirecting. Each one can either be a permanent or temporary redirect and they both just use the Redirect methods on the Response object.

For redirecting to a route, it is going to generate a URL to the route using the UrlHelper’s GenerateUrl method. For the RedirectResult it is instead going to use the UrlHelpers GenerateContentUrl method.

Either of these two are useful, and both will maintain your TempData if you need to pass something along with the redirect, all you have to do is put it in TempData.

Conclusion

I hope you’ve learned that the results of actions in MVC are not actually very complicated, but there is a lot you can do with them. You’re not being forced into just displaying views. You have a lot more control than that. None of them were that complicated were they? The code under the hood is not always complicated, so it’s worth taking a look from time to time. If you examine how something is working, it’s often far easier to use it.

Difference Between ViewBag and ViewData in MVC 3

If you’re new to ASP.NET MVC, you might be wondering what these two things are and when to use each one. If you’ve been using MVC and are just new to version 3 of MVC, you are probably wondering what this new ViewBag is for and if it’s different from the ViewData you’ve been using. In the beginning of the Summer, I had the opportunity to explain this difference to the two NimblePros interns when they started working on ASP.NET MVC 3 for the first time. This post should serve as a reference for them, me, and anyone else who is interested in knowing more about these two objects.

ViewBag and ViewData serve the same purpose in allowing developers to pass data from controllers to views. When you put objects in either one, those objects become accessible in the view. This is one way we interact between the view and the controller in ASP.NET MVC. We pass data from the view to the controller by placing it in these objects.

How ViewData Works

ViewData is a dictionary of objects that are accessible using strings as keys. This means that we will write code like this:

In the Controller

public ActionResult Index()
{
var softwareDevelopers = new List<string>
{
"Brendan Enrick",
"Kevin Kuebler",
"Todd Ropog"
};

ViewData["softwareDevelopers"] = softwareDevelopers;

return View();
}

In the View

<ul>
@foreach (var developer in (List<string>)ViewData["softwareDevelopers"])
{
<li>
@developer
</li>
}
</ul>

Notice that when we go to use out object on the view that we have to cast it since the ViewData is storing everything as object. Also, we need to be careful since we’re using magic strings to access these values.

How ViewBag Works

ViewBag uses the dynamic feature that was added in to C# 4. It allows an object to dynamically have properties added to it. The code we write using ViewBag will look like this:

In the Controller

public ActionResult Index()
{
var softwareDevelopers = new List<string>
{
"Brendan Enrick",
"Kevin Kuebler",
"Todd Ropog"
};

ViewBag.softwareDevelopers = softwareDevelopers;

return View();
}

In the View

<ul>
@foreach (var developer in ViewBag.softwareDevelopers)
{
<li>
@developer
</li>
}
</ul>

Notice here that we did not have to cast our object when using the ViewBag. This is because the dynamic we used lets us know the type. Keep in mind that these dynamics are as the name suggest, dynamic, which means that you need to be careful as these are basically magic properties instead of magic strings.

ViewBag and ViewData Under the Hood

So these two things seem to work almost exactly the same. What’s the difference? The difference is only in how you access the data. ViewBag is actually just a wrapper around the ViewData object, and its whole purpose is to let you use dynamics to access the data instead of using magic strings. Some people prefer one style over the other. You can pick whichever you like. In fact, because they’re the same data just with two different ways of accessing it, you can use them interchangeably. (I don’t recommend this, but you can do it.) If you want you are able to put data into the ViewBag and access it from the ViewData or put stuff in the ViewData and access it in the ViewBag.

This is all that the ViewBag property is. It’s just a DynamicViewDataDictionary with the ViewData as its data.

public dynamic ViewBag 
{
get
{
if (_dynamicViewData == null)
{
_dynamicViewData =
new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewData;
}
}

Then when we access the dynamic members of the DynamicViewDataDictionary, we are actually just getting this override of the DynamicObject’s TryGetMember. In this method, it’s just using the name of the member we tried to access as the string key for the ViewData dictionary.
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
result = ViewData[binder.Name];
return true;
}

So for a short answer:

These two objects are two different ways of accessing the exact same data. The ViewBag is just a dynamic wrapper around the ViewData dictionary.

Developers Give Back

This year’s Cleveland GiveCamp was a great success. The event ended with the completion of 23 software projects for 23 organizations who needed the support of a lot of fantastic developers. The GiveCamp event in Cleveland is one of many events that happen all over.

The event brings together non-profit organizations and charities who need assistance in developing software to fit their needs. These people get together with volunteers to figure out what they need and how to best achieve that over the course of a weekend. When the event begins, hundreds of developers gather, split into teams, and work together to complete these projects over a weekend. That’s right, it all happens in one weekend. That means that the event is fast-paced and delivers a great deal of value to the organizations.

I worked on the Euclid Beach Park Now with a great group of people including one other NimblePros team member. We were building a new, dynamic site for the group. Our main goals were to give the site a fresh new look and make it so that updates could be made easily to the site. We also wanted to allow visitors to the site to write about their experiences and memories of the Euclid Beach Park.

The group started with a lot of great .NET expertise, so they wanted to use a .NET-based CMS to allow them to customize it if needed. They decided to use Orchard CMS, so they asked if anyone at the event knew about Orchard CMS. Caitlin Steinert and I raised our hands as people who had used Orchard before. We joined the team.

The group of people working on that project were fantastic and were able to get up to speed with Orchard in just that weekend. We occasionally called in Kevin Kuebler with a question or two, but other than that the group was able to build the whole project in the course of the weekend. The site is now hosted through DiscountASP.NET who offers free Windows hosting for GiveCamp-created sites.

Without such a fantastic group of people there is no way we could have accomplished so much in the course of just that weekend. I’d like to thank the rest of my team for doing such a fantastic job for Euclid Beach Park Now who seemed to really love the site we built for them.

Our team

EuclidBeachParkNowTeam

Overmocking

One of the most powerful tool available to developers testing a legacy code base is the ability to mock out classes that their code depends on. This is of great importance since our unit tests need to limit the scope, and we do this by trying to limit our dependencies. Through mocking we can exchange one dependency on the infrastructure of our application for an in-memory mock.

Sometimes mocking is overused, and I am not just talking about cases where every objected gets mocked to the point where we’re testing nothing. I am talking about a different issue in mocking. I am talking about where developers put on their mocking blinders when unit testing. It’s an easy thing to do, and I’ve done it plenty of times myself.

Setting Up Our Example

We will start of by defining our example. We will have a method to do some sort of calculation (an ideal and easy testing scenario). It will be a legacy code base, which means that it is untested code and probably hard to test. We’ll start off by making it a private static method and put in a nice dependency that one might try to mock to avoid.

private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1)
{
var numbersInCalculation = Repository.GetNumbers()
.Where(n => n.IsActive);

foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

Now that we have this method, which is scary and really needs some testing we’ll take a look at the simple way of testing it; we will use parameter injection to pass in the dependency since we’re static we not easily able to do any other safe forms of dependency injection. When we do this, we end up with the following code.
 
private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1, IRepository repository)
{
var numbersInCalculation = repository.GetNumbers()
.Where(n => n.IsActive);

foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

This is a pretty simple change. We now mock out the repository and pass in the mock in our test and we tell it instead to return the collection we specify in memory instead of requesting the data from the database.

Why This is Wrong

My first question is, what is the name of the method? CalculateFooOnXyz. Notice that I didn’t say, “GetDataFromTheDatabase”. That’s because we shouldn’t be doing that. It isn’t part of the calculation. The numbers returned from the database are required for calculating, so that means that we should have that object as our dependency instead.

How We Change It

So instead of making the repository our parameter, we should make the collection of numbers our parameter. This way we’re depending on the in-memory collection of CLR objects. This is much less of a dependency, and in is not one that needs to be mocked. By doing this alternative we’re better following the Single Responsibility and Dependency Inversion principles.

Our best code for testing will look like this.

private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1, List<CalcNumbers> numbersInCalculation)
{
foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

Comments? Have a better way of doing it? Did I make a mistake?