我需要能够通过signalR在我的MVC应用中将部分视图作为字符串返回。我正在使用集线器。
我正在使用以下方法返回部分视图字符串(来自here):
public static string RenderPartialView(string controllerName, string partialView, object model)
{
var context = httpContextBase as HttpContextBase;
var routes = new 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();
}
}
为了使这个方法有效,我需要HttpContext.Current
因此在我的OnConnected(我注意到它总是存在)我设置它是这样的:
public class TaskActionStatus : Hub
{
private static HttpContextBase httpContextBase;
...
public override Task OnConnected()
{
httpContextBase = new HttpContextWrapper(HttpContext.Current) as HttpContextBase;
...
然后我在我的RenderPartialView方法中使用它:
var context = httpContextBase as HttpContextBase;
这样我总能访问当前的HttpContext。但是,我注意到有时我的HttpContext静态副本为null。这是为什么?。
答案 0 :(得分:1)
我使用假的http上下文来生成视图:
public static string GetRazorViewAsString(object model, string filePath)
{
HttpContext httpContext = MockHelper.FakeHttpContext();
var st = new StringWriter();
var context = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var controllerContext = new ControllerContext(new RequestContext(context, routeData), new FakeController());
var razor = new RazorView(controllerContext, filePath, null, false, null);
razor.Render(
new ViewContext(controllerContext, razor, new ViewDataDictionary(model), new TempDataDictionary(), st),
st);
return st.ToString();
}
#endregion
}
public class FakeController : Controller
{
}
public class MockHelper
{
#region Public Methods and Operators
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest(string.Empty, "http://novomatic/", string.Empty);
var stringWriter = new StringWriter();
var httpResponce = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponce);
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;
}
#endregion
}