C# 如何将MVC局部视图(包含剑道网格)呈现为html字符串
我试图使用“假控制器上下文”将MVC局部视图(包含剑道网格)呈现为html字符串 我想知道是否有一种方法可以为它创建合适的假控制器。。因此,我可以通过静态方法访问MVC局部视图(包含剑道网格) 在此方面的任何帮助都将不胜感激。提前谢谢 我一直收到这个错误:C# 如何将MVC局部视图(包含剑道网格)呈现为html字符串,c#,asp.net-mvc,razor,kendo-grid,kendo-asp.net-mvc,C#,Asp.net Mvc,Razor,Kendo Grid,Kendo Asp.net Mvc,我试图使用“假控制器上下文”将MVC局部视图(包含剑道网格)呈现为html字符串 我想知道是否有一种方法可以为它创建合适的假控制器。。因此,我可以通过静态方法访问MVC局部视图(包含剑道网格) 在此方面的任何帮助都将不胜感激。提前谢谢 我一直收到这个错误: [ArgumentNullException: Value cannot be null. Parameter name: controllerContext] System.Web.Mvc.ChildActionValueProvid
[ArgumentNullException: Value cannot be null.
Parameter name: controllerContext]
System.Web.Mvc.ChildActionValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +137
System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +80
System.Web.Mvc.ControllerBase.get_ValueProvider() +39
Kendo.Mvc.UI.Grid`1.ProcessDataSource() +254
Kendo.Mvc.UI.Grid`1.WriteHtml(HtmlTextWriter writer) +818
Kendo.Mvc.UI.WidgetBase.ToHtmlString() +102
Kendo.Mvc.UI.Fluent.WidgetBuilderBase`2.ToHtmlString() +15
System.Web.WebPages.WebPageBase.Write(Object value) +103
ASP._Page_Views_Reporting_ReportElement_SimpleKendoGrid_cshtml.Execute() in c:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Views\Reporting\ReportElement_SimpleKendoGrid.cshtml:8
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +253
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +148
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +122
xxx.Api.Ui.Helpers.ViewRenderer.RenderViewToStringInternal(String viewPath, Object model, Boolean partial) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:218
xxx.Api.Ui.Helpers.ViewRenderer.RenderPartialView(String viewPath, Object model) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:81
xxx.Api.Ui.Helpers.ViewRenderer.RenderPartialView(String viewPath, Object model, ControllerContext controllerContext) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:149
xxx.Api.Ui.Controllers.ReportingController.Test() in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Controllers\ReportingController.cs:86
lambda_method(Closure , ControllerBase , Object[] ) +87
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +229
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +67
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +72
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +38
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +186
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +157
值不能为null。
参数名称:controllerContext
描述:执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解更多信息
有关错误的信息及其在代码中的来源
Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: controllerContext
Source Error:
Line 8: @(Html.Kendo().Grid<SimpleKendoModelData>()
视图渲染器类:
// Read: https://weblog.west-wind.com/posts/2012/may/30/rendering-aspnet-mvc-views-to-string
/// <summary>
/// Class that renders MVC views to a string using the
/// standard MVC View Engine to render the view.
/// </summary>
public class ViewRenderer
{
/// <summary>
/// Required Controller Context
/// </summary>
protected ControllerContext Context { get; set; }
/// <summary>
/// Initializes the ViewRenderer with a Context.
/// </summary>
/// <param name="controllerContext">
/// If you are running within the context of an ASP.NET MVC request pass in
/// the controller's context.
/// Only leave out the context if no context is otherwise available.
/// </param>
public ViewRenderer(ControllerContext controllerContext = null)
{
// Create a known controller from HttpContext if no context is passed
if (controllerContext == null)
{
if (HttpContext.Current != null)
{
var currentContext = HttpContext.Current;
var context = new HttpContextWrapper(currentContext);
var routeData = new RouteData();
controllerContext = new ControllerContext(new RequestContext(context, routeData), new FakeController());
}
else
throw new InvalidOperationException(
"ViewRenderer must run in the context of an ASP.NET " +
"Application and requires HttpContext.Current to be present.");
}
Context = controllerContext;
}
/// <summary>
/// Renders a full MVC view to a string. Will render with the full MVC
/// View engine including running _ViewStart and merging into _Layout
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to render the view with</param>
/// <returns>String of the rendered view or null on error</returns>
public string RenderView(string viewPath, object model)
{
return RenderViewToStringInternal(viewPath, model, false);
}
/// <summary>
/// Renders a partial MVC view to string. Use this method to render
/// a partial view that doesn't merge with _Layout and doesn't fire
/// _ViewStart.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to pass to the viewRenderer</param>
/// <returns>String of the rendered view or null on error</returns>
public string RenderPartialView(string viewPath, object model)
{
return RenderViewToStringInternal(viewPath, model, true);
}
/// <summary>
/// Renders a partial MVC view to string. Use this method to render
/// a partial view that doesn't merge with _Layout and doesn't fire
/// _ViewStart.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to pass to the viewRenderer</param>
/// <param name="controllerContext">Active Controller context</param>
/// <returns>String of the rendered view or null on error</returns>
public static string RenderView(string viewPath, object model,
ControllerContext controllerContext)
{
ViewRenderer renderer = new ViewRenderer(controllerContext);
return renderer.RenderView(viewPath, model);
}
/// <summary>
/// Renders a partial MVC view to string. Use this method to render
/// a partial view that doesn't merge with _Layout and doesn't fire
/// _ViewStart.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to pass to the viewRenderer</param>
/// <param name="controllerContext">Active Controller context</param>
/// <param name="errorMessage">optional out parameter that captures an error message instead of throwing</param>
/// <returns>String of the rendered view or null on error</returns>
public static string RenderView(string viewPath, object model,
ControllerContext controllerContext,
out string errorMessage)
{
errorMessage = null;
try
{
ViewRenderer renderer = new ViewRenderer(controllerContext);
return renderer.RenderView(viewPath, model);
}
catch (Exception ex)
{
errorMessage = ex.GetBaseException().Message;
}
return null;
}
/// <summary>
/// Renders a partial MVC view to string. Use this method to render
/// a partial view that doesn't merge with _Layout and doesn't fire
/// _ViewStart.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to pass to the viewRenderer</param>
/// <param name="controllerContext">Active controller context</param>
/// <returns>String of the rendered view or null on error</returns>
public static string RenderPartialView(string viewPath, object model,
ControllerContext controllerContext)
{
ViewRenderer renderer = new ViewRenderer(controllerContext);
return renderer.RenderPartialView(viewPath, model);
}
/// <summary>
/// Renders a partial MVC view to string. Use this method to render
/// a partial view that doesn't merge with _Layout and doesn't fire
/// _ViewStart.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">The model to pass to the viewRenderer</param>
/// <param name="controllerContext">Active controller context</param>
/// <param name="errorMessage">optional output parameter to receive an error message on failure</param>
/// <returns>String of the rendered view or null on error</returns>
public static string RenderPartialView(string viewPath, object model,
ControllerContext controllerContext,
out string errorMessage)
{
errorMessage = null;
try
{
ViewRenderer renderer = new ViewRenderer(controllerContext);
return renderer.RenderPartialView(viewPath, model);
}
catch (Exception ex)
{
errorMessage = ex.GetBaseException().Message;
}
return null;
}
/// <summary>
/// Internal method that handles rendering of either partial or
/// or full views.
/// </summary>
/// <param name="viewPath">
/// The path to the view to render. Either in same controller, shared by
/// name or as fully qualified ~/ path including extension
/// </param>
/// <param name="model">Model to render the view with</param>
/// <param name="partial">Determines whether to render a full or partial view</param>
/// <returns>String of the rendered view</returns>
protected string RenderViewToStringInternal(string viewPath, object model,
bool partial = false)
{
// first find the ViewEngine for this view
ViewEngineResult viewEngineResult = null;
if (partial)
viewEngineResult = ViewEngines.Engines.FindPartialView(Context, viewPath);
else
viewEngineResult = ViewEngines.Engines.FindView(Context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("ViewCouldNotBeFound");
// get the view and attach the model to view data
var view = viewEngineResult.View;
Context.Controller.ViewData.Model = model;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(Context, view,
Context.Controller.ViewData,
Context.Controller.TempData,
sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result;
}
/// <summary>
/// Creates an instance of an MVC controller from scratch
/// when no existing ControllerContext is present
/// </summary>
/// <typeparam name="T">Type of the controller to create</typeparam>
/// <returns></returns>
public static T CreateController<T>(RouteData routeData = null)
where T : Controller, new()
{
T controller = new T();
// Create an MVC Controller Context
HttpContextBase wrapper = null;
if (HttpContext.Current != null)
wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
//else
// wrapper = CreateHttpContextBase(writer);
if (routeData == null)
routeData = new RouteData();
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
}
MVC局部视图模型:
public class SimpleKendoModel
{
public SimpleKendoModel()
{
Results = new List<SimpleKendoModelData>();
}
public List<SimpleKendoModelData> Results { get; set;}
}
public class SimpleKendoModelData
{
public SimpleKendoModelData()
{
Data = 0;
}
public int Data { get; set; }
}
公共类SimpleKendoModel
{
公共SimpleKendoModel()
{
结果=新列表();
}
公共列表结果{get;set;}
}
公共类SimpleKendoModelData
{
公共SimpleKendoModelData()
{
数据=0;
}
公共int数据{get;set;}
}
感谢这篇帖子:
[ArgumentNullException: Value cannot be null.
Parameter name: controllerContext]
System.Web.Mvc.ChildActionValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +137
System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +80
System.Web.Mvc.ControllerBase.get_ValueProvider() +39
Kendo.Mvc.UI.Grid`1.ProcessDataSource() +254
Kendo.Mvc.UI.Grid`1.WriteHtml(HtmlTextWriter writer) +818
Kendo.Mvc.UI.WidgetBase.ToHtmlString() +102
Kendo.Mvc.UI.Fluent.WidgetBuilderBase`2.ToHtmlString() +15
System.Web.WebPages.WebPageBase.Write(Object value) +103
ASP._Page_Views_Reporting_ReportElement_SimpleKendoGrid_cshtml.Execute() in c:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Views\Reporting\ReportElement_SimpleKendoGrid.cshtml:8
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +253
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +148
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +122
xxx.Api.Ui.Helpers.ViewRenderer.RenderViewToStringInternal(String viewPath, Object model, Boolean partial) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:218
xxx.Api.Ui.Helpers.ViewRenderer.RenderPartialView(String viewPath, Object model) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:81
xxx.Api.Ui.Helpers.ViewRenderer.RenderPartialView(String viewPath, Object model, ControllerContext controllerContext) in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Helpers\ViewRenderer.cs:149
xxx.Api.Ui.Controllers.ReportingController.Test() in C:\Users\xxx\Documents\Visual Studio 2015\Projects\xxx\Controllers\ReportingController.cs:86
lambda_method(Closure , ControllerBase , Object[] ) +87
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +229
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +67
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +72
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +38
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +186
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +157
我实际上已经解决了这个问题
使用下面的类,我能够使用MVC Razor局部视图(包含剑道网格)成功地创建一个模板HTML,用于电子邮件模板。。允许我从静态方法调用它
我创建了一个名为ControllerExtensions的类
public static class ControllerExtensions
{
public static ControllerContext GetFakeControllerContext()
{
HttpContext.Current = HttpContext.Current ?? GetFakeHttpContext();
var currentContext = HttpContext.Current;
var controller = CreateController<FakeController>();
var st = new StringWriter();
var context = new HttpContextWrapper(currentContext);
var routeData = GetFakeRouteData(controller);
var controllerContext = new ControllerContext(new RequestContext(context, routeData), controller);
return controllerContext;
}
public static HttpContext GetFakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc, false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
public static RouteData GetFakeRouteData(Controller controller)
{
var routeData = new RouteData();
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
return routeData;
}
public static T CreateController<T>(RouteData routeData = null)
where T : Controller, new()
{
T controller = new T();
// Create an MVC Controller Context
var wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
if (routeData == null)
routeData = new RouteData();
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
}
public class FakeController : Controller
{
}
公共静态类控制器扩展
{
公共静态控制器上下文GetFakeControllerContext()
{
HttpContext.Current=HttpContext.Current??GetFakeHttpContext();
var currentContext=HttpContext.Current;
var controller=CreateController();
var st=新的StringWriter();
var context=新的HttpContextWrapper(currentContext);
var routeData=GetFakeRouteData(控制器);
var controllerContext=newcontrollercontext(newrequestcontext(context,routeData),controller);
返回控制器上下文;
}
公共静态HttpContext GetFakeHttpContext()
{
var httpRequest=新的httpRequest(“,”http://stackoverflow/", "");
var stringWriter=新的stringWriter();
var httpResponse=新的httpResponse(stringWriter);
var httpContext=新的httpContext(httpRequest,httpResponse);
var sessionContainer=new HttpSessionStateContainer(“id”,new SessionStateItemCollection(),
新的HttpStaticObjectsCollection(),10,true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc,false);
httpContext.Items[“AspSession”]=typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
空,调用约定。标准,
新[]{typeof(HttpSessionStateContainer)},
空)
.Invoke(新对象[]{sessionContainer});
返回httpContext;
}
公共静态路由数据GetFakeRouteData(控制器)
{
var routeData=新routeData();
如果(!routeData.Values.ContainsKey(“控制器”)和&!routeData.Values.ContainsKey(“控制器”))
routeData.Values.Add(“controller”,controller.GetType().Name
.ToLower()
.更换(“控制器”);
返回路由数据;
}
公共静态T CreateController(RouteData RouteData=null)
其中T:Controller,new()
{
T控制器=新的T();
//创建MVC控制器上下文
var wrapper=newhttpcontextwrapper(System.Web.HttpContext.Current);
if(routeData==null)
RoutedData=新RoutedData();
如果(!routeData.Values.ContainsKey(“控制器”)和&!routeData.Values.ContainsKey(“控制器”))
routeData.Values.Add(“controller”,controller.GetType().Name
.ToLower()
.更换(“控制器”);
controller.ControllerContext=新的ControllerContext(包装器、路由数据、控制器);
返回控制器;
}
}
公共类伪造控制器:控制器
{
}
并按以下方式使用:
public static string GetHtml()
{
var model = new SimpleKendoModel();
for (int x = 0; x < 10; x++)
{
var result = new SimpleKendoModelData();
result.Data = x;
model.Results.Add(result);
}
var currentContext = ControllerExtensions.GetFakeControllerContext();
var html = ViewRenderer.RenderPartialView("~/Views/Reporting/ReportElement_SimpleKendoGrid.cshtml", model, currentContext);
return html;
}
公共静态字符串GetHtml()
{
var模型=新的SimpleKendoModel();
对于(int x=0;x<10;x++)
{
var result=新的SimpleKendoModelData();
结果:数据=x;
model.Results.Add(结果);
}
var currentContext=ControllerExtensions.GetFakeControllerContext();
var html=ViewRenderer.RenderPartialView(“~/Views/Reporting/ReportElement\u SimpleKendoGrid.cshtml”,model,currentContext);
返回html;
}
问题可能来自行公共视图渲染器(ControllerContext ControllerContext=null)
@HizkiSunjaya在哪里将模型传递到actionMethod中的视图?@T–nNguỹn我添加了堆栈跟踪信息,以便您更好地了解我遇到的问题having@Kumar_Vikas我在这行代码中传递模型--//这段注释掉的代码有效//var html=ViewRenderer.RenderPartialView(“~/Views/Reporting/ReportElement\u SimpleKendoGrid.cshtml”,模型,ControllerContext);var html=ViewRenderer.RenderPartialView(“~/Views/Reporting/ReportElement\u SimpleKendoGrid.cshtml”,模型,currentContext)正如你在评论中看到的,我只需要想一想是否有办法重新创建正确的currentContext,如果我要为它创建一个假的控制器
public class SimpleKendoModel
{
public SimpleKendoModel()
{
Results = new List<SimpleKendoModelData>();
}
public List<SimpleKendoModelData> Results { get; set;}
}
public class SimpleKendoModelData
{
public SimpleKendoModelData()
{
Data = 0;
}
public int Data { get; set; }
}
public static class ControllerExtensions
{
public static ControllerContext GetFakeControllerContext()
{
HttpContext.Current = HttpContext.Current ?? GetFakeHttpContext();
var currentContext = HttpContext.Current;
var controller = CreateController<FakeController>();
var st = new StringWriter();
var context = new HttpContextWrapper(currentContext);
var routeData = GetFakeRouteData(controller);
var controllerContext = new ControllerContext(new RequestContext(context, routeData), controller);
return controllerContext;
}
public static HttpContext GetFakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc, false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
public static RouteData GetFakeRouteData(Controller controller)
{
var routeData = new RouteData();
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
return routeData;
}
public static T CreateController<T>(RouteData routeData = null)
where T : Controller, new()
{
T controller = new T();
// Create an MVC Controller Context
var wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
if (routeData == null)
routeData = new RouteData();
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
}
public class FakeController : Controller
{
}
public static string GetHtml()
{
var model = new SimpleKendoModel();
for (int x = 0; x < 10; x++)
{
var result = new SimpleKendoModelData();
result.Data = x;
model.Results.Add(result);
}
var currentContext = ControllerExtensions.GetFakeControllerContext();
var html = ViewRenderer.RenderPartialView("~/Views/Reporting/ReportElement_SimpleKendoGrid.cshtml", model, currentContext);
return html;
}