Displaying image from database in webpages - c#

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...

Related

See ASP.NET MVC Index page in C# be populated with data from model without ID in the URL

In my application I am using Entity Framework 6 and ASP.NET MVC in C#.
I have a table that has records that I plan on populating my Index page with. How do I populate the index page without having the system add the id of the record to the URL. See example below. I have already looked at routing but with adding custom route you are forced to add more text to the url when all I want is the URL to show up as example.com. I don't want and don't need example.com/MenuRecords/Details/20 for a user to see.
So example.com should load the following data from the model below in the index view of the HomeController.
index.cshtml page calling the model data shown below:
#model example.Models.tblMenuRecords
#Model.ThisWeeksBestDrink
#Model.ThisWeeksBestAppetizer
#Model.ThisWeeksBestDesert
#Model.ThisWeeksBestLunchSpecial
This is the cntroller action method:
public ActionResult Index()
{
return View();
}
How do I get that to work properly for the Index page? Since this is the home page that is calling data from a model I cannot have the URL have anything other than example.com .... but I do understand that when calling data from a model you do need some sort of ID but I just do not really understand how to do that.
I know that there is the route config that includes this default route that allows you to show only the name of the domain...But how is this done when you are trying to load data from the database.
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
Is this the correct way to pass an instance of the tblMenuRecords to the view?
public ActionResult Index()
{
tblMenuRecords tblMenuRecords = db.tblMenuRecords();
return View(tblMenuRecords);
}
I think you have to fix the action
public ActionResult Index()
{
tblMenuRecords tblMenuRecords = db.tblMenuRecords.FirstOrDefault();
return View(tblMenuRecords);
}
I think your view is missed with model. View code should be like below
#model Models.MenuRecords
#{
ViewBag.Title = "Menu Records";
}
<h2>Details</h2>
<div>
<h4>Menus</h4>
<hr />
<table>
<tr>
<td>
#Html.DisplayFor(model => model.ThisWeeksBestDrink)
</td>
<td>
#Html.DisplayFor(model => model.ThisWeeksBestLunchSpecial)
</td>
</tr>
</table>
</div>
I hope, it will help you.

How to get YouTube URL from Database and display Video In view

I need to Get youtube URL which is stored in database and display in the view. While saving into the database I am saving the complete URL like "https://www.youtube.com/watch?v=is0A9x8q_zA".
But with below code nothing display. I cannot store only ID (is0A9x8q_zA) from the above URL into the database, because I am storing different type of URL inside the same table like youtube url, blogs URL, tutorial URLs.
How do I display youtube video? Is there a better option?
My View code :
<div class="col-md-2">
#foreach (var item in group)
{
if (item.urltype == "YouTube")
{
<iframe src=#Url.Content(item.url) width="400" frameborder="0"></iframe>
}
</div>
In order to embed Youtube video, you need to provide different URL. You can use that URL from the database to get the id and apply a different format to a "src" attribute
Your view file
<div class="col-md-2">
#foreach (var item in group)
{
if (item.urltype == "YouTube")
{
//get URI first
var videoURI = new URI(item.url);
//get video id from URI
var videoId = var videoId = HttpUtility.ParseQueryString(videoUrl.Query).Get("v");
<iframe src="https://www.youtube.com/embed/#videoId" width="400" frameborder="0"></iframe>
}
</div>
I hope this helps.
Check generated HTML (Browser Dev tools : Inspect element) to make sure URL is getting loaded properly.
Also, https://developers.google.com/youtube/iframe_api_reference
has an example. Hope it helps.

Build Menu Items From Controller

I am creating HTML Menus from controller. Menus are stored in database and I make html tag as below :
foreach (UIMenuModel item in list)
{
if (item.Controller != "Home")
{
string line = string.Format(#"<li><a asp-area=""{0}"" asp-controller=""{1}"" id=""{1}""
asp-action = ""{2}"" style = ""font-size:16px;;"" > {3} </a></li>", item.Area, item.Controller, item.Action, item.LinkText);
sb.Append(line);
}
}
which gives me below HTML :
<li><a asp-area="" asp-controller="CrossApproval" id="CrossApproval" asp-action="Index" style="font-size:16px;;"> Cross Approval </a></li>
Other Menu Item, Which is written in HTML itself, gives below HTML in browser.
<li><a id="CrossRequest" style="font-size:16px" href="/CrossRequest">Cross Request</a></li>
On UI, it looks perfect. However, I am not able to click and navigate to desired controller and action methods. Can someone please help me to identify while this anchor tag is not allowing me to navigate.
Use RazorLightEngine to convert plain string as rendered Razor string:
string content = "Hello #Model.Name. Welcome to #Model.Title repository";
var model = new
{
Name = "John Doe",
Title = "RazorLight"
};
var engine = new RazorLightEngine();
string result = engine.ParseString(content, model);
And then add it any place in razor view like encoded string
<div>
#Html.Raw(result)
</div>
As posted in Question, HTML with href was working fine. So, I decided to mimic the same behaviour from the controller and changed my code as below :
string line = string.Format(#"<li><a asp-area=""{0}"" id=""{1}"" href=""/{1}/{2}""
style=""font-size:16px"">{3}</a></li>", item.Area, item.Controller, item.Action, item.LinkText);
This generated a link which I can click and navigate.

Problems with Charting Display

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" />

Reloading Partial View with JQuery

I have a page with a video at the top and a list of videos you can choose from. Currently, clicking a link in the video list will reload the entire page. I need it to only refresh the partial view I have containing the video at the top of the page.
I saw several posts here on SO showing how to reload partial views with JQuery, but couldn't get it to work correctly in my situation. I'm unsure how to pass the correct id of the video along.
Controller:
public ActionResult Videos(int topVideo = 0)
{
VideosModel model = new VideosModel();
model.Videos = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).ToList();
if (topVideo == 0)
model.TopVideo = model.Videos.First();
else
{
model.TopVideo = model.Videos.Where(x => x.StatsVideoId == topVideo).FirstOrDefault();
if (model.TopVideo == null)
model.TopVideo = model.Videos.First();
}
return View(model);
}
View:
#model Project.Models.VideosModel
<section class="videos">
<div id="top_video">
#{Html.RenderPartial("StatsVideo", Model.TopVideo);}
</div>
<ul>
#foreach (var item in Model.Videos)
{
<li>
<div class="videoList">
<a href ="#Url.Action("Videos", "Home", new { topVideo = item.StatsVideoId })">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
</li>
}
</ul>
</section>
If there's any more information needed, please let me know.
After several hours of bashing my head against the wall, I got it to work! Just as a reference to anyone else in the future who's viewing this article, here's how I got it to work:
I set the onclick of the link to point to a javascript method, passing in the id of the video as a parameter:
#foreach (var item in Model.Videos)
{
<li>
<div class="videoList">
<a href ="#" onclick="updateTopVideo(#item.StatsVideoId)">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
</li>
}
And then I included this script in the view at the bottom:
<script>
var updateTopVideo = function (itemId) {
var url = '#Url.Content("~/Home/StatsVideo/")';
url = url + itemId;
$.get(url, "", callBack, "html");
};
var callBack = function (response) {
$('#top_video').html(response);
};
</script>
Finally, I added a method to my controller that would return the partial view needed for the video at the top of the screen:
public ActionResult StatsVideo(int Id)
{
IStatsVideo vid = StatsVideoService.GetEntity(new Lookup(TableStatsVideo.StatsVideoId, Id));
if (vid == null)
vid = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).FirstOrDefault();
return PartialView(vid);
}
This code should be fairly easy to understand. Basically, the onclick calls the first javascript method, which then calls the controller. The controller builds the partial view and returns it. The first javascript method passes it to the second javascript method which sets the html of the div "top_video" to be the returned partial view.
If anything doesn't make sense, or anyone's having trouble with this in the future, let me know and I'll do my best to offer some help.
I think there may be several confusing and inconsistent elements here.
First, you are returning a full view instead of a partial view. This reloads all containing elements, not just the part that is relevant to your partial view.
Second, you are using Url.Action, which only generates the url. I would recommend using Ajax.ActionLink, which allows you to do fully ajax calls, refreshing the content of your partial div and updating a target div element.
instead of:
<div class="videoList">
<a href ="#Url.Action("Videos", "Home", new { topVideo = item.StatsVideoId })">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
try the more modern solution
<div class="videoList">
#Ajax.ActionLink(
"Videos",
"Home",
"new { topVideo = item.StatsVideoId },
new AjaxOptions {
HttpMethod = "GET",
OnSuccess = "handleSuccess"
}
)
</div>
This way you can be very specific on what you want each link to do, and you can pass along multiple parameters as well as define a callback function. You can also use "UpdateTargetId" in your ajax options to load your newly refreshed partial view into a DOM element.
You can remove the around the image and just store the url generated by the Url.Action in a data-href attribute.
Then you can use the jquery load method to load the data:
$(".videolist>img").click(function () {
$("#content").load($(this).data("href"));
});
I created a fiddle that loads content dynamically here, so you can play with it if you want: http://jsfiddle.net/bTsLV/1/

Categories

Resources