2

I'm migrating one of my Asp.Net MVC 5 project to Asp.Net Core. I have a custom ActionResult, which renders the view as partial view if the request was ajax request, and renders the view as normal view with layout if the request was a normal request. I have issues with converting the old ExecuteResult to new ExecuteResultAsync.

Here it is my old code:

public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.Buffer = true;
        context.Controller.ViewData.Model = Model;

        using (var sw = new StringWriter())
        {
            var request = context.RequestContext.HttpContext.Request;

            if (string.IsNullOrEmpty(ViewName))
            {
                ViewName = request.RequestContext.RouteData.GetRequiredString("action");
            }

            var viewResult = request.IsAjaxRequest()
                ? ViewEngines.Engines.FindPartialView(context, ViewName)
                : ViewEngines.Engines.FindView(context, ViewName, "_Layout");

            var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);
            context.HttpContext.Response.Write(sw.GetStringBuilder().ToString());
        }
    }

And here it is my half converted code:

public override async Task ExecuteResultAsync(ActionContext context)
    {
        context.HttpContext.Response.Buffer = true; //broken
        context.HttpContext.Controller.ViewData.Model = Model; //broken

        using (var sw = new StringWriter())
        {
            var request = context.HttpContext.Request;

            if (string.IsNullOrEmpty(ViewName))
                ViewName = context.ActionDescriptor.Name;

            var engine = context.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;

            var viewResult = request.Headers["X-Requested-With"] == "XMLHttpRequest"
                ? engine.FindPartialView(context, ViewName)
                : engine.FindView(context, ViewName);

            var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw, new HtmlHelperOptions()); //broken
            await viewResult.View.RenderAsync(viewContext);
            await context.HttpContext.Response.WriteAsync(sw.GetStringBuilder().ToString());
        }
    }

My main issue is the ControllerContext -> ActionContext migrating. Please help me to convert ControllerContext to ActionContext. Thank you very much!

1 Answer 1

1

Ehh, put something together to fit RC2 bits real quick. Feel free to improve on it:

public override async Task ExecuteResultAsync(ActionContext context)
{
    var request = context.HttpContext.Request;

    if (string.IsNullOrEmpty(ViewName))
    {
        ViewName = context.ActionDescriptor.Name;
    }

    var engine = context.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;

    var viewResult = engine.FindView(context, ViewName, isMainPage: request.Headers["X-Requested-With"] != "XMLHttpRequest");
    var tempDataProvider = context.HttpContext.RequestServices.GetService(typeof(ITempDataProvider)) as ITempDataProvider;
    var modelMetaDataProvider = context.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider)) as IModelMetadataProvider;

    using (var writer = new HttpResponseStreamWriter(context.HttpContext.Response.Body, Encoding.UTF8))
    {
        var tempData = new TempDataDictionary(context.HttpContext, tempDataProvider);
        var viewData = new ViewDataDictionary(modelMetaDataProvider, context.ModelState)
        {
            Model = Model
        };
        var viewContext = new ViewContext(
            context,
            viewResult.View,
            viewData,
            tempData,
            writer,
            new HtmlHelperOptions());

        await viewResult.View.RenderAsync(viewContext);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, I will check it!
This line has this error: var tempData = new TempDataDictionary(context.HttpContext, tempDataProvider); //Argument 1: cannot convert from 'Microsoft.AspNet.Http.HttpContext' to 'Microsoft.AspNet.Http.IHttpContextAccessor'
This should be the correct line: var tempData = new TempDataDictionary(new HttpContextAccessor { HttpContext = context.HttpContext }, tempDataProvider);
Note, my bits are for RC2 :)
It would be nice to rewrite this sample to new version. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.