繁体   English   中英

将MVC PartialView渲染为SignalR响应

[英]Render MVC PartialView into SignalR response

我想将PartialView呈现为HTML字符串,以便将其返回到SignalR ajax请求。

就像是:

SignalR Hub (mySignalHub.cs)

public class mySignalRHub: Hub
{
    public string getTableHTML()
    {
        return PartialView("_MyTablePartialView", GetDataItems()) // *How is it possible to do this*
    }
}

Razor PartialView(_MyTablePartialView.cshtml)

@model IEnumerable<DataItem>

<table>
    <tbody>
        @foreach (var dataItem in Model)
        {
        <tr>
            <td>@dataItem.Value1</td>
            <td>@dataItem.Value2</td>
        </tr>
        }
    </tbody>
</table>

HTML(MySignalRWebPage.html)

<Script>
    ...      
    //Get HTML from SignalR function call
    var tableHtml = $.connection.mySignalRHub.getTableHTML();

    //Inject into div
    $('#tableContainer).html(tableHtml);
</Script>

<div id="tableContainer"></div>

我的问题是我似乎无法在Controller之外渲染PartialView。 甚至可以在Controller外部渲染PartialView吗? 能够利用Razor附带的令人敬畏的HTML生成能力将是非常好的。

我错了吗? 还有另外一种方法吗?

这里,这是我在控制器中使用的ajax,我修改了一下所以它可以从方法而不是控制器调用,方法returnView渲染你的视图并返回HTML字符串,这样你就可以将JS / jQuery插入你的页面了你在客户端收到它:

  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));
        }

我没有在Hub上测试它,但它应该工作。

可能最好的选择是使用RazorEngine ,正如Wim所暗示的那样。

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);
    }
}

除了上面@ user1010609提供的答案之外,我也在努力解决这个问题,并且最终得到了一个函数,该函数返回渲染的PartialView给定控制器名称,视图和模型的路径。

考虑到你没有控制器这一事实,因此没有一个通常的状态来自SignalR事件。

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();
    }
}

你会用类似的东西来称呼它:

RenderPartialView("MyController", "~/Views/MyController/_partialView.cshtml", model);

你有没有想过使用像http://razorengine.codeplex.com/这样的剃须刀模板引擎? 您不能使用它来解析部分视图,但您可以使用它来解析剃刀模板,这几乎与部分视图类似。

如何使用RazorEngineHostRazorTemplateEngine 我发现这篇很好的文章可能就是你要找的东西。 它是关于在ASP.NET(MVC)之外托管Razor。

基于下面提供的相似问题的答案,我建议使用

Html.Partial( partialViewName

它返回一个MvcHtmlString,您应该将其用作SignalR响应的内容。 但是,我没有测试过这个。

堆栈溢出问题: 是否可以在控制器外渲染视图?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM