2016-06-27 61 views
0

我正在爲ASP.NET MVC編寫一個自定義視圖引擎。我正在嘗試添加對兒童操作的支持。下面是應該執行子操作並將結果作爲字符串返回的處理程序。在此之前,一切工作都正常;該方法在應該被調用並且參數全部正確填充時被調用。ASP MVC - 手動執行子動作

private string HandleActionHelper(ViewContext viewContext, string actionName, string controllerName, RouteValueDictionary routeValues) 
    { 
     var routeData = new RouteData(); 

     if (string.IsNullOrEmpty(controllerName)) 
      controllerName = viewContext.RouteData.Values["controller"] as string; 

     routeData.Values["action"] = actionName; 
     routeData.Values["controller"] = controllerName; 
     foreach(var value in routeValues) 
     { 
      routeData.Values.Add(value.Key, value.Value); 
     } 

     var requestContext = new RequestContext(viewContext.HttpContext, routeData); 
     var mvcHandler = new MvcHandler(requestContext); 

     StringWriter writer = new StringWriter(); 
     viewContext.HttpContext.Server.Execute(mvcHandler, writer, true); 

     return writer.GetStringBuilder().ToString(); 
    } 

它輕視viewContext.HttpContext.Server.Execute(mvcHandler, writer, true);一個System.Web.HttpException

完整的錯誤消息如下:

錯誤執行的處理子請求 'System.Web.Mvc.MvcHandler'。

我一直在網上搜尋時,翻翻MVC來源怎麼看,這是我在它最刺不只是複製/粘貼了很多internal MVC類。

我該如何執行一個子操作並將結果作爲字符串返回?

編輯:添加完整的堆棧跟蹤

System.Web.dll中System.Web.HttpServerUtility.ExecuteInternal(System.Web.IHttpHandler 處理器,System.IO.TextWriter作家,布爾preserveForm, bool setPreviousPage,System.Web.VirtualPath path,System.Web.VirtualPath filePath,string physPath,System.Exception錯誤,字符串 queryStringOverride)Unknown System.Web.dll!System.Web.HttpServerUtility.Execute(System.Web .IHttpHandler handler,System.IO.TextWriter writer,b ool preserveForm,bool setPreviousPage)Unknown System.Web.dll!System.Web.HttpServerUtility.Execute(System.Web.IHttpHandler handler,System.IO.TextWriter writer,bool preserveForm)Unknown System.Web.dll!System .Web.HttpServerUtilityWrapper.Execute(System.Web.IHttpHandler handler,System.IO.TextWriter writer,bool preserveForm)未知 JadeViewEngine.dll!JadeViewEngine.JadeView.HandleActionHelper(System.Web.Mvc.ViewContext viewContext,string actionName,串controllerName, System.Web.Routing.RouteValueDictionary routeValues)線路85 C# JadeViewEngine.dll!JadeViewEngine.JadeView.Render.AnonymousMethod__0(動態 輸入)線路39 C#edge_nativeclr.node!ClrFunc.Call(值,有效載荷, 回調)未知 edge_nativeclr.node!.clrFuncProxy(Nan.FunctionCallbackInfo * 資訊)未知[原產於託管過渡] [託管到本機 過渡]
edge_nativeclr.node!.Nan.imp?A0x8dda69af.FunctionCallbackWrapper (v8.FunctionCallbackInfo * 資訊)未知[原產於託管過渡] [託管到本機 過渡]
edge_nativeclr.node!NodejsFuncInvokeContext.CallFuncOnV8Thread()未知 edge_nativeclr.node!.clrActionContext.ActionCallback(void *的 數據)未知[原生管理轉換] [管理原生 轉換]
edge_nativeclr.node!.continueOnV8Thread(uv_async_s *句柄, int狀態)未知[原生管理轉換] [管理原生 轉換] EdgeJs.dll!EdgeJs.Edge.Func。AnonymousMethod__1()未知 mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart_Context(對象 狀態)未知 mscorlib.dll中!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext 的ExecutionContext,System.Threading.ContextCallback回調,對象 狀態,布爾preserveSyncCtx)未知 mscorlib.dll中!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext 的ExecutionContext,System.Threading.ContextCallback回調,對象 狀態,布爾preserveSyncCtx)未知 mscorlib.dll中!系統.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback callback,object 狀態)未知 mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart()未知 [原產於託管過渡]

+0

什麼是完整的堆棧跟蹤?我不確定這是否是正確的方法 - 通過觸發相同響應流上的子請求,而不是通過寫入字符串,子動作通常起作用。 –

+0

@AntP堆棧跟蹤添加到問題。如果在Razor視圖中調用'HtmlHelper.RenderAction()',它會寫入流,但是如果調用HtmlHelper.Action(),它會返回一個'MvcString',然後可以調用'ToString()'。 – Entith

+0

自發布這個問題以來,我一直試圖通過創建一個'HtmlHelper'實例並使用它的Action()方法來實現這一點。這在我的測試中完全符合我的要求。問題是我使用Edge.js來執行一些NodeJS代碼,如果我在我的HandleActionHelper()方法中調用'HtmlHelper.Action()'方法(它本身由NodeJS代碼調用),那麼'Action )方法永遠不會返回,並且沒有錯誤或異常。我認爲解決這個問題將成爲這個問題的主題。我仍然想知道是否有更合適的方法來做我想做的事情。 – Entith

回答

0

所以我的解決方案,這是建立在你剃刀得到HtmlHelper類的一個實例意見,然後用其Action()方法來獲得結果字符串:

using System.Web.Mvc; // Bring in HtmlHelper 
using System.Web.Mvc.Html; // Bring in HtmlHelper's extension methods. 
... 
var html = new HtmlHelper(viewContext, new ViewPage()); 
string actionResults = html.Action("ActionName", "ControllerName"); 

注1:這是一個自定義IView實施自定義視圖引擎中,所以我只是在ViewContext instanc通過我已經有了。如果您沒有可用的ViewContext,則必須創建一個。這是一個古老的例子(所以不知道它有多好作品),但它應該幫助您開始:Create HtmlHelper instance in Controller

注2:正如我在原來的問題的意見中提到,我是有這種做法的麻煩。據我所知,HtmlHelper在異步上下文中不起作用。我使用Edge.js來調用NodeJS代碼,這是所有異步的東西,所以我認爲這是造成這些問題的原因。當我將呼叫移動到Edge.js之外的HtmlHelper時,它工作正常。