mvc4 get image in view from controller - c#

First of all, i have used this way in another controller and it works perfectly, now i copied and paste it in another controller, but it didnt work.
i want to get an image from my controller.
i used this code in controller
[Authorize]
[AcceptVerbs(HttpVerbs.Get)]
public FileContentResult getPassportImg(int tenantID)
{
byte[] image = db.Tenants.Find(tenantID).passportImage;
if (image != null)
{
return new FileContentResult(image, "image/jpeg");
}
else
{
return null;
}
}
and i make breakpoints throw it and the data is being retrieved correctly.
in the view i do this
<div class="display-field">
<img src="#Url.Action("getPassportImg", "Tenant", new { tenantID = Model.ID })" alt="asdasdf" />
</div>
but when i run my application, it's not get the image. Can you
Please help me resolve this

Related

.Net Core MVC Web App - passing value from View to Controller in a Form not working

I've read other posts on here to try and fix my issue but no luck.
I have a form, that is based on a simple model.
public class Image
{
public string FileName { get; set; }
public string ImagePath { get; set; }
}
In my view, I have a form which displays an image:
#model Uploader.Models.Image
<h1>View Image</h1>
<form asp-controller="Images" asp-action="Download" method="post" enctype="multipart/form-data">
<img src="~/Images/#Model.FileName" />
<input type="submit" value="Download Image" class="btn btncolour btn-primary" />
#Model.FileName
</form>
That last Model.Filename, I was just testing to see if the value is present (which it is). From what i can see, everything is fine here, when I submit this form, the values from my model (specifically Image.FileName) should be posted back to the server.
my controller method:
[HttpPost]
public async Task<IActionResult> Download(Image image)
{
if (image.FileName == null)
return Content("filename not present");
var path = Path.Combine(
Directory.GetCurrentDirectory(),
"wwwroot", image.FileName);
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
My code hits this method upon postback, but image.FileName is always null, even though on the View itself, I can see that model.FileName does contain a value.
Could anyone explain what I am doing wrong?
many thanks
FileName is used for src of image but not as an input. Only input field values are sent in request when you click submit.
Try adding text input with name="FileName", then enter some value and click submit. Then you should be able to receive this value in controller method.

how to render partial view and image from same action result method?

I want to return partial view and base64 string from same ActionResult method on load of my View page.
This is my View:Index.cshtml
<body>
<div id="topimage">
#Html.Action("Fetch", "image", new { parameter = 1 }) //Seperate partial view to display top image.
<\div>
<div id="Bottomimage">
<img src=""/>//No partial View to display Bottom image here and how to call my controller method here with passing parameter.
<\div>
</body>
Partial View:_TopImage.cshtml
#model MyMvc.Demo.Model.ImageAttributes
<div>
<img src="data:image;base64,#System.Convert.ToBase64String(Model.Image)" />
</div>
My Controller method which will display both Top and bottom image based on parameter 1 and 0:
public ActionResult Fetch(int parameter)
{
using (var db = new MyDBContext())
{
if(parameter==1)//display top image
var Image = db.ImageAttributes.Where(r => r.DisplayDirection == parameter).FirstOrDefault();
return PartialView("_TopImage", Image );
else
{
var Image = db.ImageAttributes.Where(r => r.DisplayDirection == parameter).FirstOrDefault();
//Now here i just want to return Bytes of image which i will get in my ad Object as
//becasue there is no seperate partial view to display bottom image.so i will
//direclty return bytes from here and convert in to base 64 sstring there to render bottom image
//for eg: <img src="data:image;base64,#System.Convert.ToBase64String(Model.Image)" />
//How to do this
}
}
}
Note:I dont want to create Seperate Controller method and i dont want to change my any view.
So can anybody please Guide me for this???
You can store the action returned HtmlString in a variable if you dont want to call action two times:
#{
var Image = Html.Action("Fetch", "image", new { parameter = 1 });
}
<div id="topimage">
#Image //Seperate partial view to display top image.
<\div>
<div id="Bottomimage">
#image
<\div>
UPDATE:
IN that case modify your action else part like this:
else
{
var Image = db.ImageAttributes.Where(r => r.DisplayDirection == parameter).FirstOrDefault();
var base64Image = Convert.ToBase64String(Image.Image);
var byteArray = Convert.FromBase64String(base64Image);
return File(byteArray , "image/png", "image.png");
}
and in View:
<img src="#Url.Action("Fetch", "image", new { parameter = 0 })" />
If you want to load Your partial view to all it's View Page the simply call Your Partial View From Shared Folder of Your Views

Uploaded HttpPostedFileBase Image not displaying after refresh with FileContentResult Action

I am having an issue with the controller action where I upload an image and the initial POSTed result is displayed in the view without issue. The image is shown normally.
If I refresh or change pages and return, the image will no longer display.
I have checked what the controller action is returning, and it does indeed return the content to the view.
This is the IMG tag that I'm using to call the controller action.
<img src="#Url.Action("Display", "Home")" />
This is the controller action:
public ActionResult Display()
{
var tempModel = new PartialModel();
tempModel = (PartialModel)Session["Model"];
var ImageUpload = tempModel.ProductImage;
if (ImageUpload != null)
{
byte[] content = new byte[ImageUpload.ContentLength];
ImageUpload.InputStream.Read(content, 0, ImageUpload.ContentLength);
return File(content, ImageUpload.ContentType);
}
return null;
}
This is the create action that receives the POST values:
public ActionResult Create(PartialModelStore p)
{
Session.RemoveAll();
//m.initializeModelLists(p);
Session["Model"] = p;
//return View("Index", p);
return RedirectToAction("Index");
}
I'm using the Session to store values because this is just a mock up application.
I have looked into using Data URI but I need to support older browsers, thus I'm using this method.

Need uploadcontrol in a ajax.beginform using asp.net mvc3 html5 razor

I've been looking for a long time for this but I'm still stuck, I need to have an upload control where the user can upload a document and give additional information.
I've had to do this before without the upload control so what I do is I get an ajax.beginform that will give all the input from the user to the controller and than close the popup trough a onsucces function, so this looks like this:
view:
#using (Ajax.BeginForm("Save", "Documents", new AjaxOptions { HttpMethod = "Post", OnSuccess = "CloseDialog" }, new { #class = "form-inline", id = "FormId" }))
{
#Html.Label("Description", "Description")
<div class="span3">
#Html.TextBoxFor(m => m.Description)
</div>
}
I tried adding there an Html.BeginForm but then I found out that it is not possible to use nested forms so I deleted this.
In my controller I have:
public PartialViewResult Index(string description)
{
var model = new DocumentsModel{ Description = description};
return PartialView(model);
}
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file, string description)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath(#"D:\Documentds\"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index", new { description = description });
}
Ofcourse because the html.beginform won't work this controlleraction won't work either
So my question is how to do this without having to use a html.beginform?
You need to have the file upload inside the form and also the enctype="multipart/form-data" property on the form that calls uploadfile. That could be one problem.
Also, you could use JavaScript to submit the form you want from another part of the page without having them nested and keeping your design.

MVC3 - getting red x instead of picture from db

I am getting red x mark instead of the picture when storing in database. I believe I am having problems in the Views files. Please could someone have a look at this and tell me how to correct it. If I have wrong URL Actions please tell me which ones I should be using. Thanks in advance.
SubCategory2 Table has the following columns...
Column field > Picture1 : Data Type > varbinary(MAX)
Column field > ImageMimeType : Data Type > varchar(50)
Index.cshtml file
#foreach (var item in Model) {
<td>
<img src="#Url.Action("GetImage", "SubProductCategory2",
new { id = item.SubProductCategoryID})" alt="" height="100" width="100" />
</td>
Edit.cshtml file
"Edit" is the method in the contoller. "ProductCategoryL2" is the method in the controller. "GetImage" is the method in controller. All these methods are in the same controller file called ProductCategoryControllerL2
#using (Html.BeginForm("Edit", "ProductCategoryL2", "GetImage",
FormMethod.Post, new { #encType = "multipart/form-data" }))
{
<div class="editor-field">
<img src="#Url.Action("GetImage", "SubProductCategory2", new {
Model.SubProductCategoryID })" alt="" />
#Html.ValidationMessage("Picture1", "*")
<input type="file" id="fileUpload" name="Create" size="23"/>
</div>
}
ProductCategoryL2Controller.cs file
[HttpPost]
public ActionResult Edit(int id, FormCollection collection,
SubProductCategory2 editSubProdCat, HttpPostedFileBase image)
{
var r = db.SubProductCategory2.First(x => x.SubProductCategoryID
== id);
if (TryUpdateModel(r))
{
if (image != null)
{
editSubProdCat.ImageMimeType = image.ContentType;
editSubProdCat.Picture1 = new byte[image.ContentLength];
image.InputStream.Read(editSubProdCat.Picture1, 0,
image.ContentLength);
}
db.SaveChanges();
return RedirectToAction("/");
}
return View(r);
}
public FileContentResult GetImage(int productId)
{
var product = db.SubProductCategory2.First(x =>
x.SubProductCategoryID == productId);
return File(product.Picture1, product.ImageMimeType);
}
Addition Note
I am using MVC 3 framework. The GetImage method has been extacted from Steven Sanderson book Pro ASP.NET MVC 2 Framework. So I am not sure if that will be a problem?
The first step I would take to debug would be to try the URL for the image in your browser directly. Right-click on the red X, copy the url and paste it in your address bar. If the url looks right you should be a better error telling you what the problem is. If that fails, put a breakpoint in your GetImage routine to make sure the routes are correct and your method is getting called. Try Fiddler to see the request being made and what your web server is saying.
My guess is that you have the action wrong. It looks like you are linking to the GetImage action on the SubProductCategory2 controller when the method is on your ProductCategoryL2 controller.
Also I don't understand how your Model.SubProductCategoryID value is supposed to be mapped to your productId parameter. Try changing these calls:
Url.Action("GetImage", "SubProductCategory2",
new { id = item.ProductCategoryID})
Url.Action("GetImage", "SubProductCategory2", new {
Model.SubProductCategoryID })
to these:
Url.Action("GetImage", "ProductCategoryL2",
new { productId = item.ProductCategoryID})
Url.Action("GetImage", "ProductCategoryL2", new {
productId = Model.SubProductCategoryID })
Your input file field is called Create:
<input type="file" id="fileUpload" name="Create" size="23"/>
whereas the controller action parameter handling the form submission is called image (the one with HttpPostedFileBase type) => this parameter will always be null in your Edit controller action and nothing will be saved in the database.
Also the attribute is called enctype and not encType in the Html.BeginForm helper. Also inside the GetImage action ensure that product.Picture1 represents a correct image byte array and that it's content type matches with product.ImageMimeType.
So for example to further debug this issue you could try to save it to some temporary file to see if it is a valid image just before returning. Also make sure that the product instance you have fetched from the database is not null:
// if the content type is image/png:
File.WriteAllBytes(#"c:\foo.png", product.Picture1);
Then ensure that foo.png open successfully with an image viewer.
You are trying to return file content as the value to your img's src attribute. Your browser will need to issue a separate request for the image.
change your view to this:
<img src="GetImage/#(Model.SubProductCategoryID)" />

Categories