When migrating ASP.NET applications from Windows to Linux using Mono, developers frequently encounter case sensitivity issues. Windows' case-insensitive filesystem often masks capitalization inconsistencies that become critical when deployed on Linux. This manifests particularly in:
- File inclusion paths in ASPX/CSHTML files
- Assembly references in Web.config
- Resource file paths (images, scripts)
For developers preferring native Linux filesystems:
1. ext4 Casefold Feature (Kernel 5.2+)
Modern Linux kernels support case-insensitive lookups:
# Enable casefold on existing directory
chattr +F /var/www/myapp
# Create new casefold directory
mkdir -p /var/www/myapp
chattr +F /var/www/myapp
Note: Requires filesystem formatted with encoding=utf8
option.
2. OverlayFS with nocase Option
mount -t overlay overlay -o lowerdir=/var/www,upperdir=/var/www_upper,workdir=/var/www_work,nocase /var/www_final
Samba Share Mount (As Mentioned)
# /etc/fstab entry
//localhost/wwwshare /var/www cifs credentials=/etc/samba/creds,uid=www-data,gid=www-data 0 0
NFS with Case-Insensitive Proxy
Configure NFS server with namecase lookup:
# /etc/exports
/var/www *(rw,insecure,no_subtree_check,fsid=0,no_root_squash,crossmnt,namecase=ignore)
For environments where filesystem changes aren't possible:
Mono Runtime Configuration
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;bin" caseInsensitive="true"/>
</assemblyBinding>
</runtime>
</configuration>
ASP.NET Path Normalization
Add this to Global.asax.cs:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string path = Request.PhysicalPath;
string actualPath = Directory.GetFiles(Path.GetDirectoryName(path),
Path.GetFileName(path),
SearchOption.TopDirectoryOnly)
.FirstOrDefault();
if (actualPath != null && actualPath != path)
{
Context.RewritePath(actualPath);
}
}
For Docker deployments:
FROM mono:latest
RUN apt-get update && apt-get install -y smbclient
RUN mkdir -p /mnt/www && echo "//samba/share /mnt/www cifs credentials=/samba-creds 0 0" >> /etc/fstab
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Where entrypoint.sh contains:
#!/bin/bash
mount /mnt/www
exec mono /var/www/bin/YourApplication.exe
When migrating ASP.NET applications from Windows to Linux (using Mono or .NET Core), case sensitivity becomes a major pain point. Windows' case-insensitive filesystem allows Default.aspx
and default.aspx
to refer to the same file, while Linux treats them as distinct entities.
Here are the most effective approaches I've tested in production environments:
1. SMB/CIFS Mount (Most Reliable)
# /etc/fstab entry
//localhost/web_share /var/www cifs credentials=/etc/samba/creds,uid=www-data,gid=www-data,file_mode=0664,dir_mode=0775 0 0
Pros: Native Windows compatibility, easy setup
Cons: Slight performance overhead
2. Ext4 Casefold Feature (Kernel 5.2+)
# Format new partition with casefolding
mkfs.ext4 -O casefold /dev/sdX1
# Mount with proper options
mount -o casesensitive=no /dev/sdX1 /var/www
Note: Requires CONFIG_UNICODE
kernel option enabled
3. OverlayFS Workaround
Create a case-insensitive layer over your existing filesystem:
mkdir -p /var/{www.upper,www.work}
mount -t overlay overlay -olowerdir=/var/www,upperdir=/var/www.upper,workdir=/var/www.work /var/www
For situations where filesystem changes aren't possible:
ASP.NET Core Middleware
app.UseStaticFiles(new StaticFileOptions {
OnPrepareResponse = ctx => {
var requestedPath = ctx.File.PhysicalPath;
if (!File.Exists(requestedPath)) {
var caseInsensitivePath = Directory.GetFiles(
Path.GetDirectoryName(requestedPath),
Path.GetFileName(requestedPath),
new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive }
).FirstOrDefault();
if (caseInsensitivePath != null) {
ctx.Context.Response.Redirect($"/{Path.GetRelativePath(
env.WebRootPath,
caseInsensitivePath
).Replace('\\', '/')}");
}
}
}
});
Case-insensitive operations in Linux come with tradeoffs:
- SMB: ~15-20% throughput reduction
- Ext4 casefold: Minimal impact (~3-5%)
- Application-level solutions: Highest overhead (30-50% for file-heavy operations)
For enterprise deployments, I recommend:
- Use Ext4 casefold where supported (newer kernels)
- Implement application-level case normalization during CI/CD pipeline
- For legacy systems, SMB mounts provide the best compatibility
Always test with:
find /var/www -type f | sort | xargs -I {} bash -c 'echo "${#}" "$(realpath --relative-to=/var/www "{}")"'