0

I have an asmx method that accepts a list of files like so:

[WebMethod]
public void UploadFiles(List<byte[]> files)
{

}

The Windows metadata is not included in the byte array. I tried using Dictionary<filename, byte[]> but classes that implement IDictionary are not serializable. I also tried using KeyValuePair<string, byte[]>[] but IMO it looks dirty. Are there other ways to include the name of the file?

jmc
  • 1,649
  • 6
  • 26
  • 47
  • 1
    Dictonaries and multiple classes with circular references are the most prevalent non-serializable objects. There are plenty of other ways to send it, including just making a `MyFile` class constaining the `Name` and `Payload` (or however you want to call it). Not sure what you're asking beyond suggesting a simple data structure. – Flater Mar 17 '15 at 08:56
  • Not sure I understand, but are you just trying to get your files into a list of byte[]? – sr28 Mar 17 '15 at 09:07
  • @Flater well, yes. I guess a data structure is a decent way to do it. thanks – jmc Mar 17 '15 at 09:08
  • @sr28 nope, its a list of files, 1 file = 1 byte array – jmc Mar 17 '15 at 09:08
  • What I mean is, do you currently have a list of files that you're trying to pass to the method 'UploadFiles', which only accepts a List? – sr28 Mar 17 '15 at 09:10
  • Yes I have, but specifically the list is already converted to an array. – jmc Mar 17 '15 at 09:12
  • 1
    Could this help? http://stackoverflow.com/questions/13739348/why-i-could-not-serialize-a-tuple-in-c – sr28 Mar 17 '15 at 09:26

1 Answers1

1

As mentioned in the comments, this can easily resolved by making a custom data class.

It's unfortunate that Dictionaries aren't serializable, but it's an inherent flaw of the XML serialization process. Same goes for data classes with circular references, it just doesn't work.
WCF, however, has managed to fix those issues. But you're using .asmx (SOAP), so you're stuck with the unfortunate incompatibility.

I'd simply make a custom class:

[Serializable]
public class File
{
    public string FileName {get;set;}
    public byte[] Payload {get;set;}
}

Then change your web method to:

[WebMethod]
public void UploadFiles(List<File> files)
{
    //...
}

Simple, but effective :)

Flater
  • 12,908
  • 4
  • 39
  • 62
  • I've got this working and I'm now getting a very large array. Can you recommend me some links on how to chunk or stream this array when passing to the web service? – jmc Mar 17 '15 at 12:39
  • That's a different question altogether. I'd look into splitting the List you send based on the size of the files (e.g. send only X files at a time, so that the total size of the X files you send doesn't exceed 1MB). If you need help with this, it'd be best to create a new question :) – Flater Mar 17 '15 at 14:24