基本上,用户进入页面,生成报告并决定是否保存该报告。
如果是,那么我必须将此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);
并通过邮寄将该html发送到API。
所以,我很好奇是否有C#方式可以做到这一点?在Controller的方法中。
还:那有潜在危险吗?例如。会话内容可以保存在该html文件中,或者用户可以通过API发送非HTML文件的内容...
答案 0 :(得分:2)
如果我理解您的意思是正确的,那么此解决方案可能就是您想要的:
[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>
在客户端,当用户想要以字符串形式获取HTML时,您可以尝试使用jquery来获取它:
$.post('/home/gethtml').done(function (html) {
// html is a string here..
// <div>
// Content: Hi!
// </div>
$('body').append(html);
});
或创建您的自定义服务:
ViewRender.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;
using System;
using System.IO;
public class ViewRender : IViewRender
{
private IRazorViewEngine _viewEngine;
private ITempDataProvider _tempDataProvider;
private IServiceProvider _serviceProvider;
public ViewRender(
IRazorViewEngine viewEngine,
ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
public string Render(string name)
{
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, name, false);
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", name));
}
var view = viewEngineResult.View;
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary<string>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary())
{
Model = null
},
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
output,
new HtmlHelperOptions());
view.RenderAsync(viewContext).GetAwaiter().GetResult();
return output.ToString();
}
}
public string Render<TModel>(string name, TModel model)
{
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, name, false);
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", name));
}
var view = viewEngineResult.View;
using (var output = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
view,
new ViewDataDictionary<TModel>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary())
{
Model = model
},
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
output,
new HtmlHelperOptions());
view.RenderAsync(viewContext).GetAwaiter().GetResult();
return output.ToString();
}
}
private ActionContext GetActionContext()
{
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = _serviceProvider;
return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
}
}
IViewRender.cs :
public interface IViewRender
{
string Render(string name);
string Render<TModel>(string name, TModel model);
}
Startup.cs :
services.AddTransient<IViewRender, ViewRender>();
用法:
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);
//...
}
}
答案 1 :(得分:0)
Return View as String in .NET Core
该网址的回复副本^
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);
或者对于PartialView:
partialViewHtml = await this.RenderViewAsync("Report", model, true);