C# t4mvc actionresult已转换为字符串

C# t4mvc actionresult已转换为字符串,c#,asp.net,asp.net-mvc,asp.net-mvc-3,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 3,我试图从T4MVC ActionResult中获取执行调用的结果,并从EmailService类中的静态函数中获取整个字符串。任何帮助都将不胜感激 像这样的 static string ExecuteAction(ActionResult result) { /* Code goes here */ } public static class EmailService { public static bool SendWelcomeEmail(string nam

我试图从T4MVC ActionResult中获取执行调用的结果,并从EmailService类中的静态函数中获取整个字符串。任何帮助都将不胜感激

像这样的

static string ExecuteAction(ActionResult result)
{
     /* Code goes here */
}
public static class EmailService 
{    
     public static bool SendWelcomeEmail(string name, string email)
     {    
          var message = ExecuteAction(MVC.Emails.WelcomeEmail(name, email));    
          /* Other code */    
     }    
}
string body = RenderPartialViewToString("PasswordChangedEmail");
这样我就可以像这样调用函数了

static string ExecuteAction(ActionResult result)
{
     /* Code goes here */
}
public static class EmailService 
{    
     public static bool SendWelcomeEmail(string name, string email)
     {    
          var message = ExecuteAction(MVC.Emails.WelcomeEmail(name, email));    
          /* Other code */    
     }    
}
string body = RenderPartialViewToString("PasswordChangedEmail");

我做了这件事

 protected virtual string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.RouteData.GetRequiredString("action");

        ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
您将这样实现它

static string ExecuteAction(ActionResult result)
{
     /* Code goes here */
}
public static class EmailService 
{    
     public static bool SendWelcomeEmail(string name, string email)
     {    
          var message = ExecuteAction(MVC.Emails.WelcomeEmail(name, email));    
          /* Other code */    
     }    
}
string body = RenderPartialViewToString("PasswordChangedEmail");

局部视图只是局部视图,但是,没有任何理由不能使用完整视图。希望能有帮助。

我做了这件事

 protected virtual string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.RouteData.GetRequiredString("action");

        ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
您将这样实现它

static string ExecuteAction(ActionResult result)
{
     /* Code goes here */
}
public static class EmailService 
{    
     public static bool SendWelcomeEmail(string name, string email)
     {    
          var message = ExecuteAction(MVC.Emails.WelcomeEmail(name, email));    
          /* Other code */    
     }    
}
string body = RenderPartialViewToString("PasswordChangedEmail");

局部视图只是局部视图,但是,没有任何理由不能使用完整视图。希望有帮助。

您将无法使用T4MVC ActionResults来执行此操作,因为它们有一个空的
ExecuteSult()
实现

我可以看到两种明显的方法来处理这个问题:

1.创建要调用的操作方法所在的控制器实例,然后调用它。您可能决定从ControllerFactory获取一个实例,而不是直接实例化该类,尽管如果您知道它是什么类型,我会直接从该类型实例化一个实例

要从默认控制器工厂获取控制器,可以使用

 ControllerBuilder.Current.GetControllerFactory().CreateController(RequestContext requestContext, string controllerName);
这将返回一个
IController
,因此您需要将其转换为正确的控制器类型,以便调用操作方法。直接实例化一个更容易:)


2.使用电子邮件模板解决方案,如或卡齐的。所有这些都利用了Razor,这样您就可以很好地创建电子邮件模板。

您将无法使用T4MVC ActionResults来实现这一点,因为它们有一个空的
ExecuteSult()
实现

我可以看到两种明显的方法来处理这个问题:

1.创建要调用的操作方法所在的控制器实例,然后调用它。您可能决定从ControllerFactory获取一个实例,而不是直接实例化该类,尽管如果您知道它是什么类型,我会直接从该类型实例化一个实例

要从默认控制器工厂获取控制器,可以使用

 ControllerBuilder.Current.GetControllerFactory().CreateController(RequestContext requestContext, string controllerName);
这将返回一个
IController
,因此您需要将其转换为正确的控制器类型,以便调用操作方法。直接实例化一个更容易:)


2.使用电子邮件模板解决方案,如或卡齐的。所有这些都可以利用Razor,这样您就可以拥有良好的模板电子邮件信息。

如果有人对答案感兴趣:

private static RequestContext RequestContext(this HttpContext context)
{
    var httpContextBase = new HttpContextWrapper(context);
    var routeData = new RouteData();
    return new RequestContext(httpContextBase, routeData);
}

private static RouteData GetRoute(this ActionResult url)
{
    var data = url.GetRouteValueDictionary();
    var route = new RouteData();
    foreach (var item in data)
        route.Values[item.Key] = item.Value;
    return route;
}

public static string ExecuteAsString(this T4MVC_ActionResult result)
{
    var controllerName = result.Controller;
    var context = HttpContext.Current.RequestContext();
    context.RouteData = result.GetRoute();
    var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(context, controllerName);
    controller.ControllerContext = new ControllerContext(context, controller);
    var htmlHelper = new HtmlHelper(new ViewContext(
                              controller.ControllerContext,
                              new WebFormView(controller.ControllerContext, "HACK"),
                              new ViewDataDictionary(),
                              new TempDataDictionary(),
                              new StringWriter()),
                        new ViewPage());
    return htmlHelper.Action(result).ToString();
}

如果有人对答案感兴趣:

private static RequestContext RequestContext(this HttpContext context)
{
    var httpContextBase = new HttpContextWrapper(context);
    var routeData = new RouteData();
    return new RequestContext(httpContextBase, routeData);
}

private static RouteData GetRoute(this ActionResult url)
{
    var data = url.GetRouteValueDictionary();
    var route = new RouteData();
    foreach (var item in data)
        route.Values[item.Key] = item.Value;
    return route;
}

public static string ExecuteAsString(this T4MVC_ActionResult result)
{
    var controllerName = result.Controller;
    var context = HttpContext.Current.RequestContext();
    context.RouteData = result.GetRoute();
    var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(context, controllerName);
    controller.ControllerContext = new ControllerContext(context, controller);
    var htmlHelper = new HtmlHelper(new ViewContext(
                              controller.ControllerContext,
                              new WebFormView(controller.ControllerContext, "HACK"),
                              new ViewDataDictionary(),
                              new TempDataDictionary(),
                              new StringWriter()),
                        new ViewPage());
    return htmlHelper.Action(result).ToString();
}

你想达到什么目标?应该返回什么字符串?从视图中设计和构建电子邮件模板您试图实现什么?应该返回什么字符串?从ViewsHanks设计和构建电子邮件模板用于此,但它不太有效,因为我没有控制器上下文为什么不?您试图在何处执行控制器操作?此方法比Kyle的答案更可靠。Kyle对WebFormView和其他一些东西有依赖性。与此方法非常相似的是,我可以在不做任何更改的情况下将rails风格的邮件从mvc2迁移到mvc3。谢谢你,但它不太有效,因为我没有控制器上下文。为什么不呢?您试图在何处执行控制器操作?此方法比Kyle的答案更可靠。Kyle对WebFormView和其他一些东西有依赖性。与此方法非常相似,我可以在不做任何更改的情况下将rails风格的邮件程序从mvc2迁移到mvc3。我真的很感激这个信息。如何从控制器工厂获得实例?@Kyle-我已经更新了答案,但我认为最好直接创建一个:)Russ,你说得很对。我真的很感激这个信息。如何从控制器工厂获取实例?@Kyle-我已经更新了答案,但我认为最好直接创建一个:)