Controller
public IActionResult play(IFormFile video1)
{
//read decrypted in bytes
MemoryStream ms = new MemoryStream();
video1.CopyTo(ms);
var readVideoBytes = ms.ToArray();
//encrypt
var decryptedVideoBytes = DecryptionAes(readVideoBytes);
var fileBytes1 = decryptedVideoBytes.ToArray();
ViewBag.Data = Convert.ToBase64String(fileBytes1);
}
View
<form asp-controller="video" asp-action="index" method="post" enctype="multipart/form-data" id="editForm">
<input type="file" name="video1" id="video1" class="form-control browse-btn mb-2">
<input type="submit" value="View Video" />
</form>
#if (ViewBag.Data != null)
{
<video controls autoplayheight="300" width="300">
<source type="video/mp4" src="data:video/mp4;base64,#ViewBag.Data">
</video>
}
Image UI
Above Worked well for small video but for larger video it is not working
How to create byte array in chunk and play ?
Related
Ok, I am sure this already has an answer somewhere, but I can honestly tell you that everything I have tried, has failed. Here is my current configuration:
Shared _Layout.cshtml (below the footer)
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="https://unpkg.com/dropzone#5/dist/min/dropzone.min.js"></script>
#await RenderSectionAsync("Scripts", required: false)
Images View
#model NewProductVM
<form id="form2" method="post" enctype="multipart/form-data" data-parsley-validate class="form-horizontal form-label-left">
<div class="form-group">
<label class="control-label col-md-2" for="first-name">
<span class="required">*</span>
</label>
<input type="hidden" value="#Model.Id" />
<div class="col-md-6" id="dropzone">
<div action="UploadFiles" class="dropzone" id="uploader">
Drop files here or click to upload.<br>
</div>
</div>
</div>
</form>
Products Controller
[HttpPost]
public async Task<IActionResult> UploadFiles(string Id)
{
bool bSuccess = true;
_ConnectionString = _Configuration.GetConnectionString("StorageConnectionString");
_ContainerName = _Configuration.GetValue<string>("StorageContainerName");
string uploads = Path.Combine(_hostingEnvironment.ContentRootPath, "Uploads");
if (!Directory.Exists(uploads))
Directory.CreateDirectory(uploads);
foreach (var iFormFile in Request.Form.Files)
{
if (iFormFile.Length > 0)
{
if (StorageHelper.IsImage(iFormFile))
{
var filePath = Path.Combine(uploads, iFormFile.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await iFormFile.CopyToAsync(stream);
}
bSuccess = await StorageHelper.UploadFileToStorage(iFormFile, filePath, _ConnectionString, _ContainerName);
System.IO.File.Delete(filePath);
ProductImage productImage = new ProductImage
{
ProductId = int.Parse(Id),
ImageURL = $"{_Configuration.GetValue<string>("StorageContainerURL")}/{iFormFile.FileName}"
};
await _imageService.AddNewImageAsync(productImage);
}
}
}
return RedirectToAction("Index");
}
I would really like to pass the entire NewProductVM model to the UploadFiles method, but there are not very many properties in the view model, so I could pass each property individually.
Right now I am taking someones suggestion to create a hidden form field and add a value I want to pass to the controller as a form field, but the parameter value in the UploadFiles method is null. I have also tried using asp-route-id="#Model.Id". When I did that, the value of id was 0 in the controller method.
Anyone have any suggestions?
Ok, I finally found the answer and I cannot believe how simple it was. I have been working on this for several hours. I found the answer here: https://social.msdn.microsoft.com/Forums/en-US/a87c6936-c0b5-4f47-b074-dbaf4c154cdd/id-parameter-returning-null-after-using-formdataappend-to-append-id-to-model-id-in-mvc-5?forum=aspmvc
This is what I did:
Images.cshtml
<form id="form2" method="post" enctype="multipart/form-data" data-parsley-validate class="form-horizontal form-label-left">
<div class="form-group">
<label class="control-label col-md-2" for="first-name">
<span class="required">*</span>
</label>
<div class="col-md-6" id="dropzone">
<div action="UploadFiles?Id=#Model.Id" class="dropzone" id="uploader">
Drop files here or click to upload.<br>
</div>
</div>
</div>
</form>
ProductsController.cs
[HttpPost]
public async Task<IActionResult> UploadFiles(int Id)
{
bool bSuccess = true;
_ConnectionString = _Configuration.GetConnectionString("StorageConnectionString");
_ContainerName = _Configuration.GetValue<string>("StorageContainerName");
//int Id = int.Parse(fc["Id"]);
string uploads = Path.Combine(_hostingEnvironment.ContentRootPath, "Uploads");
if (!Directory.Exists(uploads))
Directory.CreateDirectory(uploads);
foreach (var iFormFile in Request.Form.Files)
{
if (iFormFile.Length > 0)
{
if (StorageHelper.IsImage(iFormFile))
{
var filePath = Path.Combine(uploads, iFormFile.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await iFormFile.CopyToAsync(stream);
}
bSuccess = await StorageHelper.UploadFileToStorage(iFormFile, filePath, _ConnectionString, _ContainerName);
System.IO.File.Delete(filePath);
//ProductImage productImage = new ProductImage
//{
// ProductId = Id,
// ImageURL = $"{_Configuration.GetValue<string>("StorageContainerURL")}/{iFormFile.FileName}"
//};
//await _imageService.AddNewImageAsync(productImage);
}
}
}
return RedirectToAction("Index");
}
The part that really made it work was action="UploadFiles?Id=#Model.Id".
So basically, I am using the action to pass the values I want to my controller method.
Here is my current setup to upload a file to my webapp:
HTML:
<iframe name="myframe" id="frame1" class="hidden"></iframe>
<form target="myframe" method="post" enctype="multipart/form-data" action="/api/User/collection">
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
Controller:
// POST api/user/collection
[HttpPost("collection")]
public ActionResult<IResponse> SetCollection(IFormFile file)
{
var collection = fileDeflator.UnzipAndGetCollection(file);
if (collection == null)
return BadRequest(new BaseResponse("The collection file is invalid."));
return base.SetUserCollection(collection);
}
It's working, except that there is no feedback at all for the client.
I would prefer that the JSON returned by the server be caught in a javascript callback on the web page (not the iframe) and be parsed to refresh a section on the page.
Is that possible with the nature of form submit ?
I ended with something working as I wanted with the helpful resources that Amy provided.
Here is the solution:
<form id="formSendCollection">
<input type="file" id="fileCollection" name="fileCollection" />
<span onclick="submitCollection();" class="button is-primary">Submit</span>
</form>
function submitCollection() {
var fdata = new FormData();
var fileCollection = document.getElementById('fileCollection').files[0];
fdata.append("fileCollection", fileCollection);
sendAjax('/api/User/Collection', fdata, function (body) {
vueApp.modelUser.collection = JSON.parse(body);
});
}
function sendAjax(url, body, callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === XMLHttpRequest.DONE) {
callback(xmlhttp.responseText);
}
};
xmlhttp.open('POST', url, true);
xmlhttp.send(body);
}
I'm trying to display an image and I don't understand where my error is. I checked questions on the topic, but without result.
I've got an image in a byte[] type object : imageBuffer. I'm sure the everything is ok till here, the following code is functioning.
unsafe
{
fixed (byte* ptr = imageBuffer)
{
using (Bitmap image = new Bitmap(20 * lengthList, 20 * lengthList, 20 * lengthList * 4,
PixelFormat.Format32bppRgb, new IntPtr(ptr)))
{
image.Save(#"C:\Users\FS091843\Desktop\ Stations\Station1\greyscale.png");
}
}
}
(PS : my imageBuffer object has before the Bitmap creation no dimensions (I mean, it is no 2D array) : it is more precisely a byte[400 * lengthList * lengthList * 4])
As the convertbase64() can't figure out the dimensions without indications, I tried this :
// Some stuff before
DashboardPageModel dashboard = new DashboardPageModel();
unsafe
{
fixed (byte* ptr = imageBuffer)
{
using (Bitmap image = new Bitmap(20 * lengthList, 20 * lengthList, 20 * lengthList * 4,
PixelFormat.Format32bppRgb, new IntPtr(ptr)))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
image.Save(#"C:\Users\FS091843\Desktop\Stations\Station1\greyscale.png");
dashboard.image = imageBytes;
// Convert byte[] to Base64 String
}
}
}
}
return View(MVC.Views.Common.Dashboard.DashboardIndex, dashboard);
Where dashboard comes from my Model class (my project is an MVC project).
My View file finally looks like :
#model Serene7.Common.DashboardPageModel
#{
ViewData["Title"] = "Dashboard";
ViewData["PageId"] = "Dashboard";
}
#section Head {
<link rel="stylesheet" href="~/Content/iCheck/flat/blue.css">
<link rel="stylesheet" href="~/Scripts/morris/morris.css">
<link rel="stylesheet" href="~/Scripts/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet" href="~/Scripts/datepicker/datepicker3.css">
<link rel="stylesheet" href="~/Scripts/daterangepicker/daterangepicker-bs3.css">
<link rel="stylesheet" href="~/Scripts/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<script src="~/Scripts/raphael/raphael-min.js"></script>
<script src="~/Scripts/morris/morris.min.js"></script>
<script src="~/Scripts/sparkline/jquery.sparkline.min.js"></script>
<script src="~/Scripts/jvectormap/jquery-jvectormap-1.2.2.min.js"></script>
<script src="~/Scripts/jvectormap/jquery-jvectormap-world-mill-en.js"></script>
<script src="~/Scripts/knob/jquery.knob.js"></script>
<script src="~/Scripts/daterangepicker/moment.min.js"></script>
<script src="~/Scripts/daterangepicker/daterangepicker.js"></script>
<script src="~/Scripts/datepicker/bootstrap-datepicker.js"></script>
<script src="~/Scripts/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script>
<script src="~/Scripts/adminlte/pages/dashboard.js"></script>
<script src="~/Scripts/adminlte/demo.js"></script>
}
#section ContentHeader {
<h1>#LocalText.Get("Navigation.Dashboard")<small>#Html.Raw(Texts.Site.Dashboard.ContentDescription)</small></h1>
}
<!-- Small boxes (Stat box) -->
<div class="row">...</div><!-- /.row -->
<!-- Main row -->
<img src="data:image/png;base64,#(Convert.ToBase64String(Model.image))" alt="Red dot"/><!-- not really a red dot, had no idea what to enter as description -->
<div class="row">...</div>
and I get as a result :
Why isn't it functioning ?
Here is the html output
//<head>...</head>
<body id="s-LoginPage" class="no-navigation">
<script id="Template_Membership_LoginPanel" type="text/template">
<div class="flex-layout">
<div class="logo"></div>
<h3>Welcome to SERENE (Serenity Application Template)</h3>
<form id="~_Form" action="">
<div class="s-Form">
<div class="fieldset ui-widget ui-widget-content ui-corner-all">
<div id="~_PropertyGrid"></div>
<div class="clear"></div>
</div>
<div class="buttons">
<button id="~_LoginButton" type="submit" class="btn btn-primary">
Sign In
</button>
</div>
<div class="actions">
<i class="fa fa-angle-right"></i> Forgot password?
<i class="fa fa-angle-right"></i> Register a new account
<div class="clear"></div>
</div>
</div>
</form>
</div>
</script>
<div class="page-content">
<div id="LoginPanel">
</div>
</div>
<script type="text/javascript">
jQuery(function() {
new Serene7.Membership.LoginPanel($('#LoginPanel')).init();
});
</script>
</body>
</html>
The image looks like :
// …
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// …
You are storing raw bytes in the memory stream. It is just by chance that your image viewing tool displays the file properly because most image viewers are built to (mostly) ignore file extensions and try to render whatever is appropriate for them.
You need to actually convert your image into a PNG file in order to get the actual PNG bytes out of it:
// …
using (MemoryStream m = new MemoryStream())
{
image.Save(m, ImageFormat.Png); // convert to PNG
byte[] imageBytes = m.ToArray();
// …
Once you did that, the bytes will be proper PNG data, so it should also render in the browser properly, and the file on your disk should become a lot smaller since it’s no longer raw bitmap data.
I try to user an input type file to upload a file but my code don't work.
the variable "filePosted" stay to null value.
My code :
HTML :
<form method="post" name="gestionmembre" runat="server" enctype="multipart/form-data">
#using (Html.BeginForm()){
<label class="lmembre" for="nom">Nom:</label>#Html.TextBox("nom")<br />
<label class="lmembre" for="prenom">Prénom:</label>#Html.TextBox("prenom", Request["Prenom"])<br />
<label class="lmembre" for="mail">Mail:</label>#Html.TextBox("mail", Request["mail"])<br />
<label class="lmembre" for="photo">Photo:</label><input id="phototelecharge" type="file" name="photo" value="Télécharger photo"/> <br />
<div class="errorform">#Html.ValidationSummary()</div>
<input id="ajoutmembre" type="submit" name="boutonmembre" value="Ajouter"/>
}
</form>
I don't know if I have to put this atributes in form tag (method runat enctype).
now, in the controler, in block to receive form values, I put :
else if (Request["boutonmembre"] == "Ajouter")
{
//Traitement de l'upload de l'image
HttpPostedFile filePosted;
filePosted = System.Web.HttpContext.Current.Request.Files["phototelecharge"];
if (filePosted != null && filePosted.ContentLength > 0)
{
string fileNameApplication = System.IO.Path.GetFileName(filePosted.FileName);
string fileExtensionApplication = System.IO.Path.GetExtension(fileNameApplication);
// generating a random guid for a new file at server for the uploaded file
string newFile = Guid.NewGuid().ToString() + fileExtensionApplication;
// getting a valid server path to save
string filePath = System.IO.Path.Combine(Server.MapPath("uploads"), newFile);
if (fileNameApplication != String.Empty)
{
filePosted.SaveAs(filePath);
}
}
}
The problem is in :
filePosted = System.Web.HttpContext.Current.Request.Files["phototelecharge"];
The variable fileposted is null.
In the webpage, I select a file fro a disk and the path of the file is realy indicate in the textbox.
Tks for help me.
David
Here is a simple example
Controller
namespace stackoverflow.Controllers
{
public class HomeController : Controller
{
public ActionResult PostFile(HttpPostedFileBase myFile)
{
System.Diagnostics.Debugger.Break();
return View();
}
}
}
View
#using (Html.BeginForm("PostFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div id="postdata">
<input type="file" name="myfile" id="myFile" />
<input type="submit" value="submit" />
</div>
}
I have a form which looks, simplified, like this:
<form id="image-form" enctype="multipart/form-data">
<input type="text" name="imageEntryName" />
<input type="file" name="imageEntry" />
<input type="text" name="imageEntryAltText" />
<input type="submit" value="SEND INN" class="btn-ok" />
</form>
This is posted to this action:
[HttpPost]
[Route("~/api/Exhibition/SubmitImageEntry")]
public async Task<HttpResponseMessage> SubmitImageEntry()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
var provider = new MultipartFormDataStreamProvider("C:/test");
var data = await Request.Content.ReadAsMultipartAsync(provider);
return new HttpResponseMessage(HttpStatusCode.OK);
}
And this works. I get the posted data. But is this possible without the MultipartFormDataStreamProvider saving files to C:/test? I possible, I can just keep the data in memory until the action is completed.
EDIT: With MultipartFormDataStreamProvider I get the .FormData["key"] option, which is what I want.
Use the MultipartMemoryStreamProvider.