Render MVC PartialView into SignalR response

前端 未结 6 992
抹茶落季
抹茶落季 2020-12-13 04:19

I would like to render a PartialView to an HTML string so I can return it to a SignalR ajax request.

Something like:

SignalR Hub (mySignal

相关标签:
6条回答
  • 2020-12-13 04:45

    Have you thought about using a razor template engine like http://razorengine.codeplex.com/ ? You can't use it to parse partial views but you can use it to parse razor templates, which are almost similar to partial views.

    0 讨论(0)
  • 2020-12-13 04:45

    How about using the RazorEngineHost and RazorTemplateEngine. I found this nice article that might be what you're looking for. It's about hosting Razor outside of ASP.NET (MVC).

    0 讨论(0)
  • 2020-12-13 04:47

    Probably the best choice is to use RazorEngine, as Wim is suggesting.

    public class mySignalRHub: Hub
    {
        public string getTableHTML()
        {
            var viewModel = new[] { new DataItem { Value1 = "v1", Value2 = "v2" } };
    
            var template = File.ReadAllText(Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory,
                @"Views\PathToTablePartialView\_MyTablePartialView.cshtml"));
    
            return Engine.Razor.RunCompile(template, "templateKey", null, viewModel);
        }
    }
    
    0 讨论(0)
  • 2020-12-13 04:55

    Further to the answer provided by @user1010609 above, I struggled through this as well and have ended up with a function that returns the rendered PartialView given a controller name, path to the view and model.

    Takes account of the fact you don't have a controller and hence none of the usual state as coming from a SignalR event.

    public static string RenderPartialView(string controllerName, string partialView, object model)
    {
        var context = new HttpContextWrapper(System.Web.HttpContext.Current) as HttpContextBase;
    
        var routes = new System.Web.Routing.RouteData();
        routes.Values.Add("controller", controllerName);
    
        var requestContext = new RequestContext(context, routes);
    
        string requiredString = requestContext.RouteData.GetRequiredString("controller");
        var controllerFactory = ControllerBuilder.Current.GetControllerFactory();
        var controller = controllerFactory.CreateController(requestContext, requiredString) as ControllerBase;
    
        controller.ControllerContext = new ControllerContext(context, routes, controller);      
    
        var ViewData = new ViewDataDictionary();
    
        var TempData = new TempDataDictionary();
    
        ViewData.Model = model;
    
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialView);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, ViewData, TempData, sw);
    
            viewResult.View.Render(viewContext, sw);
            return sw.GetStringBuilder().ToString();
        }
    }
    

    You would call it with something similar to:

    RenderPartialView("MyController", "~/Views/MyController/_partialView.cshtml", model);
    
    0 讨论(0)
  • 2020-12-13 04:57

    Based on the answers supplied to asimilar question below, I would suggest using

    Html.Partial(partialViewName)

    It returns an MvcHtmlString, which you should able to use as the content of your SignalR reponse. I have not tested this, however.

    Stack Overflow Question: Is it possible to render a view outside a controller?

    0 讨论(0)
  • 2020-12-13 05:02

    Here, this is what I use in Controllers for ajax, I modified it a bit so it can be called from method instead of controller, method returnView renders your view and returns HTML string so you can insert it with JS/jQuery into your page when you recive it on client side:

      public static string RenderPartialToString(string view, object model, ControllerContext Context)
            {
                if (string.IsNullOrEmpty(view))
                {
                    view = Context.RouteData.GetRequiredString("action");
                }
    
                ViewDataDictionary ViewData = new ViewDataDictionary();
    
                TempDataDictionary TempData = new TempDataDictionary();
    
                ViewData.Model = model;
    
                using (StringWriter sw = new StringWriter())
                {
                    ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(Context, view);
    
                    ViewContext viewContext = new ViewContext(Context, viewResult.View, ViewData, TempData, sw);
    
                    viewResult.View.Render(viewContext, sw);
    
                    return sw.GetStringBuilder().ToString();
                }
            }
    
            //"Error" should be name of the partial view, I was just testing with partial error view
            //You can put whichever controller you want instead of HomeController it will be the same
            //You can pass model instead of null
            private string returnView()
            {
                var controller = new HomeController();
                controller.ControllerContext = new ControllerContext(HttpContext,new System.Web.Routing.RouteData(), controller);
                return RenderPartialToString("Error", null, new ControllerContext(controller.Request.RequestContext, controller));
            }
    

    I didn't test it on a Hub but it should work.

    0 讨论(0)
提交回复
热议问题