1

我正在使用 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 .. 被设置为无元素......这怎么可能?

4

2 回答 2

5

为时已晚,但按照 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 });            
}
于 2015-06-04T13:44:15.130 回答
3

这太晚了,但我没有看到很多关于这个特定问题的答案,而且我已经为此苦苦挣扎了很长时间。

Rotativa 的 ActionToPdf 不能将非原始类型移植到视图。更迂腐的是,复杂对象无法转换为接收控制器能够理解的 GET 查询字符串。不幸的是,这意味着所有可枚举的容器类都已退出。

总而言之,发生这种行为是因为 Rotativa 依赖UrlHelper类的 Action() 方法来移植路由值并允许 wkhtmltopdf 生成视图。当您调用 new ActionToPdf() 时,Action() 会反映输入路由对象并迭代其属性,从而创建一个查询字符串,该字符串由具有模型属性名称及其关联值的键值对组成。该值是使用 ToString() 方法派生的。

在更复杂的数据类型的情况下,对值执行此操作将产生类名。Rotativa 将使用这些数据创建一个查询字符串并将其传递给构建它的 wkhtmltopdf 驱动程序,该驱动程序随后将使用许多查询变量访问您想要的页面。如果您在 Rotativa 代码执行时单步执行它,您将看到正在构建的 URL,并且在它正在构建的字符串的文本可视化器中,无疑会看到如下内容:

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

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

我根本不知道有什么好的解决方法。迄今为止,我一致采用了特定于应用程序的路线,这需要一些……牺牲代码质量……我一直不愿意承诺,但当时没有看到其他方式。

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

于 2014-04-24T21:08:48.257 回答