Название действия отображается на панели инструментов PDF в браузере. Настройка ContentDisposition не влияет на это - PullRequest
3 голосов
/ 05 марта 2020

Код контроллера:

[HttpGet]
public FileStreamResult GETPDF(string guid)
{
  var stream = XeroHelper.GetXeroPdf(guid).Result;
  stream.Position = 0;
  var cd = new ContentDisposition
  {
     FileName = $"{guid}.pdf",
     Inline = true
  };

  Response.AppendHeader("Content-Disposition", cd.ToString());
  return File(stream, "application/pdf");
}

Как видите, метод называется GETPDF. Вы также можете видеть, что я настраиваю имя файла в заголовке ContentDisposition. Если вы увидите ниже, вы увидите, что имя метода используется в качестве заголовка на панели инструментов, а не имя файла.

enter image description here

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

enter image description here

Если у кого-то есть идеи, как переименовать заголовок этой панели инструментов, это будет с благодарностью.

Кроме того, это НЕ дубликат: C# MVC: Chrome с использованием имени действия для установки встроенного заголовка PDF , поскольку ответ не был принят, и единственный метод с ответами был реализован в моем методе выше и все еще не работает.

Редактировать - Для пояснения я не хочу открывать PDF в новой вкладке. Я хочу отобразить это в программе просмотра на моей странице. Такое поведение уже происходит с кодом, который я предоставил, это просто название, которое неверно и происходит от моего имени метода контроллера. Используя код контроллера, я показываю его в виде:

<h1>Quote</h1>
<object data="@Url.Action("GETPDF", new { guid = @Model.QuoteGuid })" type="application/pdf" width="800" height="650"></object>

Ответы [ 2 ]

1 голос
/ 09 марта 2020

попробуйте что-то вроде этого:

    [HttpGet]
    public FileResult GETPDF(string guid)
    {
      var stream = XeroHelper.GetXeroPdf(guid).Result;

      using (MemoryStream ms = new MemoryStream())
      {
        stream.CopyTo(ms);

        // Download
        //return File(ms.ToArray(), "application/pdf", $"{guid}.pdf");

        // Open **(use window.open in JS)**
        return File(ms.ToArray(), "application/pdf")
      }           
   }

ОБНОВЛЕНИЕ: основано на упоминании о зрителе.

Чтобы встроить в страницу, вы можете попробовать тег <embed> или <object> тег

вот пример Рекомендуемый способ встраивания PDF в HTML?

ie:

<embed src="https://drive.google.com/viewerng/
viewer?embedded=true&url=[YOUR ACTION]" width="500" height="375">

Возможно, нужно попробовать файл метод с 3-м параметром, чтобы увидеть, который работает. Если заголовок установлен в имени файла, возможно, это будет отображаться как заголовок. (хотя не уверен, что будет делать загрузка, возможно, установите ссылку для загрузки с именем pdf)

ОБНОВЛЕНИЕ 2: Другая идея:

Как вы называете URL?

Вы указываете: GETPDF?guid=XXXX

Возможно, попробуйте: GETPDF/XXXX (вам может потребоваться настроить маршрутизацию для этого или вызвать параметр "id", если это значение по умолчанию)

0 голосов
/ 16 марта 2020

Вы можете сделать это, просто добавив свое имя файла как часть URL:

<object data="@Url.Action("GETPDF/MyFileName", new { guid = @Model.QuoteGuid })" type="application/pdf" width="800" height="650"></object>`

Вы должны игнорировать MyFileName в конфигурации роута. Chrome и Firefox используют PDF js для внутреннего использования. PDFjs попытайтесь извлечь отображаемое имя из URL.

Согласно коду PDF js для извлечения отображаемого имени из URL используется следующая функция:

function pdfViewSetTitleUsingUrl(url) {
  this.url = url;
  var title = pdfjsLib.getFilenameFromUrl(url) || url;
  try {
    title = decodeURIComponent(title);
  } catch (e) {
    // decodeURIComponent may throw URIError,
    // fall back to using the unprocessed url in that case
  }
  this.setTitle(title);
}

function getFilenameFromUrl(url) {
  const anchor = url.indexOf("#");
  const query = url.indexOf("?");
  const end = Math.min(
    anchor > 0 ? anchor : url.length,
    query > 0 ? query : url.length
  );
  return url.substring(url.lastIndexOf("/", end) + 1, end);
}

Как вы можете см. этот код использует последнюю позицию «/» для поиска имени файла.

Следующий код взят из PDF js, я не знаю, почему PDF js не использует это вместо getFilenameFromUrl. Этот код использует строку запроса для определения имени файла и использует его как запасной вариант для поиска имени файла.

function getPDFFileNameFromURL(url, defaultFilename = "document.pdf") {
  if (typeof url !== "string") {
    return defaultFilename;
  }
  if (isDataSchema(url)) {
    console.warn(
      "getPDFFileNameFromURL: " +
        'ignoring "data:" URL for performance reasons.'
    );
    return defaultFilename;
  }
  const reURI = /^(?:(?:[^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
  //            SCHEME        HOST         1.PATH  2.QUERY   3.REF
  // Pattern to get last matching NAME.pdf
  const reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
  const splitURI = reURI.exec(url);
  let suggestedFilename =
    reFilename.exec(splitURI[1]) ||
    reFilename.exec(splitURI[2]) ||
    reFilename.exec(splitURI[3]);
  if (suggestedFilename) {
    suggestedFilename = suggestedFilename[0];
    if (suggestedFilename.includes("%")) {
      // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
      try {
        suggestedFilename = reFilename.exec(
          decodeURIComponent(suggestedFilename)
        )[0];
      } catch (ex) {
        // Possible (extremely rare) errors:
        // URIError "Malformed URI", e.g. for "%AA.pdf"
        // TypeError "null has no properties", e.g. for "%2F.pdf"
      }
    }
  }
  return suggestedFilename || defaultFilename;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...