加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 在MVC中检查图像mime,大小等

发布时间:2020-12-16 00:09:12 所属栏目:asp.Net 来源:网络整理
导读:我在这里找到了一个很好的方法来检查用户上传的文件是否是图片,当我尝试实现它时,我遇到了什么问题. 这是我发现检查文件的类 public static class HttpPostedFileBaseExtensions{ public const int ImageMinimumBytes = 512; public static bool IsImage(thi
我在这里找到了一个很好的方法来检查用户上传的文件是否是图片,当我尝试实现它时,我遇到了什么问题.

这是我发现检查文件的类

public static class HttpPostedFileBaseExtensions
{
    public const int ImageMinimumBytes = 512;

    public static bool IsImage(this HttpPostedFileBase postedFile)
    {            
        //-------------------------------------------
        //  Check the image mime types
        //-------------------------------------------
        if (postedFile.ContentType.ToLower() != "image/jpg" &&
                    postedFile.ContentType.ToLower() != "image/jpeg" &&
                    postedFile.ContentType.ToLower() != "image/pjpeg" &&
                    postedFile.ContentType.ToLower() != "image/gif" &&
                    postedFile.ContentType.ToLower() != "image/x-png" &&
                    postedFile.ContentType.ToLower() != "image/png")
        {
            return false;
        }

        //-------------------------------------------
        //  Check the image extension
        //-------------------------------------------
        if (Path.GetExtension(postedFile.FileName).ToLower() != ".jpg"
            && Path.GetExtension(postedFile.FileName).ToLower() != ".png"
            && Path.GetExtension(postedFile.FileName).ToLower() != ".gif"
            && Path.GetExtension(postedFile.FileName).ToLower() != ".jpeg")
        {
            return false;
        }

        //-------------------------------------------
        //  Attempt to read the file and check the first bytes
        //-------------------------------------------
        try
        {
            if (!postedFile.InputStream.CanRead)
            {
                return false;
            }

            if (postedFile.ContentLength < ImageMinimumBytes)
            {
                return false;
            }

            byte[] buffer = new byte[512];
            postedFile.InputStream.Read(buffer,512);
            string content = System.Text.Encoding.UTF8.GetString(buffer);
            if (Regex.IsMatch(content,@"<script|<html|<head|<title|<body|<pre|<table|<as+href|<img|<plaintext|<cross-domain-policy",RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
            {
                return false;
            }
        }
        catch (Exception)
        {
            return false;
        }

        //-------------------------------------------
        //  Try to instantiate new Bitmap,if .NET will throw exception
        //  we can assume that it's not a valid image
        //-------------------------------------------

        try
        {
            using (var bitmap = new System.Drawing.Bitmap(postedFile.InputStream))
            {
            }
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }
}

我的个人资料班

public class Profile
{
    public int ProfileID { get; set; }
    [Required(ErrorMessage = "Please enter a profile name")]
    public string Name { get; set; }
    [Required(ErrorMessage = "Please enter a intro")]
    public string Intro { get; set; }
    [Required(ErrorMessage = "Please enter a description")]
    public string Description { get; set; }
    public decimal Rate { get; set; }
    public byte[] ImageData { get; set; }
    public string ImageMimeType { get; set; }
}

我更改后的ProfileController.我添加了HttpPostedFileBase作为参数,并且还使用了这一行,如果(HttpPostedFileBaseExtensions.IsImage(file)== true),我认为它会将其排序,但没有任何区别.

[HttpPost]
    public ActionResult Edit(Profile profile,HttpPostedFileBase file)
    {
        if (HttpPostedFileBaseExtensions.IsImage(file) == true)
            {
                if (ModelState.IsValid)
                    {               

                        repository.SaveProfile(profile);
                        TempData["message"] = string.Format("{0} has been saved",profile.Name);
                        return RedirectToAction("List");
                    }
                 else
                    {
                        // there is something wrong with the data values
                        return View(profile);
                    }
            }
        else
        {
            return View(ViewBag);
        }            
    }

最后来自存储库的SaveProfile方法.

public void SaveProfile(Profile profile)
    {
        Profile dbEntry = context.Profiles.Find(profile.ProfileID);                        
        if (profile.ProfileID == 0)
        {
            context.Profiles.Add(profile);
        }
        else
        {
            if (dbEntry != null)
            {                    
                    dbEntry.Name = profile.Name;
                    dbEntry.Rate = profile.Rate;
                    dbEntry.Intro = profile.Intro;
                    dbEntry.Description = profile.Description;
                if (profile.ImageData != null)
                {

                    dbEntry.ImageData = profile.ImageData;
                    dbEntry.ImageMimeType = profile.ImageMimeType;
                }                                                               
            }
        }
        context.SaveChanges();
    }

我还尝试编辑SaveProfile方法,但是无法像在类中那样实现所有函数,而只是将它分开并按原样使用它.任何想法我哪里出错了?

解决方法

你有很多问题,一些是重大问题,一些是小问题.

首先,您使用的扩展方法是错误的.添加扩展的重点是它成为该类型实例的方法. this关键字param是隐式的,并且由反向引用调用该方法的对象填充,而不是显式传递.换句话说,你应该对你的条件有什么:

if (file.IsImage())
{
    ...

另请注意,没有与true进行比较.虽然没有任何问题,但完全没有必要,你已经有了一个布尔值.

其次,虽然围绕其余代码放置此条件应该有效地防止对象被保存,但它不向用户提供指导.相反,你应该做的事情如下:

if (!file.IsImage())
{
    ModelState.AddModelError("file","Upload must be an image");
}

if (ModelState.IsValid)
{
    ...

通过向ModelState添加错误,不仅会导致IsValid为false,而且现在会在再次返回表单时向用户显示实际的错误消息.

第三,通过尝试从数据库中选择现有的配置文件实例,您将获得该实例或null.因此,您无需检查ProfileId是否为0,这是一个非常脆弱的检查(用户只需将隐藏字段的值更改为其他内容即可修改现有项目).相反,只需:

var dbEntry = context.Profiles.Find(profile.ProfileID);                        
    if (dbEntry == null)
    {
        // add profile
    }
    else
    {
        // update profile
    }

第五,你永远不会对文件做任何事情.在某些时候,你应该做的事情如下:

var binaryReader = new BinaryReader(file.InputStream);
dbEntry.ImageData = binaryReader.ReadBytes(file.InputStream.Length);
dbEntry.ImageMimeType = file.ContentType;

最后,这比任何东西都更具风格,但过度使用不必要的else块会使您的代码更难阅读.您可以简单地让错误案例失效.例如:

if (!file.IsImage())
{
    ModelState.AddModelError("file","Upload must be an image");
}

if (ModelState.IsValid)
{
    // save profile and redirect
}

return View(profile);

第一个条件将向ModelState添加错误或不添加错误.然后,在第二个条件中,代码将仅在没有错误的情况下运行,然后返回,因此您永远不会达到最终返回View(profile).但是,如果存在任何验证错误,您只需进入最终返回.没有其他必要,代码更简洁,更易读.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读