0

I have an ASP.NET MVC controller endpoint of type ActionResult that returns a ViewResult by calling Controller.View(<some html>).

When integration testing this endpoint is it possible to convert the HttpResponseMessage to a ViewResult?

1
  • Controller.View(<some html>) - I don't see an overload accepting HTML, can you please give some more details, maybe a minimal reproducible example? But if I understand your case correctly (and I probably don't), then no, you will have the generated HTML for view result in your HttpResponseMessage. If you want to test the ViewResult itself you need to setup the controller context and call the YourController.YourAction as a simple method, not via the HTTP. For HTTP - you need to analyze the generated HTML. Commented Jun 21 at 6:27

1 Answer 1

2

Unfortunately, there is no support for direct conversion from HttpResponseMessage to ViewResult.

Implementation:

  1. Create a model class for API response.
using System.Net;

public class ApiReponseModel<T>
{
    public HttpStatusCode StatusCode { get; private set; }
    public string ResponseMessage { get; private set; }
    public T Data { get; private set; }

    public ApiReponseModel(HttpStatusCode statusCode)
    {
        StatusCode = statusCode;
    }

    public ApiReponseModel(HttpStatusCode statusCode, T data)
    {
        StatusCode = statusCode;
        Data = data;
    }

    public ApiReponseModel(HttpStatusCode statusCode, string responseMessage)
    {
        StatusCode = statusCode;
        ResponseMessage = responseMessage;
    }

    public ApiReponseModel(HttpStatusCode statusCode, string responseMessage, T data)
    {
        StatusCode = statusCode;
        ResponseMessage = responseMessage;
        Data = data;
    }
}
  1. Implement the helper method for converting HttpResponseMessage to ViewResult.
using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;

public static class ViewResultHelper
{
    public static async Task<ViewResult> ToViewResultAsync<T>(
        this HttpResponseMessage response,
        string viewName,
        string errorViewName = "/Views/Shared/Error.cshtml")
    {
        if (!response.IsSuccessStatusCode)
        {
            var errorRespContentString = await response.Content.ReadAsStringAsync();

            return new ViewResult
            {
                ViewName = errorViewName,
                ViewData = new ViewDataDictionary()
                {
                    Model = new ApiReponseModel<T>
                    (
                        response.StatusCode,
                        response.ReasonPhrase,
                        JsonConvert.DeserializeObject<T>(errorRespContentString)
                    )
                }
            };
        }

       var respContentString = await response.Content.ReadAsStringAsync();

        return new ViewResult
        {
            ViewName = viewName,
            ViewData = new ViewDataDictionary()
            {
                Model = new ApiReponseModel<T>
                (
                    response.StatusCode,
                    JsonConvert.DeserializeObject<T>(respContentString)
                 )
            }
        };
    }
}
  1. Caller for the helper method in your controller action.
/* Mocked response */
/*
User user = new User { Name = "Test User" };
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StringContent(JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json")
};
*/

return await response.ToViewResultAsync<User>("<Your View Name>");
  1. In your view, it should expect the Model with ApiReponseModel<T> type.
@model /* Your Project namespace */.Models.ApiReponseModel<User>

@using Newtonsoft.Json


<!-- To get API response body data -->
<code>
    @JsonConvert.SerializeObject(Model.Data, Formatting.Indented)
</code>
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.