首先,某些背景信息:
我正在尝试确定MVC项目中的哪个View正在处理对以下方法的显式调用。该方法的MSDN文档位于:http://msdn.microsoft.com/EN-US/library/dd492930.aspx
protected internal ViewResult View(
Object model
)
原作者使用View生成带有第三方库的PDF文件。我需要修改视图以包含其他信息。
问题:我无法找到要修改的视图。它们有数百种,而且(恕我直言)它们的命名和组织都很差。生成PDF的基本过程如下所示。我在第3步和第4步之间感到困惑。
我非常清楚地理解其他一切。我不明白的是,对视图(模型)的调用如何确定返回ViewResult时要使用的View文件。任何帮助非常感谢!
我包含以下代码,以防任何人确定答案。
ActionResult:
public ActionResult ProposalPDF(String id, String location, bool hidePrices = false)
{
var proposal = _adc.Proposal.GetByKey(int.Parse(id));
var opportunity = _adc.Opportunity.GetByKey(proposal.FkOpportunityId.Value);
ViewData["AccountId"] = opportunity.FkAccountId;
ViewData["AccountType"] = opportunity.FkAccount.FkAccountTypeId;
ViewData["Location"] = location;
ViewData["HidePrices"] = hidePrices;
return ViewPdf(proposal);
}
ViewPDF方法:
protected ActionResult ViewPdf(object model)
{
// Create the iTextSharp document.
var document = new Document(PageSize.LETTER);
// Set the document to write to memory.
var memoryStream = new MemoryStream();
var pdfWriter = PdfWriter.GetInstance(document, memoryStream);
pdfWriter.CloseStream = false;
document.Open();
// Render the view xml to a string, then parse that string into an XML dom.
var viewModel = View(model);
var xmlText = RenderActionResultToString(viewModel);
var htmlPipelineContext = new HtmlPipelineContext();
htmlPipelineContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
//CSS stuff
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
var cssResolverPipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlPipelineContext, new PdfWriterPipeline(document, pdfWriter)));
var xmlWorker = new XMLWorker(cssResolverPipeline, true);
var xmlParser = new XMLParser(xmlWorker);
xmlParser.Parse(new StringReader(xmlText));
// Close and get the resulted binary data.
document.Close();
var buffer = new byte[memoryStream.Position];
memoryStream.Position = 0;
memoryStream.Read(buffer, 0, buffer.Length);
// Send the binary data to the browser.
return new BinaryContentResult(buffer, "application/pdf");
}
RenderActionResultToString辅助方法:
protected string RenderActionResultToString(ActionResult result)
{
// Create memory writer.
var sb = new StringBuilder();
var memWriter = new StringWriter(sb);
// Create fake http context to render the view.
var fakeResponse = new HttpResponse(memWriter);
var fakeContext = new HttpContext(System.Web.HttpContext.Current.Request, fakeResponse);
var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), this.ControllerContext.RouteData, this.ControllerContext.Controller);
var oldContext = System.Web.HttpContext.Current;
System.Web.HttpContext.Current = fakeContext;
// Render the view.
result.ExecuteResult(fakeControllerContext);
// Restore data.
System.Web.HttpContext.Current = oldContext;
// Flush memory and return output.
memWriter.Flush();
return sb.ToString();
}
答案 0 :(得分:1)
确定将使用哪个视图模板的逻辑位于从调用返回的ViewResult
var viewModel = View(model);
如何选择视图取决于配置的ViewEngine,但它将使用当前的Area
,Controller
和Action
路由值来确定应该是哪个视图提供服务。
ProposalPDF
操作的路由值取决于路由的配置方式,但假设默认值,操作路由值为ProposalPDF
,控制器路由值将为名称此操作所在的控制器类(减去控制器后缀),该区域将是控制器所在的区域文件夹,如果在默认控制器文件夹中,则为空字符串值。然后使用这些路径值,将使用以下约定在Views文件夹中查找视图
~/Views/{Area}/{Controller}/{View}.cshtml
总有 Glimpse 可以帮助提供运行时诊断,例如哪个View文件用于提供返回的页面,虽然我不知道这会怎样查看在内部执行ViewResult以提供文件内容的时间。
答案 1 :(得分:1)
我不是确切地确定你在问什么,但是,当你致电View(model)
时,所选择的视图是基于惯例的。
以下是一个例子:
public class HerbController : Controller {
public ActionResult Cilantro(SomeType model) {
return View(model)
}
}
这将在名为Cilantro.cshtml
的文件夹(Views / Herb / Cilantro.cshtml)中查找名为Herb
的视图文件。该框架还将查看Shared
目录,以防它是一个旨在跨多个结果共享的视图。
但是,您可能还需要查看Global.asax
文件,以查看是否为视图引擎设置了任何自定义视图路径。我上面给出的示例基于ASP.NET MVC的默认约定。如果需要,您可以覆盖它们以更好地满足您的需求。
答案 2 :(得分:1)
视图的约定是它们位于以控制器命名的文件夹中(没有“Controller”),并且该文件夹中的.cshtml文件以调用操作命名。在你的情况下,那应该是:
~/Views/[Controller]/ProposalPdf.cshtml