为不同的模型属性上载不同的文件类型

时间:2009-06-23 14:48:48

标签: asp.net-mvc

我有一个带有ImagePath和PDFPath属性的模型。

单击“保存”时,将调用控制器中的POST操作方法。我需要检查他们是否只上传了图像文件和pdf文件。如果他们上传了除这些文件类型之外的其他内容,我想使用以下内容设置ModelState错误:

ModelState.AddModelError("ImagePath", "Only image files are accepted");
ModelState.SetModelValue("ImagePath", new ValueProviderResult(null, null, null));

问题是我需要在AddModelError中设置正确的属性。问题是他们可能在ImagePath或PDFPath中放了一个* .doc文件,所以我不知道哪一个要报告为错误字段。

我如何确保他们只上传ceratin文件类型?正则表达式?

谢谢

编辑:这是我的控制器代码。

[AcceptVerbs(HttpVerbs.Post)]
    [Authorize]
    public ActionResult Create([Bind(Prefix = "", Exclude = "ID")] News item)
    {
        string imageUrl = "";
        string pdfurl = "";

        try
        {
            News.CheckForErrors(item);
        }
        catch (RulesException ex)
        {
            ex.AddModelStateErrors(ModelState, null);
        }

        foreach (string inputTagName in Request.Files)
        {
            HttpPostedFileBase file = Request.Files[inputTagName];
            if (file.ContentLength > 0)
            {
                string filePath = Path.Combine(HttpContext.Server.MapPath("/uploads"), Path.GetFileName(file.FileName));
                if (Path.GetExtension(file.FileName).ToLower() != ".jpg" || Path.GetExtension(file.FileName).ToLower() != ".pdf")
                {
                    //HELP! - Which model has the property error ImagePath/PDFPath?
                    ModelState.AddModelError("ImagePath", "Only JPG image files are accepted");
                    ModelState.SetModelValue("ImagePath", new ValueProviderResult(null, null, null));
                    break;
                }

                imageUrl = "/uploads/" + file.FileName;
            }
        }

        if (!ModelState.IsValid)
        {

                return View(item);

        }

        try
        {
            item.Save(User.Identity.Name);

        }
        catch (Exception x)
        {

        }



        return RedirectToAction("Index");

    }

1 个答案:

答案 0 :(得分:1)

你需要像GetFileByExtension()方法:

HttpPostedFileBase GetFileByExtension(HttpFileCollectionBase files, string[] extensions)
{
    Func<string, bool> extensionIsValid =
        fileExtension => extensions.Any(
            extension => String.Compare(extension, fileExtension, true) == 0
        );

    return files.Cast<string>().Select(x => files[x]).Single(
        file => extensionIsValid(System.IO.Path.GetExtension(file.FileName))
        );
}

或:

IList<HttpPostedFileBase> GetAllFilesByExtension(HttpFileCollectionBase files, string[] extensions)
{
    Func<string, bool> extensionIsValid =
        fileExtension => extensions.Any(
            extension => String.Compare(extension, fileExtension, true) == 0
        );

    return files.Cast<string>().Select(x => files[x]).Where(
        file => extensionIsValid(System.IO.Path.GetExtension(file.FileName))
        ).ToList();
}

示例:

var imageFile = GetFileByExtension(Request.Files,
                                   new [] { ".jpg", ".gif", ".png", ".bmp" });

var pdfFile = GetFileByExtension(Request.Files, new [] { ".pdf" });

或:

var imageFiles = GetAllFilesByExtension(Request.Files,
                                   new [] { ".jpg", ".gif", ".png", ".bmp" });

var pdfFiles = GetAllFilesByExtension(Request.Files, new [] { ".pdf" });

<强>更新:

也许您应尝试使用单独的表单/操作上传不同的上传(例如/ upload / create?newsid = 1?uploadtype = image for images和/ upload / create?newsid = 1?uploadtype = pdf for PDFs)。您的Upload.C​​reate操作可能如下所示:

public class UploadController : Controller
{
    public ActionResult Create(int newsId, string uploadType)
    {
        if(uploadType == "image")
        {
            // uploading only images
            var imageFiles = GetAllFilesByExtension(Request.Files, new [] { ".jpg", ".gif", ".png", ".bmp" });
            ...
        }
    }
}

在这种情况下,您始终知道文件的类型,应将其上传到操作