2013-12-19 19 views
0

我正在使用MVC 4来创建应用程序。我正在使用Rotativa创建PDF。我打电话ActionAsPdf一个复杂的模型如何将完整模型传递给Rotativa?

我的模型是

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); 

我的行动方法是调用是

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

      return View("CruiseDetails", quoteDetails); 

     } 

但某些原因,当我将它传递给Action时,所有数据都会通过Bar CruiseOptions ..它被设置为no el ements ...这怎么可能?

+0

我不知道是什么原因引起的,但如果你只是显示结果,没有尝试任何幻想,为什么不直接添加包含您所选择的巡航选项的说明一个字符串变量和传递。最糟糕的情况是,你可以通过'自动'反射来获得它,而不需要人为干预。 –

回答

3

这是方式,方法为时已晚,但我没有看到很多答案这个特定的问题在那里,我与它挣扎了很长的时间。

Rotativa的ActionToPdf无法将非基元类型移植到视图中。更迂回地说,复杂的对象没有办法翻译成接收控制器将理解的GET查询字符串。不幸的是,这意味着所有的枚举容器类都没有了。

这是因为Rotativa依赖UrlHelper类的Action()方法来端口路由值并允许wkhtmltopdf生成视图,所以出现此行为。当您调用新的ActionToPdf()时,Action()会反映输入路由对象并迭代其属性,从而创建一个由键值对组成的查询字符串以及您的模型的属性名称及其相关值。该值使用ToString()方法派生。

在更复杂的数据类型的情况下,这样做的值将产生类名称。 Rotativa将使用这些数据创建一个查询字符串并将其传递给构建它的wkhtmltopdf驱动程序,该驱动程序随后将使用大量查询变量将其传达到您的预期页面。如果通过,因为它执行Rotativa执行代码,你会看到这个URL创建的,并在文本展示台的字符串它的建设,无疑将ESPY是这样的:

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

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

我不知道这个很好的解决方法。迄今为止,我已经一致地申请了特定于应用程序的路线,这需要一些...代码质量的牺牲......我一直不喜欢承诺,但当时没有看到另一种方式。

我设想将视图数据存储在一个Session变量中,并通过控制器检索它,就像wkhtmltopdf调用它一样,但这需要一些相当不愉快的做法(在线上共享会话ID并不是很好的安全实践所有)。您也可以序列化对象,将其存储在数据库后端,并在PDF渲染控制器执行时以某种方式检索它。这似乎是一个大量的工作,为的Rotativa API礼物这么简单的方法...但如果你有足够的绝望......

4

太晚了,但下面乔希的答案,我已经使用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 });    
} 
+0

非常感谢你的回答,像一个魅力,我希望我可以给+1以上:) – Blossom