jcollum
jcollum

Reputation: 46569

does MVC enumerate results *after* a return statement somehow?

I have code that looks like this:

 [HttpPost]
 public ActionResult CustomerSearch(string firstName ...
 {
 ...
 try 
 {
   var results = from t in db.Customers... 
   var custResults = results.Select(c=> new string[] { ... });
   return this.Json(custResults );
 }    
 catch (TimeoutException exc1)
 { 
    return this.Json(new {error = "Search failed (timeout)"});   
 }
 catch (System.Exception exc)
 { ... }
}

I test this by setting the timeout on the sql call to something small (5s). The exception is certainly happening, I can see it in my logs and the protected override void OnException event is firing. But the catch for the TimeoutException or Exception never gets hit. I suspect there's something about how MVC works that I'm not understanding.

The peculiar thing is that if I put a breakpoint on the return this.Json(custResults); I can pass that line with no problem. But if I put a ToList() on the .Select(..) then the TimeoutException will be thrown. How can MVC enumerate a result set after a return statement has been executed?

Upvotes: 2

Views: 193

Answers (2)

sehe
sehe

Reputation: 392903

The Select() call will create a deferred (lazy) enumeration

http://msdn.microsoft.com/en-us/library/bb548891.aspx:

This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

Doing ToList() or ToArray() will create a non-deferred collection out of it

Upvotes: 0

Guvante
Guvante

Reputation: 19203

Json is likely a lazy method, in that it does not enumerate the result set given. Instead it wraps the result set in another enumerator. This means that until the MVC needs the results the SQL is never executed. Given that your functions do not perform the enumeration but MVC does, this causes the exception to happen where you cannot wrap it in a try/catch block.

As you mentioned in your post added a ToList() will cause the enumeration of the set and storage into a location, causing the exception to happen where you expect it to.

Upvotes: 3

Related Questions