💡 Pełny działający przykład dostępny na GitHub: scrub-office-document-pii-dotnet
Stara metoda była bolesna
Rutyna wygląda tak: otwierasz dokument, File, Info, Check for Issues, Inspect Document, zaznaczasz pola, Remove All, zapisujesz pod nową nazwą, zamykasz, otwierasz kolejny. Po czterdziestu plikach ktoś zauważa, że Inspect Document usunął także tytuł, na którym indeksuje się klucze rekordów, a kopia wysłana godzinę wcześniej wciąż zawierała identyfikator zatwierdzającego w SharePoint, ponieważ plik został zapisany z innej aplikacji, która pole ponownie zapisała.
Usuwanie danych osobowych z metadanych to funkcja GroupDocs.Metadata dla .NET, która programowo usuwa właściwości zawierające tożsamość z dokumentów Office i raportuje, co pozostało. Ręczna procedura zawodzi z trzech powodów: nie skaluje się powyżej kilku plików, jest „wszystko albo nic” w kwestii tego, które pola zostaną usunięte, i nie tworzy żadnego zapisu tego, co zostało usunięte. Ten artykuł pokazuje wersję .NET tej samej pracy, grupę właściwości po jednej.
Warto wiedzieć, co tak naprawdę znajduje się w dokumencie. Plik Word, który przeszedł przez rundę recenzji, zazwyczaj zawiera Author i LastSavedBy pochodzące z konta Windows osoby, która go zapisała, Manager i Company z szablonu korporacyjnego, licznik wersji, TotalEditingTime, znacznik czasu LastPrinted oraz liczniki wątków komentarzy. Dodaj SharePoint do łańcucha, a otrzymasz także identyfikatory zatwierdzających, ścieżki przepływu pracy, URI typów zawartości i szablon, z którego dokument został utworzony. Nic z tego nie jest widoczne na stronie, a wszystko podróżuje w tym samym pliku.
Jest lepszy sposób
Wszystko w GroupDocs.Metadata dla .NET działa przez jeden silnik wyszukiwania właściwości. RemoveProperties przyjmuje wyrażenie lambda operujące na MetadataProperty, usuwa każdą właściwość zaakceptowaną przez lambdę i zwraca liczbę usuniętych elementów. FindProperties uruchamia tę samą lambdę, ale bez zapisu. Właściwości mają także tagi, więc Tags.Person.Creator identyfikuje pola typu autor we wszystkich formatach i pakietach, zamiast dopasowywać dosłowne nazwy, które różnią się w zależności od aplikacji.
Daje to trzy warianty czyszczenia zamiast jednego przycisku: przebieg po tagu dla pól tożsamości, przebiegi po nazwach dla rodzin takich jak komentarze i wersje oraz Sanitize(), gdy nic nie powinno pozostać. Wszystkie trzy zwracają liczby, a te liczby czynią przebieg audytowalnym.
Nowy sposób: predykat dla każdej grupy właściwości
Krok 1 – Wyczyść nazwy
Cztery kontrole tagów obejmują grupę tożsamości. Pola opisowe pozostają nietknięte, co odróżnia to od opcji Remove All w Document Inspector:
using (var metadata = new Metadata(inputPath))
{
if (metadata.FileFormat == FileFormat.Unknown) return 0;
var affected = metadata.RemoveProperties(p =>
p.Tags.Contains(Tags.Person.Creator) ||
p.Tags.Contains(Tags.Person.Editor) ||
p.Tags.Contains(Tags.Person.Manager) ||
p.Tags.Contains(Tags.Corporate.Company));
metadata.Save(outputPath);
return affected;
}
Sprawdzenie FileFormat.Unknown jest strażnikiem, który utrzymuje zero w uczciwości: bez niego nieczytelny plik i czysty plik wyglądają tak samo dla wywołującego.
Krok 2 – Wyczyść rodziny wokół nich
Komentarze, wersje i pola serwera nie mają tagu, więc predykat dopasowuje nazwy. Oś czasu edycji jest grupą najczęściej pomijaną i jednocześnie tą, która mówi, jak dokument został wyprodukowany:
using (var metadata = new Metadata(inputPath))
{
if (metadata.FileFormat == FileFormat.Unknown) return 0;
var affected = metadata.RemoveProperties(p =>
p.Name != null && (
p.Name.Contains("Revision") ||
p.Name.Contains("TrackedChange") ||
p.Name.Contains("LastPrinted") ||
p.Name.Contains("TotalEditingTime") ||
p.Name.Contains("EditTime")));
metadata.Save(outputPath);
return affected;
}
Dopasowanie podciągu jest celowe: łapie CommentsCount razem z Comment oraz TotalEditingTime razem z EditTime, bez konieczności utrzymywania dokładnej listy nazw dla każdego formatu. Przebieg SharePoint to ten sam wywołanie z dodatkowymi słowami Server, Workflow, Approver, ContentType i Template.
Krok 3 – Usuń wszystko, a potem sprawdź wynik
Na granicy zaufania jedno wywołanie zastępuje cztery poprzednie przebiegi:
using (var metadata = new Metadata(inputPath))
{
if (metadata.FileFormat == FileFormat.Unknown) return 0;
var affected = metadata.Sanitize();
metadata.Save(outputPath);
return affected;
}
Następnie część, której ręczna procedura nie ma odpowiednika. Skan weryfikacyjny ponownie wykorzystuje predykaty usuwania poprzez FindProperties i sortuje pozostałości do dwóch list:
foreach (var p in props)
{
var value = p.InterpretedValue?.ToString() ?? p.Value?.ToString() ?? string.Empty;
if (string.IsNullOrWhiteSpace(value)) continue;
if (value == "0" || value == "0.0") continue;
var entry = $"{p.Name}={value}";
var name = p.Name ?? string.Empty;
if (name.StartsWith("Comment") || name.StartsWith("Revision"))
report.ContentLevelLeaks.Add(entry);
else
report.MetadataLeaks.Add(entry);
}
MetadataLeaks musi być pusty, aby plik został uznany za zsanityzowany. ContentLevelLeaks jest informacyjny: autorzy komentarzy i zmian śledzonych w Wordzie znajdują się w word/document.xml, czyli w treści dokumentu, i ich usunięcie wymaga biblioteki do edycji treści, takiej jak Aspose.Words, a nie API metadanych.
Dlaczego nie wywołać po prostu Sanitize() na wszystkim?
Ponieważ większość dokumentów jest nadal w użyciu. Sanitize() usuwa każdy wykryty pakiet, w tym Title, Subject i Keywords – pola, od których zależy system rejestrów i indeks wyszukiwania. Używaj ukierunkowanych przebiegów, gdy plik krąży wewnątrz organizacji, zachowuj opisowe metadane, a pełne wyczyszczenie rezerwuj dla kopii, która faktycznie opuszcza firmę.
Porównanie: Przed vs. Po
| Ręczna inspekcja | GroupDocs.Metadata dla .NET | |
|---|---|---|
| Seletywność | Remove All, pola opisowe włączone | jeden predykat na grupę właściwości |
| Zakres | pola widoczne w dialogu | każdy pakiet wykryty przez bibliotekę, w tym niestandardowe części OOXML |
| Rekord | brak | liczba zmodyfikowanych elementów zwracana po każdej operacji |
| Weryfikacja | ponowne otwarcie i przegląd | skan FindProperties z listami metadanych i treści |
| Batch 200 plików | 200 kliknięć | jedna pętla, pięć operacji, jedna linia logu na plik |
Wiersz, który zmienia zachowanie, to rekord. Gdy każdy przebieg zwraca liczbę, sanitizacja przestaje być jednorazowym krokiem, który ktoś pamięta wykonać, i staje się danymi, na których pipeline może asertywnie działać: próg w teście, pole w tabeli audytu, warunek, który przerywa nocne zadanie. To także wiersz, którego ręczna procedura nie jest w stanie wygenerować przy żadnym poziomie dyscypliny.
Przykład z życia: Hook przed wysłaniem
Portal wsparcia pozwala pracownikom dołączać dokumenty do zgłoszeń klientów. Obsługa załącznika teraz uruchamia przebieg tożsamości i przebieg serwera przed zapisaniem pliku, zapisuje oba liczniki w zgłoszeniu i przeprowadza kontrolę wycieków na zapisanej kopii. Niepusta lista wycieków metadanych odrzuca upload z komunikatem wymieniającym naruszoną właściwość, więc osoba dołączająca plik dowiaduje się o problemie od razu, a nie po dotarciu do klienta.
Dwa szczegóły czynią ten hook praktycznym. Przebiegi zapisują do nowej ścieżki, więc oryginał pozostaje w prywatnym magazynie pracownika i nic nie zostaje zniszczone przez automatyczny krok. Liczby trafiają do rekordu zgłoszenia obok załącznika, co oznacza, że odpowiedź na pytanie „co zostało usunięte z tego dokumentu” jest przechowywaną liczbą, a nie przypuszczeniem o tym, co zwykle robi pipeline.
Za pierwszym razem, gdy skierowałem tę kontrolę na prawdziwy szablon, zwróciła wartość Manager, którą przebieg tożsamości usunął sekundy wcześniej, a szablon korporacyjny zapisał z powrotem przy zapisie. Wywołanie usuwające działało dokładnie tak, jak opisano; problemem był pipeline wokół niego, a jedynie odczyt po zapisaniu to ujawnił.
Co jeszcze można zrobić z GroupDocs.Metadata?
Ten sam silnik predykatów odczytuje. Porównywanie właściwości między dwoma wersjami dokumentu ujawnia zmiany właściciela i ponowne autorstwo poza procesem recenzji, a przegląd czyszczenia metadanych opisuje, gdzie interaktywne narzędzie nadal ma sens obok passu sterowanego API. Ponieważ system tagów obejmuje różne formaty, predykat tożsamości napisany tutaj działa również na PDF‑ach, obrazach i plikach audio bez modyfikacji.
Ta przenośność jest warta planowania. Reguła czyszczenia napisana jako lambda na MetadataProperty to zwykły C#, więc może żyć w bibliotece współdzielonej, być testowana jednostkowo na dokumentach testowych i być wywoływana przez dowolną usługę, która jej potrzebuje: punkt końcowy eksportu, zaplanowane zadanie rejestracyjne lub krok budowania, który sanitizuje załączniki dokumentacji przed wydaniem. Reguły pozostają w jednym miejscu; zmieniają się jedynie miejsca wywołań.
Podsumowanie
Cztery ukierunkowane przebiegi, jeden pełny Sanitize, jeden skan weryfikacyjny. Ten zestaw pokrywa praktyczny zakres dla dokumentów Office: zachowuj opisowe metadane, gdy plik krąży, usuń wszystko, gdy opuszcza organizację, i udowodnij wynik w obu przypadkach. Sklonuj przykład, uruchom go na dokumencie, który przeszedł rzeczywistą rundę recenzji, i odczytaj liczbę zmodyfikowanych elementów. Zazwyczaj są one wyższe niż się spodziewano – i właśnie o to chodzi.