Image display in asp.net mvc - image

i can't display the image on my aspx view..
i'm using mysql as database
i have this code for my model:
Imports Microsoft.VisualBasic
Imports System.Data
Public Class ClassPhotosConnection
Inherits ClassConnection
Public Function pictureSelect() As DataTable
Return ReadData("SELECT * FROM pictures")
End Function
End Class
for the controller:
Public Class AdministrationController
Inherits Global.System.Web.Mvc.Controller
Private dPhotos As New ClassPhotosConnection
<AcceptVerbs(HttpVerbs.Get)> _
Function Photos() As ActionResult
Dim _photos As DataTable = dPhotos.pictureSelect()
Return View(_photos)
End Function
End Class
for the view:
<div>
<form action="<%url.action("Photos") %>">
<%Using Html.BeginForm%>
<%Dim _photos As datatable = ViewData.Model%>
<%For count As Integer = 0 To _photos.Rows.Count - 1%>
<img src='<%=_photos.Rows(count).Item("picURL") %>' alt="" />
<p>
<%=_photos.Rows(count).Item("picCaption")%>
</p>
<%Next%>
<%End Using%>
</form>
</div>
the only thing that is displayed is the picCaption..it seems that it cannot call src='<%=_photos.Rows(count).Item("picURL") %>'
how else can i display the image?
thank you!

does the picURL contain a relative or absolute reference to the image? If the reference is realtive, you'll probably need to use the Url.Content method to map the path correctly.
<img src='<%= Url.Content("~/" + _photos.Rows(count).Item("picURL")) %>' alt="" />

Related

ASP .NET MVC Ajax insert view instead instead replace data only first time

I'm new to AJAX, and I have a very simple example, but has a problem; first call the data is duplicated at the View and in subsequent calls work correctly. What am I doing wrong?
The ~/Views/Shared/_Layout.cshtml file had all scripts necesary:
<script src="~/Scripts/jquery-3.1.0.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
First time, the initial view:
Second time, first time button click inserts a number instead of replace number:
Third time, second time button click works fine but in the second line number... an so on:
This is my code:
Model
namespace MQWebSt.Models
{
public class AjaxTest
{
public int Number { get; set; }
}
}
Controller:
using System.Web;
using System.Web.Mvc;
using MQWebSt.Models;
namespace MQWebSt.Controllers
{
public class AjaxTestController : Controller
{
// GET: AjaxTest
public ActionResult Vista()
{
AjaxTest at = new AjaxTest { Number = 1 };
return View(at);
}
[HttpPost]
public ActionResult Vista( AjaxTest model)
{
Random rnd = new Random();
model.Number = rnd.Next(1, 100);
return PartialView("AjaxTestPartial", model);
}
}
}
View Vista.chtml:
#model MQWebSt.Models.AjaxTest
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Ajax.BeginForm("Vista", new AjaxOptions { UpdateTargetId = "divEmp", InsertionMode = InsertionMode.Replace }))
{
<button class="btn btn-primary btn-md glyphicon glyphicon-menu-right" name="Contestar" type="submit" value="+1"></button>
<div class="panel panel-footer">
<table id="divEmp">
#Model.Number.ToString()
</table>
</div>
}
AjaxTestPartial.chtml:
#model MQWebSt.Models.AjaxTest
#Model.Number.ToString()
The issue is you're using InsertionMode = InsertionMode.Replace, it's going to replace the data in the UpdateTargetId. You could use InsertionMode.InsertBefore instead and it would build the values out in the parent of #divEmp. However, if you need the values to be placed in #divEmp, you'll need to write a JavaScript handler for the OnSuccess option of your Ajax form, that way you can dictate if you're doing insert vs. pre-pend vs. replace.
The issue is, your HTML markup code in your razor view is not valid. With the code you have, razor will generate the below markup (Check the view source)
<div class="panel panel-footer">
1
<table id="divEmp"></table>
</div>
You can see that 1 is not inside the table. It is outside. So when your ajax form submit happens, it will update the tables content with the new value. that is the reason you are still seeing the initial number.
The solution is to change the table to a div/span
<div id="divEmp"> #Model.Number.ToString() </div>
Or if you absolutely need to have a table for any reason, have the value inside a td and use "divEmp" as the id attribute value of that.
<table >
<tr>
<td id="divEmp">1</td>
</tr>
</table>

Spring MVC 3.2 Thymeleaf Ajax Fragments

I'm building application with Spring MVC 3.2 and Thymeleaf templating engine. I'm a beginner in Thymeleaf.
I have everything working, including Thymeleaf but I was wondering if anyone knows of a simple and clear toturial on how to do simple Ajax request to controller and in result rendering only a part of a template (fragment).
My app has everything configured (Spring 3.2, spring-security, thymeleaf, ...) and works as expected. Now I would like to do Ajax request (pretty simple with jQuery but I don't wan't to use is since Thymeleaf in its tutorial, chapter 11: Rendering Template Fragments (link) mentiones it can be done with fragments.
Currently I have in my Controller
#RequestMapping("/dimensionMenuList")
public String showDimensionMenuList(Model model) {
Collection<ArticleDimensionVO> articleDimensions;
try {
articleDimensions = articleService.getArticleDimension(ArticleTypeVO.ARTICLE_TYPE);
} catch (DataAccessException e) {
// TODO: return ERROR
throw new RuntimeException();
}
model.addAttribute("dimensions", articleDimensions);
return "/admin/index :: dimensionMenuList";
}
the part of the view where I would like to replace <ul></ul> menu items:
<ul th:fragment="dimensionMenuList" class="dropdown-menu">
<li th:unless="${#lists.isEmpty(dimensions)}" th:each="dimension : ${dimensions}">
</li>
</ul>
Any clue is greatly appreciated. Especially if I don't have to include any more frameworks. It's already too much for java web app as it is.
Here is an approach I came across in a blog post:
I didn't want to use those frameworks so in this section I'm using jQuery to send an AJAX request to the server, wait for the response and partially update the view (fragment rendering).
The Form
<form>
<span class="subtitle">Guest list form</span>
<div class="listBlock">
<div class="search-block">
<input type="text" id="searchSurname" name="searchSurname"/>
<br />
<label for="searchSurname" th:text="#{search.label}">Search label:</label>
<button id="searchButton" name="searchButton" onclick="retrieveGuests()" type="button"
th:text="#{search.button}">Search button</button>
</div>
<!-- Results block -->
<div id="resultsBlock">
</div>
</div>
</form>
This form contains an input text with a search string (searchSurname) that will be sent to the server. There's also a region (resultsBlock div) which will be updated with the response received from the server.
When the user clicks the button, the retrieveGuests() function will be invoked.
function retrieveGuests() {
var url = '/th-spring-integration/spring/guests';
if ($('#searchSurname').val() != '') {
url = url + '/' + $('#searchSurname').val();
}
$("#resultsBlock").load(url);
}
The jQuery load function makes a request to the server at the specified url and places the returned HTML into the specified element (resultsBlock div).
If the user enters a search string, it will search for all guests with the specified surname. Otherwise, it will return the complete guest list. These two requests will reach the following controller request mappings:
#RequestMapping(value = "/guests/{surname}", method = RequestMethod.GET)
public String showGuestList(Model model, #PathVariable("surname") String surname) {
model.addAttribute("guests", hotelService.getGuestsList(surname));
return "results :: resultsList";
}
#RequestMapping(value = "/guests", method = RequestMethod.GET)
public String showGuestList(Model model) {
model.addAttribute("guests", hotelService.getGuestsList());
return "results :: resultsList";
}
Since Spring is integrated with Thymeleaf, it will now be able to return fragments of HTML. In the above example, the return string "results :: resultsList" is referring to a fragment named resultsList which is located in the results page. Let's take a look at this results page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
</head>
<body>
<div th:fragment="resultsList" th:unless="${#lists.isEmpty(guests)}" id="results-block">
<table>
<thead>
<tr>
<th th:text="#{results.guest.id}">Id</th>
<th th:text="#{results.guest.surname}">Surname</th>
<th th:text="#{results.guest.name}">Name</th>
<th th:text="#{results.guest.country}">Country</th>
</tr>
</thead>
<tbody>
<tr th:each="guest : ${guests}">
<td th:text="${guest.id}">id</td>
<td th:text="${guest.surname}">surname</td>
<td th:text="${guest.name}">name</td>
<td th:text="${guest.country}">country</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
The fragment, which is a table with registered guests, will be inserted in the results block.
Rendering only Thymeleaf fragments also works well with ModelAndView.
Your controller
#RequestMapping(value = "/feeds", method = RequestMethod.GET)
public ModelAndView getFeeds() {
LOGGER.debug("Feeds method called..");
return new ModelAndView("feeds :: resultsList");
}
Your view
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<div th:fragment="resultsList" id="results-block">
<div>A test fragment</div>
<div>A test fragment</div>
</div>
</body>
</html>
What's actually rendered
<div id="results-block">
<div>A test fragment</div>
<div>A test fragment
</div>
</div>
As an alternate version to Sohail's great answer, I want to give a version that using javascript can send the whole th:object to the controller, integrating Thymeleaf in your forms, not having to use #PathVariable which becomes messy or not usable at all when you've forms with many fields.
For the form (using an example which returns an object which has an id and a name Strings, and feeds a combobox with a Map that has some of those objects as values) we have:
<form method="post" th:action="#{/yourMapping}" th:object="${object}" id="yourFormId">
<select th:field="*{mapOfObjects}">
<option
th:each="entry: ${mapOfObjects}"
th:value="${entry.value.id}"
th:text="${entry.value.name}" >
</option>
</select>
<p>Name:
<input type="text" th:field="*{name}" />
</p>
</form>
When this form is submited (using a button with type submit for example) the whole document will be replaced. However we can intercept this submit with javascript and do it the ajax-way. To achieve this, we will add an interceptor to our form using a function. First call the function that adds the interceptor right after the form:
<script>formInterceptor("yourFormId");</script>
And the function looks like this (place it in the head of the document or wherever suits your needs):
<script>
function formInterceptor(formName) {
var $form = $("#" + formName);
$form.on('submit', function(e) {
e.preventDefault();
$.ajax({
url : $form.attr('action'),
type : 'post',
data : $form.serialize(),
success : function(response) {
if ($(response).find('.has-error').length) {
$form.replaceWith(response);
}
else{
$("#ajaxLoadedContent").replaceWith(response);
}
}
});
});
};
</script>
Now whenever the form is submited, this function will trigger, and it will:
Prevent the original form submit
Make an ajax call using the url defined in the form's th:action
Serialize the form data. Your controller will be able to recieve this in an object
Replace the part of your html code with the returned fragment
The replaced part should look like this
<div id="ajaxLoadedContent"></div>
And the controller can recieve the th:object in the form, with it's values filled, like this (Replace Object with your object's type and "object" with a proper name):
#PostMapping(value = /yourMapping)
public String ajaxCtrlExample(#ModelAttribute("object") Object object, Model model) {
return yourFragmentPath;
}
And that's everything. Call the function that adds the interceptor after every form you need in ajax-version.

Pass image from controller and display in a view using ViewBag in ASP.NET MVC 3

I guess it's something very straight forward but I can't find out how to do it. In my controller I have:
public ViewResult ShowForm()
{
ViewBag.Title = Resources.ApplicationTitle;
ViewBag.LabelStatus = Resources.Status;
//Logo
ViewBag.Logo =#"C:\Images\Logo.png";
return View("ShowForm");
}
And in my view I try this:
<div id="drawForm">
<img src="#ViewBag.Logo" alt="Logo" />
</div>
However when I run this I just get the "Logo" text.
Use Server.MapPath to get the correct path of the image. Suppose your images folder is inside the Content folder that is normally included in an MVC project. You can do something like this:
public ViewResult ShowForm()
{
//Logo
ViewBag.Logo = Server.MapPath("~") + #"Content\Images\Logo.png";
return View("ShowForm");
}
And you don't have to change the code in your view.
Try this:
ViewBag.Logo = Url.Content("~/Content/Images/Logo.png");
You need a ImageController to render that.
See this:
ASP.NET MVC3: Image loading through controller
and this:
Can an ASP.NET MVC controller return an Image?
once you have a controller you can render as follows:
public class ImageController{
public ActionResult ShowImage(string path)
{
return File(path);
}
}
in your views:
<img src="#Url.Action("Render","Image", new {id =1 // or path })" />
public ActionResult ShowForm()
{
ViewBag.Title = Resources.ApplicationTitle;
ViewBag.LabelStatus = Resources.Status;
//Logo
byte[] imgbytes = File.ReadAllBytes(#"C:\Images\Logo.png");
return File(imgbytes , "image/png");
}
<div id="drawForm">
<img src="controllerName/ShowForm" alt="Logo" />
</div>

asp.net MVC 3 - JQuery ajax $.get return <nonscript> reCaptcha instead of actual html in partial view

This problem is kind of difficult to explain, but I'll do my best.
I'm simply trying to render the reCaptcha input on a form that is embedded inside a partial view.
Here's how I'm obtaining the partial view with JQuery $.get:
GetAndRenderPartialContent: function (url, obj) {
$.get(url, function (data) {
obj.replaceWith(function () {
var content = "<div id=\"" + obj.attr('id') + "\">" + data + "</div>";
return content;
});
});
}
This works great as a JQuery extension method.
The URL that's passed in to this method is simply a controller route that returns a partial view like this:
public ActionResult GetSomeContent()
{
var model = new SomeModel();
// set modal values
// Finally return partial view
return PartialView("_MyPartialView", model);
}
This works great. It even renders form values bound to the model.
The problem is only with reCaptcha. In my view I have this line to render the reCaptcha:
#Microsoft.Web.Helpers.ReCaptcha.GetHtml(theme: "clean", publicKey: ConfigurationManager.AppSettings["reCaptcha:publicKey"], language: "en")
This works when I embed it directly in the parent view.However, when it is rendered from the partial view method, I get the following results:
<noscript>
<iframe frameborder="0" height="300px" src="http://www.google.com/recaptcha/api/noscript?k=[MY PUBLIC KEY REMOVED FOR DEMO]" width="500px"></iframe>
<br /><br />
<textarea cols="40" name="recaptcha_challenge_field" rows="3"></textarea>
<input name="recaptcha_response_field" type="hidden" value="manual_challenge" />
</noscript>
It appears that the PartialView method is HtmlEncoding the output from the reCaptcha, but not the other form elements that are embedded in the form. Has anyone encountered this or have an elegant solution to this annoying problem that has taken up a couple of hours of my time?
The only solution I've been able to achieve is to render the reCaptcha in the parent view, hide it until the partial view page is called, then relocate it to the appropriate position in the form, which is not a desirable nor elegant solution.
Any help is appreciated.
Thanks.
* UPDATE **
I tried pasting the view code here but stackoverflow's editor kept rejecting the code. Suffice it to say, there is nothing unusual about the view. The model contains properties for binding such as:
[Required]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required]
[Display(Name = "Confirm Email Address")]
[Compare("Email", ErrorMessage = "Your email and confirmation email do not match.")]
public string ConfirmEmail { get; set; }
The form:
#using (Html.BeginForm("UpdateInfo", "MyAccount", FormMethod.Post, new { #id = "InfoForm" }))
Render the model items:
<div class="editor-label">
#Html.LabelFor(m => m.Email)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Email) #Html.ValidationMessageFor(m => m.Email)
</div>
Near the end of the form:
<fieldset id="reCaptchaFieldset">
<legend>Captcha Authorization</legend>
#ReCaptcha.GetHtml(theme: "clean", publicKey: System.Configuration.ConfigurationManager.AppSettings["reCaptcha:publicKey"])
</fieldset>
Try the following:
#Html.Raw(Microsoft.Web.Helpers.ReCaptcha.GetHtml(theme: "clean", publicKey: ConfigurationManager.AppSettings["reCaptcha:publicKey"], language: "en"))
Use the AJAX API part in this document:
http://code.google.com/apis/recaptcha/docs/display.html
Use this code in the partialView.

Setting form method to get without specifying controller and action

I have a partial view which I need to re-use:
div class="selectDate">
#using (Html.BeginForm("ViewTransactionLog", "Profile", FormMethod.Get))
{
<div class="selectDateLabel">Date:</div>
<div>
#Html.TextBox("start", range.Start, new { #class = "pickDate" }) to #Html.TextBox("end", range.End, new { #class = "pickDate" })
</div>
<div>
<input type="submit" value="Go" />
</div>
}
</div>
This is the code for picking 2 dates. As the data is lightweight, I wish to pass it through the Get method. I also wish to generalize it and put it into its own cshtml; however, Html.BeginForm expects the controller name and action name to be given if I wish to use the Get method. Is there anyway to avoid this so I could just move the code into a partial view of its own?
Assuming you want the form to post back to the current controller and action, you should be able to use an extension method:
public static MvcForm BeginForm<TModel>(
this HtmlHelper<TModel> html,
FormMethod formMethod)
{
string controller = (string)html.ViewContext.RouteData.Values["controller"];
string action = (string)html.ViewContext.RouteData.Values["action"];
return html.BeginForm(action, controller, formMethod);
}

Resources