2016-03-13 16 views
13

Dopo aver eseguito correttamente l'implementazione di ajax POST, caricare oggetti modello e anche oggetti complessi grazie a questo nice post, il nuovo obiettivo è avere un'implementazione per uno scenario ancora più complicato.byte di trasferimento API MVC o Web [] l'approccio più efficiente

Ho cercato di attuare il compito in questione tramite esempi di codice alla ricerca di Google senza una risposta concreta e corretta

L'obiettivo è quello di avere multiuso (multi dati-tipo) il trasferimento di dati da un lato client al server (senza uso di una maschera o HttpRequestBase) passante matrice di byte greggio nel modo più efficiente (so che è possibile implementare un nuovo protocollo HTTP/2 o googles Protocol Buffers - Google's data interchange format

[HttpPost] 
public JsonResult UploadFiles(byte[] parUploadBytearry) 
{ 
} 

preferibilmente un modello che una delle sue proprietà è un byte[]

[HttpPost] 
public [JsonResult/ActionResult] Upload(SomeClassWithByteArray parDataModel) 
{ 
} 

L'Ajax http Messaggio Firma:

Log("AajaxNoPostBack preparing post-> " + targetUrl); 
$.ajax({ 
    type: 'POST', 
    url: targetUrl, 
    data: mods, 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 

    success: function for Success.. 
}); 

Ho anche disperatamente provato questa soluzione

public JsonResult UploadFiles(object parUploadBytearry) 
{ 
    if (parUploadBytearry== null) 
     return null; 
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
    var pathtosSave = System.IO.Path.Combine(Server.MapPath("~/Content/uploaded"), "Test11.png"); 
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 
    { 
     bf.Serialize(ms, parUploadFiles); 
     var Barr = ms.ToArray(); 
     var s = new System.Web.Utils.FileFromBar(pathtosSave, BR); 
    } 
} 

come ha fatto postale e dati ricevuti fino al salvataggio dei dati (.png) su un file nel sistema, i dati non erano legittimi.

E l'ultimo tentativo sano prima che l'oggetto di tentativo di array di byte è stato questo MSDN Code example 1

Qual è il modo corretto per passare un array di byte che C# capirà?

(in caso di documenti raw byte[] o file come png immagini)

+0

Nel vostro 'SomeClassWithByteArray' esempio, se il il protocollo di trasferimento è JSON, come si serializza l'array di byte? Base64? –

+0

questa è anche un'opzione, come ho detto all'inizio del post per gli oggetti complessi ho usato il plugin 'toDictionary', mi aspettavo che i dati grezzi , come uno dei suoi membri, sarebbero i più banali per poi convertirli in qualsiasi metodo efficace –

risposta

3

Qual è il modo corretto per passare un array di byte

Il modo più facile di leggere un byte[] da WebAPI senza scrivere MediaTypeFormatter personalizzato per "application/octet-stream" è semplicemente leggendolo dallo stream della richiesta manualmente:

[HttpPost] 
public async Task<JsonResult> UploadFiles() 
{ 
    byte[] bytes = await Request.Content.ReadAsByteArrayAsync(); 
} 

In another post, ho descritto come utilizzare il formattatore integrato per BSON (Binary JSON) che esiste in WebAPI 2.1.

Se si vuole andare giù per la lettura e scrittura di un BinaryMediaTypeFormatter che risponde "application/octet-stream", un'implementazione ingenuo sarebbe simile a questa:

public class BinaryMediaTypeFormatter : MediaTypeFormatter 
{ 
    private static readonly Type supportedType = typeof(byte[]); 

    public BinaryMediaTypeFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream")); 
    } 

    public override bool CanReadType(Type type) 
    { 
     return type == supportedType; 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return type == supportedType; 
    } 

    public override async Task<object> ReadFromStreamAsync(Type type, Stream stream, 
     HttpContent content, IFormatterLogger formatterLogger) 
    { 
     using (var memoryStream = new MemoryStream()) 
     { 
      await stream.CopyToAsync(memoryStream); 
      return memoryStream.ToArray(); 
     } 
    } 

    public override Task WriteToStreamAsync(Type type, object value, Stream stream, 
     HttpContent content, TransportContext transportContext) 
    { 
     if (value == null) 
      throw new ArgumentNullException("value"); 
     if (!type.IsSerializable) 
      throw new SerializationException(
       $"Type {type} is not marked as serializable"); 

     var binaryFormatter = new BinaryFormatter(); 
     binaryFormatter.Serialize(stream, value); 
     return Task.FromResult(true); 
    } 
} 
+0

WebAPI 2.1 o Request.Content (in particolare ora) è compatibile con .NET 4.03? nel mio progetto non c'è la definizione "Request.Content'" –

+0

Web API 2.1 dovrebbe essere, non c'è alcun vincolo alla versione .NET AFAIK. L'uso di async-await', con .NET 4.0.3 richiederebbe l'uso di ['Microsoft.Async.Bcl'] (https://www.nuget.org/packages/Microsoft.Bcl.Async/) biblioteca. –

+0

_Questo pacchetto non è supportato in Visual Studio 2010, _ sapevo che avrei dovuto fare i bagagli e spostarmi un giorno, ma non ora .. Sono ancora bloccato con il familiare 2010 come nell'app per desktop non ho raggiunto il massimo tecnologia di sviluppo di Microsoft, posso vedere nel web dev la storia è diversa. se non usi l'ultimo ... beh tutto. semplicemente non puoi lavorare (non del tutto ma in modo ottimale) –

Problemi correlati