我的目标是允许用户以pdf格式打印视图。我找到了一个名为Rotativa的Nuget,并遵循了一些非常基础的教程。在测试中,它运行完美,看起来很不错,可以满足我的需求。
但是,我发现将其实施到实际的工作项目中会给我带来简单测试所没有的错误。
我有一个列表的索引视图。我希望用户将此列表打印为pdf。我尝试过许多不同种类的Rotativa(ViewAsPDF,ActionAsPDF,GeneratePDF ...)。我研究并阅读了许多教程。 。但是我认为问题与我的模型有关。 。
这是我到目前为止所拥有的
索引视图
@model IEnumerable<ICS20web.Models.IndexViewModel>
@{
ViewBag.Title = "Index";
}
<style>
#content {
}
.even {
background-color: #dcf1b8;
}
.odd {
background-color: #f4ffe1;
}
</style>
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<p>
<p>
@Html.ActionLink("Print", "PrintAllReport")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.ItemDescription)
</th>
<th>
@Html.DisplayNameFor(model => model.OriginalDate)
</th>
<th>
@Html.DisplayNameFor(model => model.TransType)
</th>
<th>
@Html.DisplayNameFor(model => model.LastUpdatedBy)
</th>
<th>
@Html.DisplayNameFor(model => model.ContactName)
</th>
<th>
@Html.DisplayNameFor(model => model.OpenClosed)
</th>
<th>
@Html.DisplayNameFor(model => model.CurrentStatus)
</th>
<th>
@Html.DisplayNameFor(model => model.CurrentStatusDate)
</th>
<th>
@Html.DisplayNameFor(model => model.RequsitionNumber)
</th>
<th>
@Html.DisplayNameFor(model => model.PONumber)
</th>
<th>
@Html.DisplayNameFor(model => model.DeliveryMonth)
</th>
<th>
@Html.DisplayNameFor(model => model.DeliveryYear)
</th>
<th>
@Html.DisplayNameFor(model => model.UnitsOrdered)
</th>
<th>
@Html.DisplayNameFor(model => model.Emergency)
</th>
<th>
@Html.DisplayNameFor(model => model.Comments)
</th>
<th>
@Html.DisplayNameFor(model => model.DeliveryUnit)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ItemDescription)
</td>
<td>
@Html.DisplayFor(modelItem => item.OriginalDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.TransType)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastUpdatedBy)
</td>
<td>
@Html.DisplayFor(modelItem => item.ContactName)
</td>
<td>
@Html.DisplayFor(modelItem => item.OpenClosed)
</td>
<td>
@Html.DisplayFor(modelItem => item.CurrentStatus)
</td>
<td>
@Html.DisplayFor(modelItem => item.CurrentStatusDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.RequsitionNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.PONumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.DeliveryMonth)
</td>
<td>
@Html.DisplayFor(modelItem => item.DeliveryYear)
</td>
<td>
@Html.DisplayFor(modelItem => item.UnitsOrdered)
</td>
<td>
@Html.DisplayFor(modelItem => item.Emergency)
</td>
<td>
@Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
@Html.DisplayFor(modelItem => item.DeliveryUnit)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.TransID })
</td>
</tr>
}
</table>
View会正确加载来自模型的正确数据到浏览器中。但是,当用户单击ActionLink PrintAllReport时。 。 。我看到以下错误:System.NullReferenceException:对象引用未设置为对象的实例。
参考第@foreach行(模型中的变量项)
我相信这是在告诉我该模型为空?但是,当它出现在浏览器中时,怎么可能呢?
这是我的索引控制器操作
public ActionResult Index()
{
var q = from tr in db.ICS_Transactions
join un in db.ICS_Units
on tr.DeliveryUnitID equals un.DeliveryUnitID
join kt in db.ICS_Contacts
on tr.Contact equals kt.LoginID
join sp in db.ICS_Supplies on tr.SuppliesID equals sp.Supplies_ID
orderby tr.Emergency descending, tr.TransID ascending
select new IndexViewModel
{
TransID = tr.TransID,
ItemDescription = sp.ItemDescription,
OriginalDate = tr.OriginalDate,
TransType = tr.TransType,
LastUpdatedBy = tr.LastUpdatedBy,
ContactName = kt.ContactName,
OpenClosed = tr.OpenClosed,
CurrentStatus = tr.CurrentStatus,
CurrentStatusDate = tr.CurrentStatusDate,
RequsitionNumber = tr.RequsitionNumber,
PONumber = tr.PONumber,
DeliveryMonth = tr.DeliveryMonth,
DeliveryYear = tr.DeliveryYear,
UnitsOrdered = tr.UnitsOrdered,
Emergency = tr.Emergency,
Comments = tr.Comments,
DeliveryUnit = un.DeliveryUnit,
PhoneNumber = un.PhoneNumber,
Street = un.Street,
City = un.City,
State = un.State,
ZipCode = un.ZipCode,
Building = un.Building,
Room = un.Room
}
;
return View(q.Where(d => d.OpenClosed == "Open").ToList());
}
这是我的PrintAllReport操作
public ActionResult PrintAllReport()
{
var model = new IndexViewModel();
//Code to get content
return new Rotativa.ViewAsPdf("Index") { FileName = "TestViewAsPdf.pdf" };
}
这将生成对象引用错误。我很困惑。这不应该与浏览器中加载的索引完全一样吗?我想念什么?
我也尝试过这种方式:
public ActionResult PrintAllReport()
{
var report = new ActionAsPdf("Index");
return report;
}
后者给了我一个身份验证错误:由于无效的身份验证标头,您无权查看此页面。
我是MVC5的新手,我对为什么正确加载索引页感到困惑,但是操作PrintAllReport无法在pdf中打开。而我需要进行更改以使其正常工作。
更新:
斯图尔德给我一些很好的信息后,我做了如下更改
{
var viewModel = new IndexViewModel();
var report = new ViewAsPdf("Index", viewModel);
return report;
}
现在,我遇到了另一个错误
传递到词典中的模型项的类型为'ICS20web.Models.IndexViewModel',但是此词典需要模型类型为'System.Collections.Generic.IEnumerable`1 [ICS20web.Models.IndexViewModel]'>
我感觉自己很亲近。 。 。但没有雪茄。