2011-02-16 47 views
4

它是否存在一種類似於Paperclip for Rails的插件?回形針for asp.net mvc

真的痛實現自己的系統文件上傳大小調整它...

將是冷靜地對模型屬性,將讓PARAMS像這樣:

型號:

[Paperclip(Sizes={thumb="100x20",big="200x40"},Path="~/public/")] 
public string Image{get;set;} 

查看:

Html.Editor(x=>x.Image) 

here is small tutorial for rails

+2

雖然問題不是措辭非常好,我理解你的痛苦。我***愛軌道回形針插件。你有沒有找到一個合適的asp mvc對口? – 2011-04-14 20:38:02

+0

我正在尋找完全相同的東西......沒有人找到/開發任何類似於paperclip for ASP.NET的東西? – 2011-09-13 02:27:14

回答

9

看起來這個問題很老舊,我偶然偶然發現它,因爲它似乎還沒有回答,所以我決定把我的2¢。

我不知道這樣的插件存在ASP.NET,但它會很輕鬆寫一個:

[AttributeUsage(AttributeTargets.Property)] 
public class PaperClipAttribute : Attribute, IMetadataAware 
{ 
    public PaperClipAttribute(string uploadPath, params string[] sizes) 
    { 
     if (string.IsNullOrEmpty(uploadPath)) 
     { 
      throw new ArgumentException("Please specify an upload path"); 
     } 

     UploadPath = uploadPath; 
     Sizes = sizes; 
    } 

    public string UploadPath { get; private set; } 
    public string[] Sizes { get; private set; } 

    public void OnMetadataCreated(ModelMetadata metadata) 
    { 
     metadata.AdditionalValues["PaperClip"] = this; 
    } 
} 

然後定義爲HttpPostedFileBase類型的定製模型綁定:

public class PaperClipModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var paperClip = bindingContext.ModelMetadata.AdditionalValues["PaperClip"] as PaperClipAttribute; 
     if (paperClip == null) 
     { 
      return base.BindModel(controllerContext, bindingContext); 
     } 

     var uploadedFile = base.BindModel(controllerContext, bindingContext) as HttpPostedFileBase; 
     if (uploadedFile == null) 
     { 
      return null; 
     } 

     var uploadPath = controllerContext.HttpContext.Server.MapPath(paperClip.UploadPath); 
     if (!Directory.Exists(uploadPath)) 
     { 
      throw new ArgumentException(string.Format("The specified folder \"{0}\" does not exist", uploadPath)); 
     } 
     var sizes = 
      (from size in paperClip.Sizes 
      let tokens = size.Split('x') 
      select new Size(int.Parse(tokens[0]), int.Parse(tokens[1])) 
      ).ToArray(); 

     foreach (var size in sizes) 
     { 
      var extension = Path.GetExtension(uploadedFile.FileName); 
      var outputFilename = Path.Combine(
       uploadPath, 
       Path.ChangeExtension(
        string.Format("image{0}x{1}", size.Width, size.Height), 
        extension 
       ) 
      ); 
      Resize(uploadedFile.InputStream, outputFilename, size); 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 

    private void Resize(Stream input, string outputFile, Size size) 
    { 
     using (var image = Image.FromStream(input)) 
     using (var bmp = new Bitmap(size.Width, size.Height)) 
     using (var gr = Graphics.FromImage(bmp)) 
     { 
      gr.CompositingQuality = CompositingQuality.HighSpeed; 
      gr.SmoothingMode = SmoothingMode.HighSpeed; 
      gr.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      gr.DrawImage(image, new Rectangle(0, 0, size.Width, size.Height)); 
      bmp.Save(outputFile); 
     } 
    } 
} 

將在Application_Start註冊:

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 

    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 
    ModelBinders.Binders[typeof(HttpPostedFileBase)] = new PaperClipModelBinder(); 
} 

,我們一幾乎完成了。剩下的就是經典的東西。

視圖模型:

public class MyViewModel 
{ 
    [PaperClip("~/App_Data", "100x20", "200x40", "640x480")] 
    [Required(ErrorMessage = "Please select a file to upload")] 
    public HttpPostedFileBase Image { get; set; } 
} 

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 
     return Content("thanks for uploading"); 
    } 
} 

查看:

@model MyViewModel 

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
    @Html.LabelFor(x => x.Image) 
    <input type="file" name="image" /> 
    @Html.ValidationMessageFor(x => x.Image) 
    <input type="submit" value="Upload" /> 
}