如何确定调用视图(对象模型)时使用哪个视图
本文关键字:视图 对象模型 何确定 调用 | 更新日期: 2023-09-27 18:36:51
首先,一些上下文:
- 语言 - C#
- 平台 - .Net Framework 4.5
- 项目类型 - ASP.Net MVC 4
我正在尝试确定 MVC 项目中的哪个视图正在处理对以下方法的显式调用。 该方法的 MSDN 文档如下所示:http://msdn.microsoft.com/EN-US/library/dd492930.aspx
protected internal ViewResult View(
Object model
)
原始作者正在使用视图生成包含第三方库的 PDF 文件。 我需要修改视图以包含其他信息。
问题:我无法找到要修改的视图。 有数百个,而且(恕我直言)它们的名称和组织都很差。 生成 PDF 的基本过程如下所示。 我在步骤 3 和 4 之间感到困惑。
- 实体的 ID 将传递到操作结果
- 从后备存储中检索实体
- 模型被传递给上面提到的 Controller.View 方法:
var viewModel = View(model);
var xmlText = RenderActionResultToString(viewModel); - 生成的 ViewResult 与 ControllerContext 的实例一起使用,以生成 HTML,就像浏览器请求一样。
- 生成的 HTML 将传递到第三方工具并转换为 PDF。
我非常清楚地了解其他一切。 我不明白的是,对 View(model) 的调用如何确定返回 ViewResult 时使用哪个 View 文件。 任何帮助非常感谢!
我包含下面的代码,以防它帮助任何人确定答案。
操作结果:
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();
}
我不完全确定你在问什么,但是,当你调用View(model)
时,选择的视图是基于约定的。
下面是一个示例:
public class HerbController : Controller {
public ActionResult Cilantro(SomeType model) {
return View(model)
}
}
这将在名为Herb
(Views/Herb/Cilantro.cshtml)的文件夹中查找名为Cilantro.cshtml
的视图文件。 框架还将查看Shared
目录,以防它是要在多个结果之间共享的视图。
但是,您可能还需要查看Global.asax
文件,以查看是否为视图引擎设置了任何自定义视图路径。 我上面给出的示例基于 ASP.NET MVC 的默认约定。 如果需要,您可以覆盖它们以更好地满足您的需求。
视图的约定是它们位于以控制器命名的文件夹中(不带"控制器"),并且该文件夹中的 .cshtml 文件以调用操作命名。在您的情况下,这应该是:
~/Views/[Controller]/ProposalPdf.cshtml
确定将使用哪个视图模板的逻辑位于从调用返回的ViewResult
中
var viewModel = View(model);
视图的选择方式由配置的 ViewEngine 决定,但它将使用当前Area
、Controller
和Action
路由值来确定应提供哪个视图。
ProposalPDF
操作的路由值将取决于路由的配置方式,但假设默认值,操作路由值将为ProposalPDF
,控制器路由值将是此操作所在的控制器类的名称(减去控制器后缀),区域将是控制器所在的区域文件夹, 如果位于默认控制器文件夹中,则值为空字符串。然后使用这些路由值,将使用以下约定在 Views 文件夹中查找视图
~/Views/{Area}/{Controller}/{View}.cshtml
总有一些 Glimpse 可以帮助提供运行时诊断,例如使用哪个 View 文件来提供返回的页面,尽管我不确定当内部执行 ViewResult 以提供文件内容时会是什么样子。