Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保存渲染视图的HTML?_C#_Html_Asp.net Core - Fatal编程技术网

C# 如何保存渲染视图的HTML?

C# 如何保存渲染视图的HTML?,c#,html,asp.net-core,C#,Html,Asp.net Core,基本上,用户进入页面,生成报告并决定是否保存 如果是,那么我必须将这个html保存为静态html文件 如果是这样的话,那就太好了: public IActionResult GetReport() { (...) string html = View(model).ToString(); save_to_database(html); return View(model); } 但是,我找到的唯一解决办法是在那个页面上按按钮 它执行如下JavaScript: v

基本上,用户进入页面,生成报告并决定是否保存

如果是,那么我必须将这个html保存为静态html文件

如果是这样的话,那就太好了:

public IActionResult GetReport()
{
    (...)
    string html = View(model).ToString();
    save_to_database(html);
    return View(model);
}
但是,我找到的唯一解决办法是在那个页面上按按钮 它执行如下JavaScript:

var html = new XMLSerializer().serializeToString(document); 

sendHTMLViaAPI(html);
并通过post将html发送到API

所以,我很好奇是否有C#ish的方法可以做到这一点?在控制器的方法中


还有:这有潜在危险吗?例如,会话内容可以保存在该html文件中,或者用户可以通过API发送非html文件的内容…

如果我理解您的意思正确,此解决方案可能就是您想要的:

[HttpPost]
public IActionResult GetHTML()
{
    var model = new ModelClass() { Content = "Hi!" };

    // or
    // return PartialView("GetHTML", model);
    return PartialView(nameof(GetHTML), model);
}
在文件
GetHTML.cshtml
中:

@model ModelClass 
<div>
    Content: @Model.Content
</div>
@model模型类
Content:@Model.Content
在客户端,当用户希望以字符串形式获取HTML时,可以尝试使用jquery获取:

$.post('/home/gethtml').done(function (html) {
    // html is a string here..

    // <div>
    //     Content: Hi!
    // </div>

    $('body').append(html);
});
$.post('/home/gethtml').done(函数(html){
//html在这里是一个字符串。。
// 
//内容:嗨!
// 
$('body').append(html);
});

或创建自定义服务:

ViewRender.cs

使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.AspNetCore.Mvc.Abstractions;
使用Microsoft.AspNetCore.Mvc.ModelBinding;
使用Microsoft.AspNetCore.Mvc.Razor;
使用Microsoft.AspNetCore.Mvc.Rendering;
使用Microsoft.AspNetCore.Mvc.ViewFeatures;
使用Microsoft.AspNetCore.Routing;
使用制度;
使用System.IO;
公共类ViewRender:IViewRender
{
私人IRazorViewEngine_viewEngine;
私有ITempDataProvider _tempDataProvider;
私人IServiceProvider_服务提供商;
公共视图渲染(
IRazorViewEngine视图引擎,
ITempDataProvider tempDataProvider,
IServiceProvider服务提供商)
{
_viewEngine=viewEngine;
_tempDataProvider=tempDataProvider;
_服务提供者=服务提供者;
}
公共字符串呈现(字符串名称)
{
var actionContext=GetActionContext();
var viewEngineResult=_viewEngine.FindView(actionContext,name,false);
如果(!viewEngineResult.Success)
{
抛出新的InvalidOperationException(string.Format(“找不到视图”{0}',名称));
}
var view=viewEngineResult.view;
使用(var输出=新的StringWriter())
{
var viewContext=新的viewContext(
行动背景,
看法
新ViewDataDictionary(
metadataProvider:new EmptyModelMetadataProvider(),
modelState:新的ModelStateDictionary())
{
模型=空
}, 
新的TempDataDictionary(actionContext.HttpContext,_tempDataProvider),
产出,
新的HtmlHelpOptions());
view.RenderAsync(viewContext.GetAwaiter().GetResult();
返回output.ToString();
}
}
公共字符串呈现(字符串名称,TModel模型)
{
var actionContext=GetActionContext();
var viewEngineResult=_viewEngine.FindView(actionContext,name,false);
如果(!viewEngineResult.Success)
{
抛出新的InvalidOperationException(string.Format(“找不到视图”{0}',名称));
}
var view=viewEngineResult.view;
使用(var输出=新的StringWriter())
{
var viewContext=新的viewContext(
行动背景,
看法
新ViewDataDictionary(
metadataProvider:new EmptyModelMetadataProvider(),
modelState:新的ModelStateDictionary())
{
模型
}, 
新的TempDataDictionary(actionContext.HttpContext,_tempDataProvider),
产出,
新的HtmlHelpOptions());
view.RenderAsync(viewContext.GetAwaiter().GetResult();
返回output.ToString();
}
}
私有ActionContext GetActionContext()
{
var httpContext=new DefaultHttpContext();
httpContext.RequestServices=\u serviceProvider;
返回新的ActionContext(httpContext,new RoutedData(),new ActionDescriptor());
}
}
IViewRender.cs:

公共接口IViewRender
{
字符串呈现(字符串名称);
字符串呈现(字符串名称,TModel模型);
}
Startup.cs:

services.AddTransient();

用法:

public class HomeController : Controller
{
    private readonly IViewRender _viewRender { get; set; }

    public HomeController(IViewRender viewRender)
    {
        _viewRender = viewRender;
    }

    public IActionResult GetHTML()
    {
        string htmlWithoutModel = _viewRender.Render("Home/GetHTML");

        var model = new ModelClass() { Content = "Hi!" };

        string htmlWithModel = _viewRender.Render<ModelClass>("Home/GetHTML", model);

        //...
    }
}
公共类HomeController:控制器
{
私有只读IViewRender _viewRender{get;set;}
公共家庭控制器(IViewRender viewRender)
{
_viewRender=viewRender;
}
public IActionResult GetHTML()
{
字符串htmlWithoutModel=_viewRender.Render(“Home/GetHTML”);
var model=newmodelclass(){Content=“Hi!”};
字符串htmlWithModel=\u viewRender.Render(“Home/GetHTML”,model);
//...
}
}

来自该url的响应副本^

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.IO;
using System.Threading.Tasks;

namespace CC.Web.Helpers
{
    public static class ControllerExtensions
    {
        public static async Task<string> RenderViewAsync<TModel>(this Controller controller, string viewName, TModel model, bool partial = false)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                viewName = controller.ControllerContext.ActionDescriptor.ActionName;
            }

            controller.ViewData.Model = model;

            using (var writer = new StringWriter())
            {
                IViewEngine viewEngine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
                ViewEngineResult viewResult = viewEngine.FindView(controller.ControllerContext, viewName, !partial);

                if (viewResult.Success == false)
                {
                    return $"A view with the name {viewName} could not be found";
                }

                ViewContext viewContext = new ViewContext(
                    controller.ControllerContext,
                    viewResult.View,
                    controller.ViewData,
                    controller.TempData,
                    writer,
                    new HtmlHelperOptions()
                );

                await viewResult.View.RenderAsync(viewContext);

                return writer.GetStringBuilder().ToString();
            }
        }
    }
}
或者这是一个局部视图:

partialViewHtml = await this.RenderViewAsync("Report", model, true);

可能的重复:嗯,8年来没有任何变化?:)抱歉,这是您的目标:将razor页面中的HTML代码转换为字符串吗?@T–nNguyễn将
视图(模型)
转换为字符串(即HTML)。基本上是为用户呈现的页面,我还想保存例如字符串
string html=View(model).ToString()
类似这样的东西。是的,这是解决方案之一,但有没有C#方法?e、 g在控制器中保存它method@Joelty我已经更新了一个服务来获取控制器中的HTML字符串。奇怪的是,
htmlWithModel
抛出
ArgumentOutOfRangeException:索引超出范围。必须为非负数且小于集合的大小。参数名称:index System.Collections.Generic.List.get\u Item(int index)
public class HomeController : Controller
{
    private readonly IViewRender _viewRender { get; set; }

    public HomeController(IViewRender viewRender)
    {
        _viewRender = viewRender;
    }

    public IActionResult GetHTML()
    {
        string htmlWithoutModel = _viewRender.Render("Home/GetHTML");

        var model = new ModelClass() { Content = "Hi!" };

        string htmlWithModel = _viewRender.Render<ModelClass>("Home/GetHTML", model);

        //...
    }
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.IO;
using System.Threading.Tasks;

namespace CC.Web.Helpers
{
    public static class ControllerExtensions
    {
        public static async Task<string> RenderViewAsync<TModel>(this Controller controller, string viewName, TModel model, bool partial = false)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                viewName = controller.ControllerContext.ActionDescriptor.ActionName;
            }

            controller.ViewData.Model = model;

            using (var writer = new StringWriter())
            {
                IViewEngine viewEngine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
                ViewEngineResult viewResult = viewEngine.FindView(controller.ControllerContext, viewName, !partial);

                if (viewResult.Success == false)
                {
                    return $"A view with the name {viewName} could not be found";
                }

                ViewContext viewContext = new ViewContext(
                    controller.ControllerContext,
                    viewResult.View,
                    controller.ViewData,
                    controller.TempData,
                    writer,
                    new HtmlHelperOptions()
                );

                await viewResult.View.RenderAsync(viewContext);

                return writer.GetStringBuilder().ToString();
            }
        }
    }
}
viewHtml = await this.RenderViewAsync("Report", model);
partialViewHtml = await this.RenderViewAsync("Report", model, true);