Display image from database in _layout in mvc4 - c#

Hi all I am having my _layout as follows which works as per my requirement, but here there are couple of things I got strucked i.e I would like to display the corresponding image for that I write as follows
#if (Session["UserName"] != null)
{
<div class="logged_in" id="user_navigation" runat="server">
<a title="Your Profile" href="">
<img alt="" src="#Url.Action("GetPhoto", new { photoId = Session["UserName"] })" height="50" width="50" class="photo" />
</a>
</div>
}
But this is not showing image as per required for me so can some one help me I would like to display the image from the database after user logged in also I would like to display the session values in some control too
This is my controller code
public ActionResult GetPhoto(string photoId)
{
byte[] photo = null;
var v = db.tblUsers.Where(p => p.UserName == photoId).Select(img => img.Photo).FirstOrDefault();
photo = v;
return File(photo, "image/jpeg");
}

You seem to have a problem with the <img> syntax. It should be like this:
<img alt="" src="#Url.Action("GetPhoto","User", new { photoId = Session["UserName"].ToString() })" height="50" width="50" class="photo" />
According to the comments section you seem to have used the WebForms view engine in your actual code (<%= Html.Encode(Session["UserName"]) %>).
This being said you have a far more serious issue with this code. The currently authenticated user should never be passed as parameter. That's a huge security vulnerability. So start by getting rid of it:
<img alt="" src="#Url.Action("GetPhoto", "User")" height="50" width="50" class="photo" />
and then inside your controller action you could retrieve it:
public ActionResult GetPhoto()
{
string user = Session["UserName"] as string;
byte[] photo = db
.tblUsers
.Where(p => p.UserName == user)
.Select(img => img.Photo)
.FirstOrDefault();
return File(photo, "image/jpeg");
}

Related

ASP.NET Core MVC - Getting data and handling 404 in same view

I'm more familiar with WebForms (which my company uses), and just started learning MVC. I followed the movies tutorial, and am having a bit of a hard time seeing how I can use the MVC pattern the way I want.
For instance, my company often asks me to make web apps that take some input from the user, looks it up in our database, and gives them back some other piece of data pertaining to the input, all on the same page.
With WebForms I can easily see if the database returned null and display an error label in that case. But with MVC treating data access like an API, I don't see how I can do the same thing without ignoring using the proper 404 code. Let's say I want to look up a movie (I commented out the 404s on purpose for now):
public class MoviesController : Controller
{
private readonly MovieDBContext _context;
public MoviesController(MovieDBContext context)
{
_context = context;
}
// GET: Movies/Info/Title
public async Task<IActionResult> Info(string title)
{
//if (title == null)
//{
//return NotFound();
//}
var movie = await _context.Movies
.FirstOrDefaultAsync(m => m.Title == title);
// if (movie == null)
// {
// return NotFound();
//}
return Json(movie);
}
Then in the view:
<h2>App</h2>
<br />
<div class="form-group">
<p>
Price Lookup App
</p>
<br />
<div class="row">
<div class="col-xs-2">
Enter movie title:
</div>
<div class="col-xs-2">
<input type="text" class="form-control" id="title" />
</div>
<div class="col-xs-2">
<input type="submit" class="btn" onclick="getMovie()" />
</div>
</div>
<br />
<div class="row">
<label id="price"></label>
</div>
</div>
<script>
function getMovie() {
var movie = $("#title").val();
if (movie != "") {
$.getJSON("../Movies/Info?title=" + movie, function (response) {
if (response != null) {
$("#price").html(response.price);
}
else {
$("#price").html("Film not found");
}
});
}
else {
$("#price").html("Film not found");
}
}
</script>
This technically works, but I feel I'm really not supposed to do it this way. I should be giving a 404 code when the movie isn't found, correct? I just don't know how to handle getting a 404 response and displaying a custom "not found" message on the same view like I am above, because the 404 stops execution of the JS. Thanks.
You can use $.ajax (ajax call), or $.get(get api call). There are componenets of success and error. you can handle the responses there

how to view single image with respect to particular ID value using MVC?

In my code overall image has been viewed but i need only particular ID value image should be displayed..
<div class="photo">
#foreach (var imgPath in Directory.GetFiles(Server.MapPath("~/ComapnyLogo"), "*.png"))
{
var img = new FileInfo(imgPath);
<img src="#Url.Content(String.Format("~/ComapnyLogo/{0}", img.Name))" />
}
</div>
hidden id
<input type="hidden" value="#ViewBag.hdnCompany" id="hdnCompany" />
public ActionResult ViewCompany()
{
var data = dp.Company.SqlQuery("Select * from CompanyRegistration").ToList();
return View(data);
}
Small mistake i cleared the problem
<img src="#Url.Content(String.Format("~/ComapnyLogo/" + MainModel.CompanyID + ".png"))" />
In this code is working fine in my side..

Difference between an internal and external link

I have an image which when clicked, redirects to another page. I need a way to know whether the link is internal(page of the application) or an external link. If the link is external I would want it to pop up in a new tab and if it is internal pop up in the same tab.
This is the code section.
<a class="lnkImage" href="#item.ImageURL" target="_blank">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
ImageURL and Actual image are coming from the model. Basically I want this functionality.
if(External)
{
<a class="lnkImage" href="#item.ImageURL" target="_blank">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
}
else if(internal)
{
<a class="lnkImage" href="#item.ImageURL">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
}
I am aware that by using Request.Url.Host I can get the host and compare it, but that would mean hard coding it and will have to be changed in different hosts. Is there a way to generically find out the domain of #item.ImageURL in the view?
UPDATE: I can do the Request.URL for both the domain of the website I am and the domain of the #item.ImageURL in the controller and set a boolean in my model, but I have 4 such sections. One link for the image, one for the image header, one for the image details and so on. So this will have me introduce 4 new model objects, set each one of them in the controller. So i want it to be possible to compare it in the view.
Please review this one.
It compares href with window.location.origin using indexOf. If it is found, it changes the window.location = href, if not it triggers anchor.click()
var ls = Array.from(document.querySelectorAll(".lnkImage img"));
ls.forEach(function(l) {
l.addEventListener('click', function(e) {
var ori = window.location.origin;
var hr = this.parentNode.href;
if (hr.indexOf(ori) >= 0) {
window.location = hr;
console.log('internal');
} else {
this.parentNode.click();
console.log('external');
}
})
})
<!--internal-->
<a class="lnkImage" href="http://stacksnippets.net" target="_blank">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
<!--external-->
<a class="lnkImage" href="http://othersite.com/test" target="_blank">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
My answer is server-based. The controller, which fills the view with model, compares for each image item.ImageURL host with current Request.Url.Host. If they are different (link is external), add attribute to the image link target="_blank", if the same - it adds target="_self". See sample code below, you can easily adjust it to your needs.
//controller
public ActionResult Index() {
var model = new CustomModel {
ImageItems = GetImageItems()
};
//set link target for view based on image url
foreach (var imageItem in model.ImageItems) {
imageItem.LinkTarget = GetLinkTarget(imageItem.ImageURL);
}
return View(model);
}
private string GetLinkTarget(string linkUrl) {
var url = new Uri(linkUrl);
return url.Host == Request.Url.Host ? "_self" : "_blank";
}
//view
<div>
#{
foreach (var imageItem in Model.ImageItems) {
<a class="lnkImage" href="#imageItem.ImageURL" target="#imageItem.LinkTarget">
<img id="PrivateimgPreview" src="#item.ActualImage" />
</a>
}
}
</div>

What can I do to come back to this previous view in C#/.NET?

I am pretty new in C# and .NET MVC framework and I have the following problem.
I have a first JQuery Mobile view that show a navbar containing some tabs. Into one of this tab I putted a ListView that show the element of a collection of DataModel.Vulnerability.Fix objects represented by the Model.VulnerabilityFixes into my model object. On the right of every element of the list I have put a button/link to delete the related Fix object that generate this row in the list.
This work fine and I obtain the following result (I post a screenshot):
This is the code of the previous tab (the one that show the Fix list):
<!-- TAB-2: FIXES, SOLUTION e MITIGATING STRATEGY: -->
<div id="tab-2" class="ui-body-d ui-content">
<h3>Fixes</h3>
<a href="#Url.Action("SearchCPE", "Asset", new { id = Model.Id })" data-icon="plus" data-inline="true" data-mini="true" data-role="button" >Aggungi un Fix</a>
<!-- Tabella contenente la lista delle fix: -->
<ul data-role="listview" data-inset="true" data-theme="b" data-split-icon="delete">
#foreach (DataModel.Vulnerability.Fix item in Model.VulnerabilityFixes)
{
<li><a href="#Url.Action("Details", "Product", new { Title = item.Title })">
<h2>#item.Title</h2>
<table style="width: 100%">
<tr>
<th>Id</th>
<th>FixName</th>
<th>Vendor</th>
<th>Version</th>
</tr>
<tr>
<td>#MyHelper.decodeNull(item.Id)</td>
<td>#MyHelper.decodeNull(item.FixName)</td>
<td>#MyHelper.decodeNull(item.Vendor)</td>
<td>#MyHelper.decodeNull(item.Version)</td>
</tr>
</table>
</a>
Delete
</li>
}
</ul>
</div>
<!-- /tab-2 -->
Ok, now I have a DeleteFix() method into the EditingController class that handle the request generated clicking od the Delete button.
This one:
public ActionResult DeleteFix(long vulnId, int currentFixId, string currentFixName)
{
DataModel.Vulnerability.Fix model = new DataModel.Vulnerability.Fix();
manager.openConnection();
try
{
model.Id = currentFixId;
model.FixName = currentFixName;
}
finally
{
manager.closeConnection();
}
return View(model);
}
This method show another view, the DeleteFix.cshtml file, that show a confirm window where is asked to the user to confirm the delete operation or if come back to the previous page, this is the code:
#model DataModel.Vulnerability.Fix
#{
ViewBag.Title = "DeleteFix";
Layout = "~/Views/Shared/MasterPageMobile.cshtml";
}
<h1>Delete Fix</h1>
<h2>Fix: #Model.Title (id: #Model.Id)</h2>
<p>
Confermare la cancellazione del fix "#Model.FixName" ?
</p>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<input type="hidden" name="id" value ="#Model.Id" />
<div data-role="controlgrup" data-type="horizontal" data-mini="true">
<a href="#Url.Action("Index", "Editing", new { id = Model.Id })" data-inline="true" data-mini="true" data-role="button" >Torna alla lista</a>
<a href="#Url.Action("Details", "Groups", new { id = Model.Id })" data-mini="true" data-inline="true" data-role="button" >Annulla</a>
<input type="submit" value="Delete" data-mini="true" data-inline="true" />
</div>
}
My problem is that I want that if the user click on the Torna alla lista button it have to be taken to the initial view that show the list of Fix object but I can't do it
Someone can help me to understand what am I missing? What can I do to obtain this result?
Tnx
Basically I would add a new property in the viewmodels used in the secondary views to have a trace of the primary url :
public string BackUrl { get; set; }
Maybe if you want this feature for more that I secondary view, you can create a base view model that all secondary viewmodels inherit.
Then, when calling a secondary view, just initialize the BackUrl property :
Delete
In the end, in the DeleteFix action, redirect to the BackUrl instead of redering the view (if the viewstate is valid :
public ActionResult DeleteFix(long vulnId, int currentFixId, string currentFixName)
{
if (ModelState.IsValid)
{
DataModel.Vulnerability.Fix model = new DataModel.Vulnerability.Fix();
manager.openConnection();
try
{
model.Id = currentFixId;
model.FixName = currentFixName;
}
finally
{
manager.closeConnection();
}
return Redirect(viewModel.BackUrl);
}
// Invalid viewstate, re-render the view
return View(model);
}

How to display saved image in a folder in ASP.net MVC

I am saving image files in a folder /images/profile and i want to save the image path in a database and do not know how to display image in a view. I am new to MVC. Following are the codes for image uploading. Please help.
HomeController.cs
public class HomeController : Controller
{
ImageEntities db = new ImageEntities();
public ActionResult Index()
{
return View();
}
public ActionResult FileUpload(HttpPostedFileBase file, tbl_Image model)
{
if (file != null)
{
string pic = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(
Server.MapPath("~/images/profile"), pic);
// file is uploaded
file.SaveAs(path);
}
return View("FileUploaded", db.tbl_Image.ToList());
}
public ActionResult FileUploaded()
{
return View();
}
}
FileUpload.cshtml
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file">Upload Image:</label>
<input type="file" name="file" id="file" style="width: 100%;" />
<input type="submit" value="Upload" class="submit" />
}
FileUploadedView.cshtml
#foreach (var item in Model)
{
<img src="~/images/profile/#item.imagepath" />
}
You shoud save image name instead of image path in table.
Then in view try this:
<img src="~/images/profile/#Model.imageUrl" />
"Update"
See here:
How to save image in database and display it into Views in MVC?
save the image path like this: "~/images/profile/mypic.jpg"
and then in you view:
<img src="#Url.Content("~/images/profile/mypic.jpg")" />
or in case you have a Photo class: (consider "item" as your image)
<img src="#Url.Content(item.Path)" />
thats it.
According to the suggestion of Samiey Mehdi I did this at my code for making it work
In the Controller:
newRecord.flName = ImageName;
In the View:
<img src="~/images/#item.flName" width="100" height="100" />

Categories