0

Первый, некоторые контекст:Как определить, используется View при вызове View (модель объекта)

  • Язык - 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 
) 

Оригинала Автор использует View для создания PDF-файла с библиотекой третьей стороны. Мне нужно изменить представление, чтобы включить дополнительную информацию.

Проблема: У меня возникли проблемы с поиском вида, который можно изменить. Их сотни, и (ИМХО) их плохо называют и организовывают. Основной процесс создания PDF-файла выглядит следующим образом. Я путаюсь между шагами 3 и 4.

    ID
  1. хозяйствующего субъекта передаются на ActionResult
  2. Лица, извлеченная из резервного хранилища
  3. модели передается метода Controller.View упомянутый выше:
    var viewModel = View (model);
    var xmlText = RenderActionResultToString (viewModel);
  4. Получившийся ViewResult используется с экземпляром ControllerContext для генерации HTML, как если бы он запрашивался браузером.
  5. Полученный HTML-код передается стороннему инструменту и преобразуется в PDF-файл.

Я понимаю все остальное очень четко. Я не понимаю, как вызов View (model) определяет, какой файл View следует использовать при возврате ViewResult. Любая помощь очень ценится!

Включая код, указанный ниже, на случай, если кто-нибудь определит ответ.

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

varAR будет ActionResult или, более конкретно, BinaryContentResult. Я не знаю свойства на любом типе, который я бы опросил, чтобы определить, какой файл View был использован. Я что-то упускаю? –

ответ

1

Я не точно уверен, что вы спрашиваете, но при вызове View(model) выбранное представление основано на соглашениях.

Вот пример:

public class HerbController : Controller { 
    public ActionResult Cilantro(SomeType model) { 
     return View(model) 
    } 
} 

Это будет выглядеть для просмотра файла называется Cilantro.cshtml в папке Herb (Views/Herb/Cilantro.cshtml). Структура также будет выглядеть в каталоге Shared, а также в том случае, если это представление, предназначенное для совместного использования нескольких результатов.

Однако вы также можете посмотреть файл Global.asax, чтобы узнать, установлены ли какие-либо настраиваемые пути просмотра для механизма просмотра. Пример, приведенный выше, основан на соглашениях по умолчанию ASP.NET MVC. Вы можете переопределить их для удовлетворения ваших потребностей, если это необходимо.

+0

Именно то, что я прошу, - это найти файл вида, если соглашения не соблюдаются. Я закончил поиск полного имени модели, которое является «CRM.Data.Proposal». Я получил результат поиска в файле .aspx, и это оказалось так. Тем не менее, тщательное проскальзывание через десятки пользовательских маршрутов в файле Global.asax было бы следующим подходом, если бы это не сработало. Спасибо! –

1

Логика чтобы определить, какой вид шаблона будет использоваться находится в ViewResult, который возвращается из вызова

var viewModel = View(model); 

и как вид выбран определяется сконфигурированного ViewEngine (ов), но она будет использовать текущие Area, Controller и Action значения маршрута, чтобы определить, какой вид должен обслуживаться.

Каковы значения маршрута для действия ProposalPDF, будет зависеть от того, как настроена ваша маршрутизация, но при условии, что значения по умолчанию будут иметь значение ProposalPDF, значение маршрута контроллера будет именем класса контроллера, в котором этот (минус суффикс контроллера), и область будет областью, в которой находится контроллер, со значением пустой строки, если в папке контроллера по умолчанию. Затем, используя эти значения маршрута, вид будет искаться в папке Views с помощью следующей конвенции

~/Views/{Area}/{Controller}/{View}.cshtml 

Существует всегда Glimpse, который может помочь с обеспечением во время выполнения диагностики тоже, например, какой вид файла был использован для обслуживать возвращенную страницу, хотя я не уверен, как это будет выглядеть, когда ViewResult выполняется внутри, чтобы предоставить содержимое файла.

+0

Хорошая справочная информация, спасибо. –

+0

Нет проблем, рада помочь. Glimpse также может помочь вам в таких ситуациях –

1

Соглашение о представлении заключается в том, что они находятся в папке с именем контроллера (без «контроллера»), а файл .cshtml внутри этой папки имеет имя после вызывающего действия. В вашем случае это должно быть:

~/Views/[Controller]/ProposalPdf.cshtml 
+0

Спасибо. Я должен был упомянуть, что знаю об условностях. Они не соблюдались. Спасибо, в любом случае. Существует TON пользовательской маршрутизации. В следующий раз я постараюсь обеспечить лучший контекст в моем вопросе. Я знаю, как раздражает, давая совершенно отличный ответ. –

Смежные вопросы