Doug Chamberlain Doug Chamberlain - 1 month ago 4
Vb.net Question

What is a good pattern for handling results from ApiControllers?

I have an ApiController.

<HttpGet>
Public Function Find(ByVal planId As Integer) As IHttpActionResult
Dim results As IHttpActionResult

Try
Dim model As PlanModel = plansDAL.GetPlan(planId)
If model IsNot Nothing Then
results = BadRequest(String.Format("Plan {0} was not found.", planId))
Else
results = Ok(model)
End If

Catch ex As Exception
results = BadRequest(String.Format("Plan {0} was not found.", planId))
End Try

Return results
End Function


I'd prefer to not have nested statements like this.

I'd like to know of a better pattern for returning the correct result when a controller action fails/redirect/finished inserting. so the controller may return 200 ok and content, or it may return 404 not found.

I have an idea of something to try, but I'd rather use some established patterns. My idea is to add a private member of type Response. then I can update that object in my controller and return it once and only once at the end.

But, I'm not sure how to make it where I don't place a burden on the developers to correctly craft responses every time.

Answer

I think this article on mvc4 provides the pattern I was looking for. It seems to streamline the method, and provides a mechanism to exercise unit tests with explicit expectations. It also makes sure that unhandled exceptions are bubbled up and will return YSOD, until they are handled as well. Possibly, they could be handled in a global error module.

All code below was written without an IDE, mistakes in syntax probably exist

 <HttpGet>
        Public Function Find(ByVal planId As Integer) As IHttpActionResult    
               Dim model As PlanModel = plansDAL.GetPlan(planId)

               If model is Nothing Then
                 throw new HttpResponseException(HttpStatusCode.NotFound)
               End If

            Return Ok(model)
        End Function

Now, for added bonus. Since i'm answering my own question. If I know want to write the unit tests, they are very straightForward.

<TestMethod>
public sub Should_Return_Ok_When_Plan_Is_Found()

dim mockedService as new Mock(Of plansDAL)
dim mockPlan as new PlanModel 'set this up however to be the expected values.
dim controller as new PlanController()

mockedService.setup(sub(s) s.GetPlan(it.isAny(Of Integer))).returns(mockPlan)
dim result as IHttpActionResult = controller.find(1)


Assert.areEqual(mockPlan,result.contents)

end sub
Comments