Полный рабочий пример доступен на GitHub:
strip-pdf-metadata-dotnet
Введение
Очистка метаданных PDF — это рабочий процесс GroupDocs.Metadata для .NET, который удаляет словарь Info PDF и поля идентификации XMP из C#‑служб. Когда PDF‑контракт покидает внутренний диск, поля Author, Creator, Producer, Keywords и пакеты XMP часто остаются в нём. Очистка браузером и быстрый проход через Acrobat могут выглядеть успешными, пока XMP всё ещё содержит имя оригинального автора. Я столкнулся с этой проблемой, когда «очищенный» черновик всё равно показывал Alice Example в поле Author после того, как партнёр открыл файл в другом просмотрщике.
GroupDocs.Metadata для .NET предоставляет C#‑службам два чётких уровня очистки над тем же объектом Metadata: Sanitize() — полное удаление обнаруженных пакетов, и RemoveProperties — когда Title и Subject должны остаться, а личные данные — нет. В этой статье сравниваются оба подхода с шагами инспекции и проверки, которые делают результат проверяемым.
Вы получите работающие примеры для .NET 8, правило выбора между очисткой для внешних файлов и архивной, а также предикат проверки, который проверяет Author / Person.Creator вместо того, чтобы паниковать из‑за отпечатков Creator/Producer PDF‑движка после Save.
Почему очистка метаданных PDF важна
Внешние файловые обмены, многопользовательские загрузки и регулируемые архивы требуют повторяемого API удаления метаданных, а не настольного клика. Этот подход особенно ценен для:
- Порталы партнёров: полное удаление перед тем, как PDF пересекает границу доверия
- Поиск по записям: сохранять Title/Subject, удаляя поля типа Author
- Ответ на инциденты: доказать, что Author удалён после ошибочного обмена
- Контрольные точки CI: провалить сборку, когда проверка возвращает false
Однострочная политика («удалять метаданные») скрывает выбор между Sanitize и выборочным удалением. Указание уровня в код‑ревью предотвращает тихое переудаление Keywords, которые нужны вашему архиву.
Предварительные требования
Перед началом убедитесь, что у вас есть:
- .NET 8 SDK
- GroupDocs.Metadata 26.8.0 (временная лицензия)
- PDF, который всё ещё содержит поля Info и/или XMP‑идентификации
- Visual Studio 2022 или VS Code (по желанию)
Установка
Установите GroupDocs.Metadata через NuGet:
dotnet add package GroupDocs.Metadata --version 26.8.0
Или восстановите зависимости из файла проекта .csproj. Для неограниченного Save задайте переменную окружения LIC_METADATA_VALID, указывающую на папку, содержащую GroupDocs.Metadata.Product.Family.lic.
Метод 1 — Инспекция перед очисткой
Начните с чтения только списка, чтобы знать, какие поля действительно присутствуют в PDF. Инструменты браузера часто пропускают XMP; этот список служит базой для сравнения «до/после».
using var metadata = new Metadata(inputPath);
var properties = metadata.FindProperties(p =>
p.Tags.Contains(Tags.Person.Creator) ||
p.Tags.Contains(Tags.Tool.Software) ||
p.Tags.Contains(Tags.Content.Title) ||
p.Tags.Contains(Tags.Content.Subject) ||
string.Equals(p.Name, "Author", StringComparison.OrdinalIgnoreCase) ||
string.Equals(p.Name, "Creator", StringComparison.OrdinalIgnoreCase) ||
string.Equals(p.Name, "Producer", StringComparison.OrdinalIgnoreCase) ||
string.Equals(p.Name, "Keywords", StringComparison.OrdinalIgnoreCase));
foreach (var property in properties)
{
Console.WriteLine($"{property.Name} = {property.Value}");
}
Ключевые моменты:
- Теги плюс имена: комбинируйте проверку тегов с равенством
Author/Keywordsдля производителей, которые помечают поля иначе - Без изменения: безопасно для режимов сухого прогона и тикетов поддержки
- Общие фильтры: те же идеи можно переиспользовать в предикатах удаления позже
Метод 2 — Sanitize всех обнаруженных метаданных
Используйте Sanitize(), когда PDF должен уйти без следов авторства. Вызов удаляет распознанные пакеты, включая поля словаря Info и XMP, если API их обнаруживает, после чего сохраняется новый файл.
using var metadata = new Metadata(inputPath);
int removed = metadata.Sanitize();
Console.WriteLine(removed);
metadata.Save(outputPath);
Ключевые моменты:
- Один вызов: небольшая поверхность для внешних маршрутов
- Логировать количество: операторы могут увидеть уже чистые входы против больших очисток
- Ожидать штампы инструмента: после
SaveCreator/Producer могут показывать значенияTool.SoftwarePDF‑движка
Лучше всего: загрузки партнёров, публичные ссылки, обмен между арендаторами.
Метод 3 — Удалять только свойства авторского стиля
Когда Title, Subject и Keywords всё ещё нужны для поиска, удаляйте личные данные с помощью RemoveProperties, а не стирайте каждый пакет.
using var metadata = new Metadata(inputPath);
int removed = metadata.RemoveProperties(p =>
p.Tags.Contains(Tags.Person.Creator) ||
p.Tags.Contains(Tags.Person.Editor) ||
string.Equals(p.Name, "Author", StringComparison.OrdinalIgnoreCase) ||
string.Equals(p.Name, "Creator", StringComparison.OrdinalIgnoreCase) ||
string.Equals(p.Name, "Producer", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(removed);
metadata.Save(outputPath);
Ключевые моменты:
- Предикат проверяемый: в код‑ревью видно, какие именно поля идентификации удаляются
- Описательные поля остаются: Title/Subject/Keywords сохраняются при этом фильтре
- Тот же SDK: не требуется отдельная библиотека для выборочного пути
Лучше всего: внутренние архивы, циркулирующие черновики, политики, запрещающие Author, но допускающие keywords.
Как доказать удаление Author после Save?
Откройте очищенный PDF заново и ищите только Author / Person.Creator / Person.Editor. Выведите True, если ничего не осталось. Не рассматривайте оставшиеся отпечатки Creator/Producer Tool.Software как провал очистки — Save может переписать их именем PDF‑движка. Это различие сохраняет честность проверок соответствия в CI и предотвращает ложные тревоги, когда движок ставит свои собственные поля.
using var metadata = new Metadata(inputPath);
var leftovers = metadata.FindProperties(p =>
p.Tags.Contains(Tags.Person.Creator) ||
p.Tags.Contains(Tags.Person.Editor) ||
string.Equals(p.Name, "Author", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(!leftovers.Any());
Ключевые моменты:
- Задавать правильный вопрос: «Удалён ли Author?», а не «Пустой ли Creator?»
- Второе открытие: проверка после
Save, а не только в памяти - Подходит для CI: один булевый результат для тестов и логов
Выбор между Sanitize и RemoveProperties
| Вопрос | Предпочтительно Sanitize | Предпочтительно RemoveProperties |
|---|---|---|
| Файл выходит за пределы компании? | Да | Только если описательные поля должны сохраниться |
| Поиск в архиве требует Title? | Нет | Да |
| Политика гласит «нет людей в метаданных»? | Любой, затем проверка | Да, с предикатом, ориентированным на людей |
| Оператор хочет одну кнопку? | Да | Обернуть в именованный маршрут |
strip-pdf-metadata-dotnet — это исполняемый демонстрационный проект .NET, который последовательно выполняет все четыре шага над Resources/contract-with-metadata.pdf, чтобы вы могли увидеть инспекцию, полную очистку, выборочное удаление и проверку в одном запуске консоли.
Распространённые ошибки
- Полагаться только на очистку браузера: XMP часто выживает.
- Проверять имена Creator/Producer: отпечатки движка после
Saveвызывают ложные провалы. - Один предикат навсегда: пересматривайте имена полей идентификации, когда появляются новые производители.
- Пропуск настройки лицензии для Save: режим оценки может блокировать неограниченные записи; задайте
LIC_METADATA_VALIDдля полного тестирования конвейера. - Пропуск инспекции: без списка «до» нельзя понять, удалил ли Sanitize 7 полей или 0, потому что файл уже был чист.
На образце contract-with-metadata.pdf лицензированный запуск обычно выводит Author и Keywords при инспекции, количество удалённых полей при Sanitize около 7 и True от проверки, ориентированной на Author. Выборочное удаление автора выводит меньшее число (около 3), при этом Title и Subject остаются видимыми при второй инспекции.
Дополнительные ресурсы
- Use case: Sanitize vs author removal for PDF metadata (.NET)
- Docs: remove all detected metadata packages
- Docs: remove specific metadata properties
- GitHub: strip-pdf-metadata-dotnet
- API reference
Заключение
Очистка метаданных PDF в .NET — это не один вызов API с расплывчатым названием. Выбирайте Sanitize() для внешних стираний, RemoveProperties — когда Title и Subject должны остаться, и всегда инспектируйте, а затем проверяйте поля авторского стиля после Save. Склонируйте репозиторий‑пример, запустите его на образце контракта, а затем перенесите те же методы в ваш сервис загрузки с логированием количества удалённых полей.