我正在调用最多接受六个文件的API,总大小不能超过15Mb,允许的文件类型为:pdf, doc, docx, xls, xlsx, jpeg, jpg, gif, png, txt
。
我有一个名为TryAddAttachment
的方法,可用于检查是否符合要求。然而,没有什么能阻止程序员调用代码,而不是像下面那样绕过检查。什么是防止这种情况的最佳方法,或者是否有更好的解决方案来解决上述问题?
var contactForm = new ContactForm();
var file = new FileAttachment();
file.FileName = "Test.txt";
file.Content = Encoding.ASCII.GetBytes("Test text");
contactForm.Attachments.Add(file);
当前代码:
public class ContactForm
{
private readonly List<FileAttachment> _attachments;
private readonly string[] _validExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".jpeg", ".jpg", ".gif", ".png", ".txt" };
public ContactForm()
{
_attachments = new List<FileAttachment>();
}
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SocialSecurityNumber { get; set; }
public string Message { get; set; }
public List<FileAttachment> Attachments
{
get { return _attachments; }
}
public bool TryAddAttachment(FileAttachment attachment)
{
if (_attachments.Count + 1 > 6)
{
return false;
}
var extension = Path.GetExtension(attachment.FileName);
if (!IsValidExtension(extension))
{
return false;
}
long totalSize = 0;
foreach (var fileAttachment in _attachments)
{
totalSize += fileAttachment.Content.Length;
}
if (totalSize + attachment.Content.Length > 15000000)
{
return false;
}
_attachments.Add(attachment);
return true;
}
private bool IsValidExtension(string ext)
{
return _validExtensions.Contains(ext);
}
}
public class FileAttachment
{
public string FileName { get; set; }
public string ContentType
{
get
{
if (!string.IsNullOrWhiteSpace(FileName))
{
return MimeMapping.GetMimeMapping(FileName);
}
return null;
}
}
public byte[] Content { get; set; }
}
更新代码:
public class ContactForm
{
private readonly List<FileAttachment> _attachments;
private readonly string[] _validExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".jpeg", ".jpg", ".gif", ".png", ".txt" };
public ContactForm()
{
_attachments = new List<FileAttachment>();
}
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SocialSecurityNumber { get; set; }
public string Message { get; set; }
/// <summary>
/// Use AddAttachment to add files
/// </summary>
public ReadOnlyCollection<FileAttachment> Attachments
{
get { return _attachments.AsReadOnly(); }
}
public void AddAttachment(FileAttachment attachment)
{
var maximumAttachments = 6;
if (_attachments.Count + 1 > maximumAttachments)
{
throw new Exception($"Maximum attachments is {maximumAttachments}");
}
var extension = Path.GetExtension(attachment.FileName);
if (!IsValidExtension(extension))
{
var allowedExtensionsString = string.Join(",", _validExtensions);
throw new Exception($"Invalid file extension {extension}. Allowed are: {allowedExtensionsString}");
}
long totalSize = 0;
foreach (var fileAttachment in _attachments)
{
totalSize += fileAttachment.Content.Length;
}
totalSize += attachment.Content.Length;
var maximumSize = 15000000;
if (totalSize > maximumSize)
{
throw new Exception($"Total size of attachments is to big {totalSize}, maximum is {maximumSize}");
}
_attachments.Add(attachment);
}
private bool IsValidExtension(string ext)
{
return _validExtensions.Contains(ext);
}
}
public class FileAttachment
{
public string FileName { get; set; }
public string ContentType
{
get
{
if (!string.IsNullOrWhiteSpace(FileName))
{
return MimeMapping.GetMimeMapping(FileName);
}
return null;
}
}
public byte[] Content { get; set; }
}