2013-04-02 2 views
2

Мне нужно уметь возвращать частичный вид как string в моем приложении MVC через signalR. Я использую хабы.signalR отправить часть результата результата с помощью концентратора

Я использую следующий метод, чтобы вернуть часть строки вида (из 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. Почему это?.

  • Какой лучший подход здесь?
  • Есть ли способ сделать частичный просмотр без HttpContext?
+0

Вы не вернете вид из центра, если вам нужно то, что вы делаете что-то неправильно. – davidfowl

+0

Я не возвращаю просмотров. Я возвращаю строку. (просмотр строки) – ShaneKm

+0

И вы пытаетесь позвонить в трубу mvc из SingalR? – davidfowl

ответ

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 
} 
Смежные вопросы