Using the following code I am trying to resize a image and to save it into a table into a VARBINARY(MAX) type field.
When I try to display the saved image, I get nothing on my screen...
When I try to decode manually the saved image using an online decoder, I get the following error :
"The MIME of file was detected as “application/octet-stream”, but the decoder displays it as “image/octet-stream”"
Please help me to save the image into table !
Thank you very much !
The sample below is based on :
https://www.prowaretech.com/Computer/Blazor/Examples/WebApi/UploadImages
and the online Base64 decoder I used is :
https://base64.guru/converter/decode/image
This is the code I am using :
#page "/TestBase64"
#using ResizeUploadImages.Shared
#using System.IO
#using System.Text;
#using System.Threading;
#using System.Threading.Tasks;
#using Microsoft.AspNetCore;
#inject HttpClient Http
#inject IJSRuntime JsRuntime
<table border="1" cellspacing="1" cellpadding="1">
<tr>
<td>
#foreach (var item in filesBase64_V1)
{
<tr>
<td style="text-align: center">
<h6> File Name : </h6>
<h6> "#item.fileName" </h6>
</td>
</tr>
<tr>
<td style="text-align: center">
<img src="data:#item.contentType;base64,#item.base64data" />
</td>
</tr>
}
</td>
</tr>
<tr>
<td>
<div class="custom-file" id="img_V1_div">
<InputFile id="inputFile_V1" class="custom-file-input" multiple="false" OnChange="OnChange" accept="image/png, image/jpeg, image/gif, image/bmp" />
<label class="custom-file-label" for="inputFile_V1">Choose file</label>
</div>
</td>
</tr>
</table>
#code {
List<ImageFile>
filesBase64_V1 = new List<ImageFile>();
async Task OnChange(InputFileChangeEventArgs e)
{
filesBase64_V1 = new List<ImageFile>(); // clear the list of files
var files = e.GetMultipleFiles(); // get the files selected by the users
foreach (var file in files)
{
var preview_file = await file.RequestImageFileAsync(file.ContentType, 250, 250); // resize the image file
var buffer_preview_file = new byte[preview_file.Size]; // allocate a buffer to fill with the file's data
using (var stream = preview_file.OpenReadStream())
{
await stream.ReadAsync(buffer_preview_file); // copy the stream to the buffer
}
filesBase64_V1.Add(new ImageFile { FileData=buffer_preview_file, base64data = Convert.ToBase64String(buffer_preview_file), contentType = file.ContentType, fileName = file.Name, IMAGE_IS_DISPLAYED = false }); // convert to a base64 string!!
await JsRuntime.InvokeVoidAsync("alert", $"{buffer_preview_file}");
//I am saving the two variables
// buffer_preview_file
// and
// base64data
// into a table into two VARBINARY(MAX) fields
// Each time when I try to load images from that table, I get nothing
// on my page
}
}
}
Related
We use ASP.NET MVC 5's AjaxHelper and Ajax.BeginForm to request a partial view. That request also needs some JSON data in order to update a map control.
The view rendering part of the process works great (a table body is replaced with the strongly-typed partial view), but the JSON data (embedded into the data-json attribute of the div element as described in this answer and retrieved in my OnSuccess function) always has the same value.
To eliminate the controller code or ViewBag as culprit, I replaced the JSON data (originally retrieved from the ViewBag) with a direct call to DateTime.Now. Sure enough, the same DateTime is printed each time in updateMap() (e.g., 2/11/2016+5:24:42+PM)
I've tried disabling caching, and changing the HTML method to Post, in my AjaxOptions.
In the Parent View (changing the ListBox selection submits the form):
#model string
#{
ViewBag.Title = "Project List";
AjaxOptions ajaxOpts = new AjaxOptions
{
UpdateTargetId = "tableBody",
OnSuccess = "updateMap",
HttpMethod = "Post",
AllowCache = false
};
}
#using (Ajax.BeginForm("GetProjectsData", ajaxOpts))
{
<fieldset>
<legend>Project State</legend>
<div class="editor-field">
#Html.ListBox("selectedStates", ViewBag.StatesList as MultiSelectList,
new { #class = "chzn-select", data_placeholder = "Choose States...", style = "width:350px;", onchange = "$(this.form).submit();" })
</div>
</fieldset>
}
<table class="table">
<thead>
<tr>
<th>
Project Name
</th>
<th>
Project Firm
</th>
<th>
Project Location
</th>
<th>
Building Type
</th>
<th>
Project Budget
</th>
<th></th>
</tr>
</thead>
<tbody id="tableBody">
#Html.Action("GetProjectsData", new { selectedStates = Model })
</tbody>
</table>
<script>
function updateMap() {
var jsonData = $("#geoJsonData").attr("data-json");
var decoded = decodeURIComponent(jsonData);
console.log(decoded); // always prints same value
}
</script>
The partial view:
#model IEnumerable<OurModel>
<div id="geoJsonData" data-json="#Url.Encode(DateTime.Now.ToString())"></div>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.COMPANY_NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.STATE)
</td>
<td>
#Html.DisplayFor(modelItem => item.BUILDING_TYPE)
</td>
<td>
#Html.DisplayFor(modelItem => item.BUDGET_AMT)
</td>
</tr>
}
I'm hesitant to jettison the MVC helper classes' pattern of returning a partial view and instead manually render a view into a JSON object. Why is the updated tablebody visible on screen, but when jQuery requests the div element it always has the same data?
Interesting...replacing the div with a good old hidden input element worked. Now fresh data is retrieved each time.
This
<div id="geoJsonData" data-json="#Url.Encode(DateTime.Now.ToString())"></div>
Became this
<input id="geoJsonData" type="hidden" value="#Url.Encode(DateTime.Now.ToString())" />
I wonder why the data-json in the div remained "stale" while the value of the input field did the trick?
I have a table with several columns. The first column contains a location name and the last column contains a delete button. When I click any of the delete buttons, it currently displays the confirmation message "Are you sure you want to delete the location:" I want the end of the confirmation message to display the location name.
Here are the relevant bits in my view:
#using (Ajax.BeginForm("FirstAjax", "Configuration", null, new AjaxOptions()
{
Confirm = "Are you sure you want to delete the location:\n",
HttpMethod = "POST",
OnFailure = "deleteFailed",
UpdateTargetId = "CustomLocations"
},
new { #id = "deleteLocation" }
))
{
<div id="reportTblDiv">
<table id="CustomLocations">
<tbody>
#foreach (var location in Model.LocationList)
{
<tr>
<td class="location">#location.LocationName</td>
<td>
<input type="submit" title=#Model.DeleteButton name="#location.LocationId" value="#Model.DeleteButton" />
</td>
</tr>
}
</tbody>
</table>
</div>
}
How can I access the correct element in Model.LocationList from the line beginning with Confirm?
Set the id of the first to be the same as the name as the second . Add a handle to the submit in javascript to update the confirm message:
<td id=#location.LocationId class="location">#location.LocationName</td>
<td>
<input type="submit" title=#Model.DeleteButton name="#location.LocationId" value="#Model.DeleteButton" onclick="return btnDeleteClicked(this);"/>
</td>
<script>
function btnDeleteClicked(btnObject){
var tLocation=$(btnObject).attr('name');
var tCurrentMessage=$("#deleteLocation").data('ajax-confirm');
$("#deleteLocation").data('ajax-confirm',tCurrentMessage + tLocation);
return true;
}
</script>
I am developing a shopping cart website in MVC3 with razor. Below code is view code, in which I am showing multiple products, each product has quantity text box and one submit button. So, in controller how would I know which submit button is called by user and how to read text from Label?
<table>
<tr>
#foreach (System.Data.DataRow i in Model.dt.Rows )
{
using (#Html.BeginForm("addtocart", "Chocolatier",FormMethod.Post,null))
{
<tr><td> <img src=" #Url.Content("~/Content/abc.gif") " alt="Imge" height ="40" width ="40"/></td></tr>
foreach (System.Data.DataColumn j in Model.dt.Columns)
{
lbl = "lbl";
lbl = lbl+#cnt.ToString();
if(j.ToString().ToLower ().Equals ("name"))
{
<tr> <td style="width : 200px"><h5>#j.ToString()</h5><label id="#lbl" >#i[j].ToString()</label></td></tr>
}
if(j.ToString().ToLower ().Equals ("description"))
{
<tr> <td style="width : 200px"><h5>#j.ToString()</h5>#i[j].ToString())</td></tr>
}
if(j.ToString().ToLower ().Equals ("price"))
{
<tr> <td style="width : 200px"><h5>#j.ToString()</h5>#Html.LabelFor(m=>m.prod_price,i[j].ToString())</td></tr>
}
}
cnt += 1;
<td>Enter quantity : #Html.TextBoxFor(m=>m.prod_quantity)</td>
<tr><td><input type ="submit" value="Add to cart" id="#cnt"/></td></tr>
<tr> <td>__________________________________________________________________________</td></tr>
}
}
</tr>
</table>
I am trying to use a partial view to represent rows of a table in my project. I currently have
<table>
<thead>
<tr>
<th >
Column 1
</th>
<th >
Column 2
</th>
<th >
Column 3
</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</tbody>
</table>
In my partial view I have this
#using (Ajax.BeginForm("SaveStuff", "Whatever",
new { id = #Model.Id }, new AjaxOptions()
{
HttpMethod = "Post",
OnSuccess = "Success"
}))
{
#Html.HiddenFor(m => m.Id)
<tr>
<td>
#Html.Label("Col1", Model.Col1)
</td>
<td>
#Html.TextBox("Number", Model.Number)
</td>
<td>
<input type="submit" id='submit-#Model.Id'/>
</td>
</tr>
}
How can I make this work?
You can put a form inside a table cell, but you can't have the form inside a tbody element, or spanning multiple columns. So there are three options:
Use a CSS layout instead of a table, or use divs with CSS display set to "table". (for example)
Put the entire form (TextBox and Submit) inside a td
Put another table inside the td element
I'd recommend #1 -- use a CSS layout to construct the table, since it's difficult to style table tags:
Main
<div class="table">
<div class="header-row">
<div class="header-cell">Column 1</th>
<div class="header-cell">Column 2</th>
<div class="header-cell">Column 3</th>
</div>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</div>
Partial
#using (Ajax.BeginForm(
actionName: "SaveStuff",
controllerName: "Whatever",
routeValues: new { id = #Model.Id },
ajaxOptions: new AjaxOptions
{
HttpMethod = "Post",
OnSuccess = "Success"
},
htmlAttributes: new { #class = "row" }
))
{
<div class="cell">
#Html.HiddenFor(m => m.Id)
</div>
<div class="cell">
#Html.Label("Col1", Model.Col1)
</div>
<div class="cell">
#Html.TextBox("Number", Model.Number)
</div>
<div class="cell">
<input type="submit" id='submit-#Model.Id'/>
</div>
}
CSS
.table { display: table; }
.header-row, row { display: table-row; }
.header-cell, cell { display: table-cell; }
You have several issues here. First, as dbaseman mentions, you can't place forms within the structure of a table and have it be legal HTML. It may work, or it might not, and even if it does work, you can't guarantee it will continue to work.
I would instead wrap your table in the form, and then on the post figure out which button was pressed based on its value and/or index.
I would strongly advise against using css tables for tabular data. It's just not semantically correct.
Another possible solution is, instead of using the Ajax.BeginForm, instead use jQuery $.ajax and then you can select a row of data in javascript to post to the server.
I have a button "btnGetAddress" on my razor page .On clik of this button,I am calling a Jquery to get my addressItmes object to be displayed on to my View page.
On clicking "btnGetAddress" I am able to hit my "JsonResult GetAddresses()" and retrieve records within my Jquery (success: function (data)).and this data has multiple address records. But I do not know how to take this data to my view .Please help me to get my data to be displayed on to my View
When my page get loaded,the user will see only the "btnGetAddress" button .When the user click on the btnGetAddress, it will call the Jquery Click function to fetch all address records from database and display each set of records on the page
$("#btnGetAddress").click(function () {
debugger;
var selected = $("#ddlType").val();
if (selected == "")
{ selected = 0; }
var dataToSend = {
SelectedTypeId: selected
};
$.ajax({
type: "GET",
url: '#Url.Action("GetAddresses", "Content")',
data: { SelectedTypeId: selected },
success: function (data) {
debugger;
},
error: function (error) {
var verr = error;
alert(verr);
}
});
pasted below is my JsonResult GetAddresses() which gets called to retrieve addressItems
public JsonResult GetAddresses()
{
model.AddressItems = AddressService.RetrieveAllAddress();
// My AddressItems is of type IEnumerable<AddressItems>
return Json(model.AddressItems, JsonRequestBehavior.AllowGet);
}
Here is my razor View Page where the address records are to be displayed.
........................
<input type="submit" id="btnGetAddress" name="btnSubmit" value="Show Addresses" />
if (!UtilityHelper.IsNullOrEmpty(Model.AddressItems))
{
foreach (var AddressRecord in Model.AddressItems)
{
<fieldset >
<legend style="padding-top: 10px; font-size: small;">Address Queue(#Model.NumRecords)
</legend>
<table>
<tr>
<td>
<span>Index</span>
</td>
<td>
</td>
<td>
<input type="submit" id="btnDelete" name="btnSubmit" value="X" />
<br />
</td>
</tr>
<tr>
<td>
<span>Address1</span>
<br />
</td>
<td>
#Html.EditorFor(model => AddressRecord.Address )
#Html.ValidationMessageFor(model => AddressRecord.Address)
</td>
</tr>
<tr>
<td>
<span>Description</span>
<br />
</td>
<td>
#Html.EditorFor(model => AddressRecord.Description)
#Html.ValidationMessageFor(model => AddressRecord.Description)
</td>
</tr>
<tr>
<td>
<input type="submit" id="btnSave" name="btnSubmit" value="Save" />
</td>
<td>
<input type="submit" id="btnDelete" name="btnSubmit" value="Delete" />
</td>
</tr>
</table>
</fieldset>
}
}
<fieldset>
Or is there any better way to achieve my objective?
Since you are getting the data via ajax you should use a jquery template engine. Basically get the data the way you are and on success you do something like
<script language="javascript" type="text/javascript">
$(function () {
$.getJSON("/getprojects", "", function (data) {
$("#projectsTemplate").tmpl(data).appendTo("#projectsList");
});
});
</script>
<script id="projectsTemplate" type="text/html">
<section>
<header><h2>Projects</h2></header>
<table id="projects">
<th>Name</th>
{{tmpl(items) "#projectRowTemplate"}}
</table>
</section>
</script>
<script id="projectRowTemplate" type="x-jquery-tmpl">
<tr>
<td>${name}</td>
</tr>
</script>
<div id="projectsList"></div>
Now each template engine is different but the above gives you an idea of what you can do
If you want to return JSON object in your controller, you are going have to turn your view into a string and return it as part of the message. If you google there are some methods out there that can do this.
However, I really think that's the hard way, why not take the data you get from the JSON in the controller and put it in a MODEL and then return your VIEW with the model data passed in. I think that's the easier way.