ASP.Net MVC3 Rendering Database stored images - asp.net-mvc

I have a controller as follows that returns a byte[]
public class ImageController : Controller
{
public ActionResult Show(int id)
{
var proxy = new ServiceProxy();
var imgData = proxy.GetCheckImage(id);
return File(imgData, "image/tiff");
}
}
My view is as follows:
<img alt ="" src='#Url.Action("show", "image", new { id = 36 })'/>
I have hard coded the image id for debug purposes.
On the browser in chrome/ie I get a x where the image needs to be displayed. But if I go directly to the controller url http://localhost/website/image/show/id=36, the image gets downloaded fine to the local machine.I have tried creating a separate ActionResult in the same controller which is used to display other data without any luck. This is a Win7/IIS7 local dev. environment.

Tiff is not supported by most browsers. The solution is to convert the Tiff to a Png file.
This post has the solution to your problem:
Render image to the screen from MVC controller

Is Tiff supported by Chrome/IE? I don't think it is...

Related

ASP.NET MVC 5: how to force image ETAG to be recalculated?

I am developing a website where a user might change his profile image.
This profile image has a fixed name such as "profile####.jpg" (where #### corresponds to the user's profile id).
In other words, if the user's profile id is "123", the image name will always be: "profile123.jpg".
The problem I am facing is that when the user changes his profile image, the new version of the image is not refreshed the next time the page is displayed (the "old" version of profile123.jpg is still used (from disk cache).
Having a look at the network communication, I have this:
profile123.jpg status 200 type jpeg ETag "e5b8c99974a3d31:0"
When I directly change the image source (in Chrome developer tools / Elements pane) to "profile123.jpg?some_sand", I obtain:
profile123.jpg?some_sand status 200 type jpeg ETag "2479c550dcad31:0".
and I have the correct profile image displayed.
Now the question:
I am using .NET Framework 4.5.2 MVC 5 (NOT ASP.NET Core)
How can I set up a correct ETag filter on static files (such as images), which would ensure that each time I change an image (keeping its name unchanged), the new version is being downloaded and displayed?
Many thanks
If you create a class that can be accessed from the Razor View (by making sure it's namespace is referenced in the View web.config) like so:-
public class CacheBreaker
{
public static string VersionTag(string rootRelativePath)
{
if (HttpRuntime.Cache[rootRelativePath] == null)
{
var path = HostingEnvironment.MapPath("~" + rootRelativePath);
if (!File.Exists(path))
{
return rootRelativePath;
}
var result = rootRelativePath + "?v=" + Encryption.GenerateMD5(File.GetLastWriteTime(path).Ticks.ToString());
HttpRuntime.Cache.Insert(rootRelativePath, result, new CacheDependency(path));
}
return HttpRuntime.Cache[rootRelativePath] as string;
}
}
you can use this reference in the View to generate a fingerprint for the image:
<img src="#CacheBreaker.VersionTag(Url.Content("~/Path/To/Image/profile123.jpg"))" />
that generates:
<img src="/Path/To/Image/profile123.jpg?v=5276dc5d07eaf51013a48a1e539def2b">
that will be updated every time the image changes.
(This code is a modified version of the code in a Mads Kristensen's blog, but based upon it, where you can find more details of the principles behind this approach.)

Umbaco Archtype rendering images (MediaPicker2)

I'm building a image slider using Archtype in Umbraco.
I was using umbraco 7.5.9 and Umbraco.MediaPicker when I started this but in the mean time I started a new project with the newest version Umbraco (7.6.2) which uses Umbraco.MediaPicker2
It was no problem rendering images with the old MediaPicker but with the MediaPicker2 it seems impossible.
Here is my setup.
The Archtype:
Here is the partial view that rendered the old MediaPicker
<div class="fullWidthSlider">
#foreach (var image in #CurrentPage.SliderImages)
{
<div>Id: #image.GetValue("image")</div>#*Line added for debug*#
var media = #Umbraco.Media(image.GetValue("image"));
<img src="#media.Url" />
}
</div>
This used to work for the old Media picker and the #image.GetValue returned int id. But with the new MediaPicker2 it returns Umbraco.Core.Udi[]
If I foreach through the properties of the archtype with the code below I get this result (see below code)
#foreach (var fieldset in Model.Content.GetPropertyValue<ArchetypeModel>("sliderImages"))
{
foreach(var prop in fieldset.Properties){
<p>#prop.Alias - #prop.Value</p>
}
}
href -
altText - alt test
image - umb://media/c33bfe07a82b4df18a79db154139cb91
href -
altText - Fjall
image - umb://media/40d5778d34bb4035b5146c901de75212
Can anyone tell me how I can render image from this data.
Thanks
I just went on a roller-coaster figuring this out!
You can get an IPublishedContent from your image string using this code:
// Your string which is retrieved from Archetype.
var imageString = "umb://media/c33bfe07a82b4df18a79db154139cb91";
// Get the guid from this string.
var imageGuidUdi = GuidUdi.Parse(imageString);
// Get the ID of the node!
var imageNodeId = ApplicationContext.Current.Services.EntityService.GetIdForKey(guidUdi.Guid, (UmbracoObjectTypes)Enum.Parse(typeof(UmbracoObjectTypes), guidUdi.EntityType, true));
// Finally, get the node.
var imageNode = Umbraco.TypedMedia(imageNodeId.Result);
Check out this thread on Our Umbraco which covers this issue.
I used this comment to figure out how to get the ID from the image's guid.
It looks like Umbraco HQ is pushing for people to use the new ModelsBuilder with typed models. I'm not sure if Archetype is supported by the ModelsBuilder which is why there's so much trouble.
I personally use Nested Content on all of my projects as it performs the same functionality but (IMO) is better supported by Umbraco because it uses Document Types to store repeatable content schema. Because of this, it can then easily be mapped to IPublishedContent and therefore is supported by the ModelsBuilder!

Asp .net core how to display RTF document file in page view cshtml

Please I need some help.
I want to build an online exam web application, so the question files as .rtf stored in database, then when the exam held, us as participant can see the questions by the button list in page.
How I can show/display any .RTF file document (from my database) to page view (.cshtml) ?
public class Exam_Question
{
....
public byte[] Question_File { get; set; }
}
I have stored the file in database.
Then in controller I call the model.
public async Task<IActionResult> Details(int? id)
{
var exam_Question = await _context.Question.SingleOrDefaultAsync(m => m.ID == id);
return View(exam_Question);
}
Then in page view I did try this.
<iframe src="data:#Model.Question_File; base64, #Convert.ToBase64String(Model.Question_File)"></iframe>
the result like this image : IFrame tag with base64 file
I want to display at least at same bold, size, paragraph, equation, etc format like in Word App.
I think one option will be to convert the RTF into HTML at server side and then rendering.
You could either use a paid library as below
SautinSoft
Or build your own RTF to HTML converter. Here is a link to CodeProject which provides pretty detailed breakdown
CodeProject
Sorry I cant think of a simpler solution at the moment
As a variant: Load RTF file and then to open in HTML.
string inpFile = #"..\..\..\..\example.rtf";
string outfile = Path.GetFullPath("Result.html");
RtfToHtml r = new RtfToHtml();
r.Convert(inpFile, outfile, new HtmlFixedSaveOptions() {Title = "Show the RTF." });

MVC ExtractAssociatedIcon show icon in view

I would like to display a file icon in one of my views.
#System.Drawing.Icon.ExtractAssociatedIcon(#"C:/Users/User1/Desktop/test.txt")
Shouldn't this display the icon? Do I need a img tag or something else?
Thanks
You cannot just have the file contents on the browser. You will need to use an <img> tag and have the server return the file stream:
Quick disclaimer: I do not have VS with me, so this is just pseudo-code:
public FileResult Icon()
{
var stream = System.Drawing.Icon.ExtractAssociatedIcon(#"C:/Users/User1/Desktop/test.txt")
return new FileStreamResult(stream, "image/png");
}
Then, just reference the action method:
<img src="/MyController/Icon">

How can I take a screenshot of a website with MVC?

I am struggling to find a way to take a screenshot of a website in MVC4. I have seen two potential solutions, which neither work well for MVC.
The first is using the WebBrowser, tutorial found here, but this gives me a ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment error.
The other is using a 3rd party called Grabz.It, but I haven't found a way to integrate it into MVC.
Any other ideas/solutions?
Thanks.
Given your additional details, you should be able to do this with any number of tools. CodeCaster's idea is fine, and PhantomJS also offers similar webkit-based image generation of an arbitrary url (https://github.com/ariya/phantomjs/wiki/Screen-Capture). It offers several output format options, such as PNG, JPG, GIF, and PDF.
Since PhantomJS is using WebKit, a real layout and rendering engine, it can capture a web page as a screenshot. Because PhantomJS can render anything on the web page, it can be used to convert contents not only in HTML and CSS, but also SVG and Canvas.
You would need to execute the phantomjs.exe app from your MVC app, or probably even better by some service that is running behind the scenes to process a queue of submitted urls.
Why do you want to integrate this in MVC? Is it your website's responsibility to take screenshots of other websites? I would opt to create the screenshot-taking-logic in a separate library, hosted as a Windows Service for example.
The WebBrowser control needs to run on an UI thread, which a service (like IIS) doesn't have. You can try other libraries though.
You could for example write some code around wkhtmltopdf, which renders (as the name might suggest) HTML to PDF using the WebKit engine.
You need to specify that the thread is in STA (single threaded apartment mode in order to instantiate the web browser).
public ActionResult Save()
{
var url = "http://www.google.co.uk";
FileContentResult result = null;
Bitmap bitmap = null;
var thread = new Thread(
() =>
{
bitmap = ExportUrlToImage(url, 1280, 1024);
});
thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
thread.Start();
thread.Join();
if (bitmap != null)
{
using (var memstream = new MemoryStream())
{
bitmap.Save(memstream, ImageFormat.Jpeg);
result = this.File(memstream.GetBuffer(), "image/jpeg");
}
}
return result;
}
private Bitmap ExportUrlToImage(string url, int width, int height)
{
// Load the webpage into a WebBrowser control
WebBrowser wb = new WebBrowser();
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(url);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
// Set the size of the WebBrowser control
wb.Width = width;
wb.Height = height;
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, wb.Width, wb.Height));
wb.Dispose();
return bitmap;
}

Resources