2010-04-08 8 views
1

ASP.NET MVC semble correctement lier automatiquement le champ d'entrée de fichier de la forme HTML et HttpPostedFileBase. D'autre part, il ne peut pas lier du champ de saisie de fichier au tableau byte..J'ai essayé et il émet une exception - quelque chose à propos de ne pas être en mesure de convertir en Base64. Je n'avais que la propriété byte array sur mes classes Model précédemment car plus tard j'en ai besoin pour effectuer la sérialisation de l'objet en fichier XML.Le modèle lie HttpPostedFileBase, puis stocke le fichier dans la banque de données

Maintenant, je suis venu avec cette solution de contournement et il fonctionne très bien, mais je ne sais pas si ce sera ok:

[DataContract] 
    public class Section : BaseContentObject 
    { 

     ... 
     [DataMember] 
     public byte[] ImageBytes; 

     private HttpPostedFileBase _imageFile; 
     public HttpPostedFileBase ImageFile 
     { 
     get { return _imageFile; } 
     set 
     { 
     _imageFile = value; 
     if (value.ContentLength > 0) 
     { 
     byte[] buffer = new byte[value.ContentLength]; 
     value.InputStream.Read(buffer, 0, value.ContentLength); 
     ImageBytes = buffer; 
     ImageType = value.ContentType; 
     } 
     } 
     } 

     [DataMember] 
     public string ImageType { get; set; } 
    } 

Répondre

4

Je pense que vous laissez votre modèle se connecter à étroitement avec votre contrôleur. La manière habituelle de faire est:

public ActionResult AcceptFile(HttpPostedFileBase submittedFile) { 
    var bytes = submittedFile.FileContents; 
    var model = new DatabaseThing { data = bytes }; 
    model.SaveToDatabase(); 
} 

Dans ce cas, il n'y a pas besoin de votre modèle pour être au courant de HttpPostedFileBase, qui est strictement un concept ASP.NET.

Si vous avez besoin complexe de liaison au-delà de ce que les DefaultModelBinder fournitures (ce qui est beaucoup), de la manière habituelle est d'enregistrer ModelBinders spécialisés dans Global.asax puis accepter vos propres classes de modèle comme action arguments Méthode, comme ceci:

En Global.asax:

ModelBinders.Binders.Add(typeof(MyThing), new ThingModelBinder()); 

Cette ModelBinder pourrait alors, par exemple, trouver un fichier qui a été enregistré avec la forme et de lier le contenu de ce fichier à la propriété Data de votre Thing.

Et dans votre contrôleur:

public ActionResult AcceptThing(MyThing thing) { 
    thing.Data.SaveToDatabase(); 
} 

Dans cette méthode d'action, votre ThingModelBinder aurait manipulé tout obligatoire, rendant transparente à la fois le contrôleur et le modèle.

La modification de vos classes de modèle actuelles pour être conscient de, et fonctionner avec, ASP.NET ne serait pas nécessaire dans ce cas. Vos classes Model sont, après tout, censées représenter vos données réelles.

+0

Vous avez partiellement raison, mais je travaille sur mes actions pour essayer de se débarrasser de FormCollection et HttpPostedFileBase, en les remplaçant par des classes Model fortement typées. – mare

+0

@mare Je pense que vous pourriez trouver de meilleurs moyens de le faire. J'ai mis à jour ma réponse. – bzlm

0

Apparemment, il y a d'énormes changements (juste trouvé) dans MVC Futures 2, en particulier en ce qui concerne les reliures de modèle.

Par exemple, le problème avec mon fichier d'entrée se liant à tableau d'octets, il est un liant maintenant:

• BinaryDataModelBinderProvider - Poignées de base 64 entrée encodée de liaison à l'octet [] et System.Linq.Data.Binary des modèles.