I have a custom .gitattributes entry like so:
*.csproj text filter=csprojsort
[filter "csprojsort"]
clean = "path/to/repo/csprojsort.exe"
git show path/to/file.csproj
That sounds like the filter is working as intended. The documentation says a clean filter is "...used to convert the content of a worktree file to a blob upon checkin", which is exactly the behavior you're seeing. It doesn't modify files in your working directory.
A smudge filter does the opposite: when you check out a file, the smudge filter runs before the data is written to a file.