Problems with Charting Display - c#

I am having problems getting pie charts to display in my views correctly. With the code below, I have confirmed that bytes are being successfully written to the model and passed to the view. I have even confirmed that I can save the pie chart to a PNG file within a directory from the view, but every time I attempt to display the pie chart in the browser, no image is displayed.
You will see that I'm using an Index view with a Partial view for the Pie Chart. The plan is to present multiple partial views into the Index view.
I'm hoping someone can help me get past this. Thanks in advance.
Model:
public byte[] PieChartBytes { get; set; }
public class StatsForPieChart
{
public string dest { get; set; }
public long recordCount { get; set; }
}
Controller:
public ActionResult _DisplayPieChart (model.ViewModel model)
{
ArrayList xSeriesList = new ArrayList();
ArrayList ySeriesList = new ArrayList();
foreach (var item in model.statsforPieChart)
{
xSeriesList.Add(item.dest);
sSeriesList.Add(item.recordCount);
}
model.PieChartBytes = new Chart(width:800, height:600, theme: ChartThem.Blue)
.AddTitle("Title")
.AddLegend()
.AddSeries(
name: "Name",
chartType: "Pie",
xValue: xSeriesList,
yValues: ySeriesList)
.GetBytes("png");
return PartialView(model);
}
Index View:
Html.RenderAction("_DisplayPieChart", new { model = Model });
Pie Chart View:
#{
//the "Save" code is only used to prove the file bytes have been successfully passed and the image is present in the view:
string sImagePath = Server.MapPath("~") + "Content\\" + Guid.NewGuid().ToString + ".png"
WebImage myImage = new WebImage(Model.PieChartBytes);
myImage.Save(sImagePath);
}
<div class="text-center">
<img src="#sImagePath" /> //works in debug mode, but gets blocked on web server - not desired solution.
<img src="#myImage" /> //desired solution, but produces no image.
</div>

Where the image is just a string of bytes and not a file stored on a server anywhere, you need to prefix the bytes like this:
<img src="data:image/png;base64,#myImage" />
This is called a Data URL or Data URI
Additionally, though, I'm not sure you need to use WebImage here. You're already calling GetBytes() on the Chart object. That should return the bytes that you can use to display the image:
<img src="data:image/png;base64,#Model.PieChartBytes" />
Based on #Anonymous3521's comment, this code worked:
Controller:
var base64 = Convert.ToBase64String(Model.PieChartBytes);
var imgSrc = String.Format("data:image/png;base64,{0}", base64);
View:
<img src="#imgSrc" />

Related

Trying to call and bind image in img src tag from server in mvc

Hi i'm trying to bind image in img tag in mvc .this tag is used in asp.net like this in the same way i want to bind image in MVC/
eg
ASP.net
<img alt="User Image" width="80px" height="80px" class="img img-thumbnail" src='<%="http://196.0.2.201/p001.ashx?pf=YY&cid="+Session[CommonConstants.SESSION_USER_ID] %>'/>
in mvc
I want to pass #ViewBag.session as parameter instead of Session[CommonConstants.SESSION_USER_ID] how to achieve it in Mvc any idea would be appreciated.
If you're using MVC why not base64 the image on the server while the page is being constructed and embed that in the image src for example with Razor:
<img src="data:image/jpeg;base64, #Model.Base64Image">
This way any logic used for generating the image is part of the same controller logic that is building your page.
Step by step:
your razor page will have a #model ViewModel Directive at the top and an image element somewhere that you are populating as above, the jpeg part can be any image type must must match the type that is being encoded.
your view model should have a string property in this case called Base64Image.
your controller should have a part that gets and converts the image e.g.
public IActionResult Index()
{
var model = new ViewModel();
// important thing here is to convert the image into a byte array:
var imageBytes = System.IO.File.ReadAllBytes(#"image.jpeg");
// Convert byte array to Base64 String
model.Base64Image = Convert.ToBase64String(imageBytes);
// return View model with base64 encoded image to page
return View(model);
}
the rendered page at the client side will have an image element something like this.
<img src="data:image/jpeg;base64, TWFuIGlzIGRpc3RpbmdR== ">
the base64 encoding will be hundreds of characters long.
Doing it this way the client doesn't need to make a second call to get the image its already in the page. What you're trying to do is define an endpoint that the client will call on to get the image.
Declare a new model
public class ModelImg
{
public int MyProperty1 { get; set; }
public bool MyProperty2 { get; set; }
public string Img { get; set; }
}
use your object in controller :
ModelImg model = new ModelImg(){Img = #"MyImgAsString",MyProperty1 = 1,MyProperty2 = true};
Assign your object or your img directly to a ViewData in your controller view:
ViewData["Img"] = model.Img;
In your View assign your src :
<img alt="User Image" width="80px" height="80px" class="img img-thumbnail" src='ViewData["Img"]'/>

Display a collection of images after each upload MVC

Have gone through the first 3 pages of Google and still can't get to the bottom of this. I have a controller which I am using to upload images:
[HttpPost]
[Authorize(Roles = "Admin,Tradesman,Customer")]
public ActionResult UploadFile(HttpPostedFileBase file)
{
// to do: ensure only valid file types are sent
try
{
if (file.ContentLength > 0)
{
using (var ctx = new ApplicationDbContext())
{
if (ModelState.IsValid)
{
// Need to check we have a current UserId and JobId before we go any furthur
var profileData = Session["UserProfile"] as UserProfileSessionData;
if (profileData.JobIdGuid.ToString().Length != 36)
{
// to do: something went horribly wrong! Redirect back to main view
}
if (profileData.UserIdGuid.ToString().Length != 36)
{
// to do: something went horribly wrong! Redirect back to main view
}
var photo = new Photos();
photo.Guid = Guid.NewGuid();
photo.Url = Server.MapPath("~/Images/2017");
photo.Extension = Path.GetExtension(file.FileName);
photo.JobGuid = profileData.JobIdGuid;
photo.UserIdGuid = profileData.UserIdGuid;
photo.Timestamp = DateTime.Now;
ctx.Photo.Add(photo);
ctx.SaveChanges();
string _path = Path.Combine(photo.Url, photo.Guid.ToString() + photo.Extension);
file.SaveAs(_path);
}
}
}
ViewBag.Message = "File Uploaded Successfully.";
return View();
}
catch
{
ViewBag.Message = "File upload failed.";
return View();
}
}
Each image is saved to a given location, the location saved to the db, happy days. Want I want though is for my images to be displayed on the same page after each upload. The model is as you'd expect just Id, Guid, Url, Extension, UserId, Timestamp.
Here is the view that uploads the images:
#{
ViewBag.Title = "UploadFile";
}
<h2>Upload File</h2>
#using (Html.BeginForm("UploadFile", "Job", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox("file", "", new { type = "file" }) 
<br />
<input type="submit" value="Next" />
#ViewBag.Message
</div>  
// to do display the images uploaded
}
Is it possible to just have some kind of for...each and have each displayed at the bottom? Anyone know how to do this! Btw this is my first C# MVC app so if this is daft question I apologise. Thanks in advance :)
You should be following the P-R-G pattern. After successfully saving the data in your HttpPost action method, you should do a redirect to your GET action method, where you will read the data you need and pass it to the view where you will display it.
I would create a view model to represent each image and use that
public class ProfileImageVm
{
public string FileName { set;get;}
public DateTime CreatedTime { set;get;}
}
Now, for your save partin your http post action method, i would advise you to not save the physical location of the file in the table. The Server.MapPath returns the physical path. Storing that is unnecessary. What if you decide to move the location to some other directory in the server tomorrow? You could simply store the unique fileName. Let's assume that you want to store all the files in the Images/2017 in app root ,you can use Server.MapPath to get the physical location so that you can store the file in disk, but do not use that to store your table record.
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
photo.Url = fileName ;
photo.Extension = Path.GetExtension(file.FileName);
With this code, it is simply storing the file name(without extension) as it is, not a unique name. That means, if you are uploading a second file with same name, it will overwrite the first one in disk. If you want to generate a unique file name, use the GetUniqueName method from this post.
Now in the GET action method, you read the Photos collection and create a list of our view model from that.
public ActionResult UploadFile()
{
var list= ctx.Photos
.Select(x=>new ProfileImageVm { FileName=x.Url + x.Extension ,
CreatedTime = x.Timestamp })
.ToList();
return View(list);
}
Now in your UploadFile view will be strongly typed to a list of ProfileImageVm, you can loop through the model data and render the images.
#model List<ProfileImageVm>
#using (Html.BeginForm("UploadFile", "Job", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.TextBox("file", "", new { type = "file" })
<input type="submit" value="Next" />
}
<h3>Images</h3>
#foreach(var item in Model)
{
<img src="~/Images/2017/#item.FileName" />
<p>Uploaded at #item.CreatedTime </p>
}
Now, after successfully saving the photo and the record in table, you will return a redirect response to the GET action.
file.SaveAs(_path);
return RedirectToAction("Upload","Job");
You can also keep the base path ~/Images/2017 in a config settings/constant and use that across your app so if you ever decide to change it to ~/Images/profilepics, there is only one place you have to change.

What is the diff between normal file upload and create thumbnails of an images using mvc?

Hi i am totally confused with file uploading. First of all any one explain me what is the difference between normal file uplaod and create thumbnail for image and save that path in db.
I checked the path of both normal and thumbnail. Moreover same only but i donno what is the differene between these two types of uplaod?.Can any one explain me these difference?
I tried both types. I paste that code here and any one tell me the difference between two types.
1) Normal Uplaod using AJAX
View
#{
ViewBag.Title = "FileUpload";
}
<head>
<title></title>
</head>
<body>
<input type="file" id="FileUpload1" />
<input type="button" id="btnUpload" value="Upload Files" />
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
// Adding one more key to FormData object
fileData.append('username', 'Manas');
$.ajax({
url: '/ImageUplaod/UploadFiles',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
});
});
</script>
Controller
public ActionResult FileUpload()
{
return View();
}
[HttpPost]
public ActionResult UploadFiles()
{
// Checking no of files injected in Request object
if (Request.Files.Count > 0)
{
try
{
// Get all files from Request object
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
//string path = AppDomain.CurrentDomain.BaseDirectory + "Uploads/";
//string filename = Path.GetFileName(Request.Files[i].FileName);
HttpPostedFileBase file = files[i];
string fname;
// Checking for Internet Explorer
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
// Get the complete folder path and store the file inside it.
fname = Path.Combine(Server.MapPath("~/Uploads/"), fname);
file.SaveAs(fname);
var imageupload = new imageupload();
imageupload.ImageUplaod = fname;
db.imageuploads.Add(imageupload);
db.SaveChanges();
}
// Returns message that successfully uploaded
return Json("File Uploaded Successfully!");
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
2) Craete Thumbnails for image using MVC and save that path in db
Model
public class ImageUploadModels
{
[Key]
public int ImgageID
{
get;
set;
}
[Required]
public string ImagePath
{
get;
set;
}
}
Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult ImageUploadThumnail(ImageUploadModels image, HttpPostedFileBase file)
{
try {
if (file != null)
{
var fileName = Path.GetFileName(file.FileName);
var thumbName = fileName.Split('.').ElementAt(0) + "_thumb." + fileName.Split('.').ElementAt(1);
fileName = Path.Combine(Server.MapPath("/Images"), fileName);
thumbName = Path.Combine(Server.MapPath("/Images"), thumbName);
image.ImagePath = fileName; //to store into database, if we use DbContext
file.SaveAs(fileName);
Image img = Image.FromFile(fileName);
int imgHeight = 100;
int imgWidth = 100;
if (img.Width < img.Height)
{
//portrait image
imgHeight = 100;
var imgRatio = (float) imgHeight / (float) img.Height;
imgWidth = Convert.ToInt32(img.Height * imgRatio);
}
else if(img.Height < img.Width)
{
//landscape image
imgWidth = 100;
var imgRatio = (float) imgWidth / (float) img.Width;
imgHeight = Convert.ToInt32(img.Height * imgRatio);
}
Image thumb = img.GetThumbnailImage(imgWidth, imgHeight, () => false, IntPtr.Zero);
thumb.Save(thumbName);
var imageupload = new imageupload();
imageupload.ImageUplaod = thumbName;
db.imageuploads.Add(imageupload);
db.SaveChanges();
}
return View();
} catch (Exception ex)
{
ViewBag.Message = ex.Message.ToString();
return View();
}
}
View
#model ImageUpload.Models.ImageUploadModels
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("ImageUploadThumnail", "ImageUplaod", null, FormMethod.Post, new
{
enctype = "multipart/form-data"
})) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true);
<fieldset> <legend> Image </legend>
<div class = "editor-label" >
#Html.LabelFor(model => model.ImagePath)
</div>
<div class = "editor-field">
<input id = "ImagePath" title = "Upload an image" type = "file" name = "file"/>
</div>
<p> <input type = "submit" value = "Upload"/>
</p>
</fieldset>
}
Now i posted two typesof upload what i tried . i want to know the difference between these two types and i want to know which is better to upload image in server after deploying the project. And also any one tell me how to create thumbnails for image using ajax . Here in above mention method i didn't use ajax for thumbnails . But i need to uplaod and save the path of the thumnails image using ajax. I tried my level best to explain my issue.Any one understand my issue and give me solution for this problem
Advance Thanks..
First of all any one explain me what is the difference between normal file uplaod and create thumbnail for image and save that path in db.
What is a thumbnail image?
It is just an image that looks like another image but with a smaller file size.
Advantages of using thumbnails on web
This can play a major role in web applications. When you visit a web page, like this one, if there are images on the page they need to be brought to your computer so your browser can show them to you. In other words, they need to be downloaded to your computer. Web sites developed with that in mind, will just include a low quality, small size image of the actual image and send that when you view the page. Then when you click on the image, for example, if you want to look at the image more closely, then the browser will make another request to the server and get the high quality image.
This technique makes the initial loading (downloading to be exact) fast so the user is not setting there waiting for all the big images if all they want to do is read something.
I am not sure if you are using uploading incorrectly but uploading is the opposite of downloading. When you visit a page, you are essentially downloading the page (unless you have already visited the page and the browser has cached it.) Therefore, uploading is you sending something to the server and I am not sure how sending something to the server will benefit from thumbnails.
I think what you may be speaking of is having a thumbnail image and the path to the high quality image of the thumbnail is stored in the db with thumbnail data. You send the thumbnail when someone requests it, then if they want the higher quality image, you get the path from the database and serve the high quality image.
This technique is highly in use by commerce sites. For example, when you are browsing Amazon, eBay, car dealerships the little images are low quality but enough to give you a good idea of what the product is. Once you click it, then the better quality images are retrieved.
Advantages of using thumbnails in other type of applications
Web is not the only place this can be used. I worked on an iPad application and we used the same technique. However, instead of clicking the image we were waiting to see if the user will zoom (pinch and zoom) on the image. As soon as the user zoomed in, we would get a higher quality image. If they zoomed in again, we would get even a higher quality image. We had 4 different levels of quality for each image.
In conclusion there are two advantages to using thumbnails:
Faster load (performance)
Bandwidth-smaller size images (especially important to mobile users because data will cost them $$$)
Here is a page with thumbnails. And here are the better quality images of one of the thumbnails.

Displaying image from database in webpages

I am creating a website in visual studio. I want retrieve and display image (of datatype image from sql server database) in webpage. I have a .cshtml page and got the following code to display some of the fields of the table. I am able to display everything except the image datatype column. I am using razor syntax.
MY code
#{
var db1 = Database.Open("database1");
var selectQueryString = "SELECT * FROM Recipes ORDER BY date";
}
<div class="left-content">
<h5>Recent Posts</h5>
<table>
<tbody>
#foreach(var row in db1.Query(selectQueryString))
{
<tr>
<td>#row.image</td>
<td>#row.title</td>
<td>#row.description</td>
</tr>
}
</tbody>
</table>
This is my output in the webpage:
Recent Posts
System.Byte[] testaspform ufegewu
System.Byte[] testone qfeyqo
System.Byte[] testtwo oadiufh
As you could see the first column show System.Byte[] instead of the image.
You can't render an image in an html file without using an <img/> tag.
What you can do is place an <img> tag and create a FileContentResult in your Controller and call it in the source of your tag using the #Url.Action() helper...
==Code==
In your HTML:
<img src="#Url.Action("ProcessImage", routeValues: new { imageToProcess = row.image })" />
In your Controller:
public FileContentResult ProcessImage(byte[] imageToProcess)
{
return new FileContentResult(imageToProcess, "image/jpeg");
}
...
Make sure to place the ProccessImage method in the same controller as the one that holds the ActionMethod that renders the view you are in, if that's not the case, then use:
HTML:
<img src="#Url.Action("ProcessImage", routeValues: new { controller = "{CONTROLLER_NAME}", imageToProcess = row.image })" />
I didn't build the code given above, so you might have to resolve any typo/syntax error...

set src property in view to a url outside of the MVC3 project

I am trying to create an application that will display images that are stored locally on the webserver. Here is what I have in my view, note that "entry" are absolute addresses like "C:\Images\Image1.jpg". However, when I run it, I get "Not allowed to load local resource: file:///C:/Images/ImageName.jpg" in the console log. So maybe it tries to access the image on the client. How do I tell my view to access the local webserver path and not look for the image source on the client? Please note that moving the images into project directory is not an option, because the images are stored on a different drive on the webserver.
<!-- language: c# -->
#model List<String>
<div style="height: 500px; overflow:scroll;">
<h2>
ScreenShots for testMachine</h2>
#foreach (var entry in Model)
{
<div class="nailthumb-container square-thumb">
<img alt="screenshot" src="#Url.Content(entry)" />
</div>
}
</div>
You cannot directly serve images outside of your ASP.NET MVC 3 application to the client. That would be a huge security vulnerability if the client could access arbitrary files on your server.
You will need to write a controller action that will return them and then point your src property of your <img> tags to this controller action.
public class ImagesController: Controller
{
public ActionResult SomeImage()
{
return File(#"C:\Images\foo.jpg", "image/jpeg");
}
}
and inside your view:
<img src="#Url.Action("SomeImage", "Images")" alt="" />
You could also pass the image name as parameter to the controller action:
public class ImagesController: Controller
{
public ActionResult SomeImage(string imageName)
{
var root = #"C:\Images\";
var path = Path.Combine(root, imageName);
path = Path.GetFullPath(path);
if (!path.StartsWith(root))
{
// Ensure that we are serving file only inside the root folder
// and block requests outside like "../web.config"
throw new HttpException(403, "Forbidden");
}
return File(path, "image/jpeg");
}
}
and in your view:
<img src="#Url.Action("SomeImage", "Images", new { image = "foo.jpg" })" alt="" />
The above code was useful for me, with a change like this
System.Web.UI.Page page = new System.Web.UI.Page();
string filePath = page.Server.MapPath("~/Log/" + fileName);
if (!filePath.StartsWith(filePath))
{
throw new HttpException(403, "Forbidden");
}
return File(filePath, "Content-Disposition", "attachment;filename=TableImportLog.csv");
}
the file thrown to the user is with file name like this "attachment;filename=TableImportLog.csv", but i want the file name as "TableErrorLog.csv"
need help for the same!

Categories

Resources