'MVC or Web API transfer byte[] the most efficient approach
After achieving successful implementation of ajax POST, uploading model objects and even complex objects thanks to this nice post,
the new goal is to have an implementation for even little more complicated scenario.
I have tried to implement the task in question via code examples searching google without a concrete and correct answer
The goal is to have multi purpose (multi data-type) data transfer from client side to server (without use of a form or HttpRequestBase) passing raw byte array in the most efficient way (i know that it is possible to implement a new protocol HTTP/2 or googles
Protocol Buffers - Google's data interchange format
[HttpPost]
public JsonResult UploadFiles(byte[] parUploadBytearry)
{
}
preferably a model which one of it's properties is a byte[]
[HttpPost]
public [JsonResult / ActionResult] Upload(SomeClassWithByteArray parDataModel)
{
}
The ajax http Post Signature :
Log("AajaxNoPostBack preparing post-> " + targetUrl);
$.ajax({
type: 'POST',
url: targetUrl,
data: mods,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function for Success..
});
I also desperately tried this workaround
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);
}
}
as it did post and received data all the way to saving the data (.png) successfully to a file in system, the data was not legit.
And the last sane try before the object to byte array attempt was this msdn Code example 1
What is the correct way to pass a byte array that C# will understand?
(in case of documents raw byte[] or files like png images)
Solution 1:[1]
What is the correct way to pass a byte array
The easiest way of reading a byte[] from WebAPI without writing custom MediaTypeFormatter for "application/octet-stream" is by simply reading it from the request stream manually:
[HttpPost]
public async Task<JsonResult> UploadFiles()
{
byte[] bytes = await Request.Content.ReadAsByteArrayAsync();
}
In another post, I described how to utilize the built in formatter for BSON (Binary JSON) which exists in WebAPI 2.1.
If you do want to go down the read and write a BinaryMediaTypeFormatter which answers "application/octet-stream", a naive implementation would look like this:
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);
}
}
Solution 2:[2]
The answer is true but I am using asp.net mvc in visual studio 2019 and it seems there is no definition for Request.Content at all ,and this is the error:
‘HttpRequest’ does not contain a definition for ‘Content’ and no accessible extension method ‘Content’ accepting a first argument of type ‘HttpRequest’ could be found.
Then I used this approach and it works for me:
Request.InputStream.Position = 0;
List<byte> bytelist = new List<byte> { };
while (Request.InputStream.Position != Request.InputStream.Length)
{
bytelist.Add((byte)Request.InputStream.ReadByte());
}
I hope it is useful ????? ????
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Community |
| Solution 2 | da jowkar |
