如何将复杂模型传递给Rotativa?

时间:2013-12-19 01:02:46

标签: asp.net-mvc-4 rotativa

我正在使用MVC 4来创建应用程序。我正在使用Rotativa来创建一个pdf。我用一个复杂的模型调用ActionAsPdf

我的模特是

public class BrandingDetails
    {
        public int PDFFileNo { get; set; }
        public string LogoImageUrl { get; set; }
        public string WebsiteUrl { get; set; }
        public string PhoneNumber_AU { get; set; }
        public string PhoneNumber_NZ { get; set; }
        public string FacebookImageUrl { get; set; }
        public string TwitterImageUrl { get; set; }
        public string PinterestImageUrl { get; set; }
        public string YoutubeImageUrl { get; set; }
        public string CruiseCode { get; set; }
        public string ShipName { get; set; }
        public string PortName { get; set; }
        public string SailDate { get; set; }
        public string CruiseNights { get; set; }
        public string Destinations { get; set; }
        public string QuoteRef { get; set; }
        public string CruiseName { get; set; }
        public string DescriptionCruise { get; set; }

        public IEnumerable<CruiseOptions> CruiseOptions { get; set; }

    }

我打电话给以下

var viewModel = QuoteHelper.GetViewModel(item);

 var pdfResult = new ActionAsPdf("CruiseDetails", quoteDetails, cruiseOptions);


var binary = pdfResult.BuildPdf(this.ControllerContext);

我正在调用的Action方法是

 public ActionResult CruiseDetails(BrandingDetails quoteDetails, IEnumerable<CruiseOptions> cruiseOptions)
        {

            return View("CruiseDetails", quoteDetails);

        }

但由于某种原因,当我将其传递给Action时,所有数据都传递给CruiseOptions ..这被设置为无元素......这怎么可能?

2 个答案:

答案 0 :(得分:4)

太晚了,但是根据Josh的回答,我找到了一个使用JSON的解决方案。我希望这有助于某人。

public class SalesReportModel : BaseModel
{
    public List<Guid> UserGuids { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }       
}

public ActionResult GenerateSalesReport(string json)
{
    SalesReportModel model = new JavaScriptSerializer().Deserialize<SalesReportModel>(json);
    return View("SalesReport", model);
}

public ActionResult SalesReport(SalesReportModel model)
{
    var json = new JavaScriptSerializer().Serialize(model);
    return new Rotativa.ActionAsPdf("GenerateSalesReport", new { json = json });            
}

答案 1 :(得分:3)

这样做太迟了,但是我没有看到这个特定问题的很多答案,而且我已经很长时间都在努力了。

Rotativa的ActionToPdf无法将非基本类型移植到视图中。更迂腐的是,复杂对象无法转换为接收控制器将理解的GET查询字符串。遗憾的是,这意味着所有可枚举的容器类都已用完。

这种情况的长期和短期是因为Rotativa依赖UrlHelper类的Action()方法来移植路由值并允许wkhtmltopdf生成视图。当您调用新的ActionToPdf()时,Action()会反映输入路由对象并迭代其属性,从而创建一个查询字符串,其中包含键值对以及模型的属性名称及其关联值。该值使用ToString()方法派生。

对于更复杂的数据类型,对该值执行此操作将产生类名。 Rotativa将使用此数据创建一个查询字符串,并将其传递给构建它的wkhtmltopdf驱动程序,然后使用许多查询变量将其传递到您的目标页面。如果您在执行时单步执行Rotativa代码,您将看到正在构建此URL,并且在其构建的字符串的Text Visualizer中,无疑会出现如下情况:

http://localhost/Home/About?yourModelsList=System.Collections.Generics.List&someOtherParameter=...

当接收控制器方法获取此数据时,当它尝试将所有这些查询变量绑定到您的模型时,它将从查询字符串中丢弃可枚举字段的值,从而导致您在列表中没有任何内容。

我根本不知道一个很好的解决方法。到目前为止,我已经一致地推出了特定于应用程序的路线,这需要一些代码质量的牺牲...我一直不愿意承诺,但当时没有看到另一种方式。

我设想将视图数据存储在Session变量中并通过wkhtmltopdf调用它来通过控制器检索它,但这需要一些相当令人讨厌的做法(在线上共享会话ID并不好)安全实践)。您还可以娱乐序列化对象,将其存储在数据库后端,并在PDF渲染控制器执行时以某种方式检索它。对于如Rotativa API提供的那么简单的方法来说,这看起来很多......但是如果你有足够的绝望......