I have to fix a bug on a website that is using asp.net and i don't know much about it (asp.net c# mvc)...
the problem is in a plugin named uploadify, and it calls for the script to upload files:
'script': '<%= ResolveUrl("~/Build/UploadImages")%>/<%= ViewData["build_id"] %>',
in the browser show like this:
'script': '/prod/cms/Build/UploadImages/680ad442-8e9c-459c-b253-e9c389c1622b',
the problem is that the folder 'Build' doens't exist, i think it's created by asp.net....
I can't find the code that uploads the file... I searched everywhere with the words 'SaveAs', 'SaveFileAs', 'Upload', 'Uploadify' in all files, and i still haven't found it yet...
the problem that uploadify gives is 'HTTP Error' after it show 100% of upload, I searched on google but no luck... i think if i found the script that uploads the file, maybe i can fix it
here's the all script of my file:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Framework.Models.Image>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Photo
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
Photo</h2>
<p>
<label>
Tipo:</label>
<%= Html.DropDownList("type", (SelectList)ViewData["types"], new { onchange = "changeScript(this.value)" })%>
</p>
<div id="dvUpload">
<input id="upload" name="upload" type="file" />
Fazer Upload | Limpar Uploads
</div>
<%-- <% using (Html.BeginForm("UploadImages", "build", new { id = ViewData["build_id"], type = "c1956908-64f5-4195-ba73-4d7710d560d7" }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<input id="File1" name="upload" type="file" />
<input type="submit" value="Enviar" />
<%} %>--%>
<br />
<br />
<table>
<tr>
<th>
</th>
<th>
Type
</th>
<th>
Imagem
</th>
<th>
Legenda
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%= Html.ActionLink("Apagar", "deleteimage", new { id = item.Properties.id, build_id = item.Properties.build_id }, new { onclick = "return confirm('Confirma esta ação?')" })%>
</td>
<td>
<%= Html.Encode(item.Type)%>
</td>
<td>
<img src="<%= Cms.Helpers.Settings.CMS_ADDRESS + item.Properties.url_address %>" width="150" height="100" />
</td>
<td>
<%= Html.TextBox(item.Properties.id.ToString(), item.Properties.description) %>
<input type="button" value="Ok" onclick="saveLegend('<%= item.Properties.id.ToString() %>')" />
</td>
</tr>
<% } %>
</table>
<p>
<%= Html.ActionLink("Create New", "Create") %>
</p>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="HeaderContent" runat="server">
<script type="text/javascript" src="<%= ResolveUrl("~/Content/JS/swfobject.js") %>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Content/JS/jQuery/jquery.uploadify.v2.1.0.js") %>"></script>
<script type="text/javascript">
var html = "";
jQuery(document).ready(function() {
html = jQuery("#dvUpload").html();
jQuery("#upload").uploadify({
'uploader': '<%= ResolveUrl("~/Content/Flash/uploadfy.swf") %>',
'script': '<%= ResolveUrl("~/Build/UploadImages")%>/<%= ViewData["build_id"] %>',
'cancelImg': '<%= ResolveUrl("~/Content/Images/cancel.png") %>',
'folder': '<%= ResolveUrl("~/Content/Images") %>',
'multi': true,
'simUploadLimit': 10,
'fileDesc': 'Apenas Imagens são permitidas',
'fileExt': '*.gif;*.jpg;*.png',
'onError' : function(errorType) {
//alert('The error was ' + errorType.toSource());
alert(JSON.stringify(errorType, null, 4));
},
'onComplete': function() {
alert("foi tudo");
}
});
AddNullValueSelectObject('type');
});
function Upload(build_id) {
jQuery('#upload').uploadifyUpload();
}
function changeScript(val)
{
jQuery("#dvUpload").empty();
jQuery("#dvUpload").html(html);
var culture = jQuery('#culture').val();
jQuery("#upload").uploadify({
'uploader': '<%= ResolveUrl("~/Content/Flash/uploadfy.swf") %>',
'script': '<%= ResolveUrl("~/Build/UploadImages")%>/<%= ViewData["build_id"] %>?type=' + val,
'cancelImg': '<%= ResolveUrl("~/Content/Images/cancel.png") %>',
'folder': '<%= ResolveUrl("~/Content/Images") %>',
'multi': true,
'simUploadLimit': 10,
'fileDesc': 'Apenas Imagens são permitidas',
'fileExt': '*.gif;*.jpg;*.png',
'onError' : function(errorType) {
//alert('The error was: ' + errorType.toSource());
alert(JSON.stringify(errorType, null, 4));
},
'onComplete': function() {
alert("foi tudo");
}
});
}
function saveLegend(id)
{
var text = jQuery('#' + id).val();
jQuery.ajax({
type: 'GET',
url: '<%= ResolveUrl("~/build/UpdatePhotoLegend")%>/' + id,
data: 'legend=' + text,
success: function(data) {
alert('Alterado com sucesso!');
}
});
}
function AddNullValueSelectObject(object_id) {
jQuery('#' + object_id).append("<option value='00000000-0000-0000-0000-000000000000'>--- SELECIONE ---</option>");
jQuery("#" + object_id + " option[value='00000000-0000-0000-0000-000000000000']").attr('selected', 'selected');
}
</script>
</asp:Content>
thanks in advance...
Normally I wouldn't answer unless I was fairly sure of my answer, however, since noone else is responding...
I have no experience with uploadify but it looks like you are using an old version of uploadify and the api has changed quite a bit so it's hard for me to say for sure. I think the 'script' parameter is actually referring to the server side "script" that would normally handle the saving of the uploaded file (the 'uploader' parameter in the current version http://www.uploadify.com/documentation/uploadify/uploader/).
Do you have a BuildController class with an UploadImages action (method)? If so, that is probably one of the causes of your error (something erroring while saving to disk). If you do have a BuildController, I wonder if that call to resolve url is correct? The resolved path looks off to me (normally you would not resolve a route based url in mvc as resolve url isn't route aware).
If you don't have a BuildController and I'm totally off let me know and I'll remove this answer. It's somewhat a shot in the dark. But it is plausible.
EDIT: Just in case you have no experience in MVC at all, the code from the "Build folder" should be located in your mvc web app under a folder called Controllers inside a class called BuildController inside a Method called UploadImages.
Promoted my comment to an answer
It's possible that the script is embedded as a resource. Try using ILSpy to confirm this. In that case you will need to access the source code. Also, it maybe that the script was minified/obfuscated and that's why you can't find anything.
Related
I study javascript. Got to ajax requests. Everything works fine in mvc. I decided to try on web forms. Trying to post a new entry on the page, please tell me what I'm doing wrong. Here is my code. The page code acts as the main view:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Tables.aspx.cs" Inherits="WebApplication1.Tables" %>
<!DOCTYPE html>
<script src="../../Scripts/jquery-1.8.0.min.js"></script>
<script src="../../Scripts/jquery.unobtrusive-ajax.js"></script>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
</head>
<body>
<div>
<table id="tab" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1408</td>
<td>Stiven King</td>
<td>500</td>
</tr>
</tbody>
</table>
</div>
<form id="form1" runat="server">
<asp:TextBox ID="txbName" runat="server"></asp:TextBox>
<asp:TextBox ID="txbAuthor" runat="server"></asp:TextBox>
<asp:TextBox ID="txbPrice" runat="server"></asp:TextBox>
<input id="btnAdd" type="submit" value="Добавить" />
</form>
</body>
</html>
<script>
$('#btnAdd').on('click', function () {
$.ajax({
type: "POST",
url: "Tables.aspx/AddBook",
data: JSON.stringify({
"Name": $('#txbName').val(),
"Author": $('#txbAuthor').val(),
"Price": $('#txbPrice').val()
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (MyDT) {
$('#tab tbody').append(MyDT);
},
error: function (xhr) {
alert(xhr.statusCode)
}
});
});
</script>
Web method code, controller:
[WebMethod]
public static string AddBook(string Name, string Author, int Price)
{
db = new Context();
string html = "";
Book book = new Book() { Name = Name, Author = Author, Price = Price };
db.Books.Add(book);
db.SaveChanges();
html = GetHTMLRow(book);
return html;
}
And another method of obtaining html code for further adding an entry to the page, something like a partial view on which the entry is going to:
public static string GetHTMLRow(Book book)
{
string htmlRow = $"<tr><td>{book.Name}</td><td>{book.Author}</td><td>{book.Price}</td></tr>";
return htmlRow;
}
My code is completely working, but for some reason the page is restarted. But shouldn't ajax request work asynchronously without touching the page? In MVC everything works fine. And then why not? What can be wrong?
when you click the button it submits the form(because the type is set to "submit"). change it to "button"
<input id="btnAdd" type="button" value="Добавить" />
I have a model from ADO.NET, so it's Linq. I can show my tables perfectly, but now I want to add a div where I show the details of the item with a button (the button contains the id_element).
I decided to use JQuery and AJAX to do this. Let's resume: I have an Index view, and I have a partial view with the "details content".
I receive an ERROR from AJAX instead of success.
Here my Index View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<AppDataGrid.Models.EMPRESA>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<table>
<tr>
<th>ID Centro</th>
<th>ID Elemento</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td><%: item.ID_CENTRO %></td>
<td><%: item.id_elemento %></td>
<%-- <td><%: item.Fecha_Llegada_Centro %></td>
<td><%: item.Fecha_Salida_Centro %></td>--%>
<td> <%: Html.ActionLink("Detalles", "Welcome", new { id=item.id_elemento })%></td>
<td><button id="detalle" onclick="send();" value="<%:item.id_elemento%>">DETALLE</button></td>
</tr>
<tr id="result">
</tr>
<% } %>
</table>
<%-- <div id="result">
</div>--%>
<script type="text/javascript">
function send() {
document.getElementById("detalle").addEventListener("click", function (event) {
event.preventDefault()
});
var id_elem = document.getElementById("detalle").value;
updateServerText(id_elem);
}
function updateServerText(id_elem) {
document.getElementById("detalle").disabled = true;
$.ajax({
cache: false,
url: '<%= Url.Action("Welcome", "Store") %>',
type: "GET",
data: {
id: id_elem
},
contentType: "application/html",
dataType: "html",
success: function (msg) {
partialView = $(msg);
$("#result").append(partialView);
//$("#result").html(msg).show("slow");
}
,
error: function (msg) {
$("#result").html("Bad parameters!").show("slow");
}
});
}
</script>
</asp:Content>
Here is my Controller:
StoreModelDataContext context = new StoreModelDataContext();
public ActionResult Index()
{
return View(context.EMPRESA.Where);
}
public PartialViewResult Welcome(int id)
{
return PartialView(context.EMPRESA.Where(c => c.id_elemento == id)
.Select(c => c));
}
Here is the Partial View (Welcome):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AppDataGrid.Models.EMPRESA>" %>
<div>
<%= ViewData.Model.ID_CENTRO %>
<%= ViewData.Model.id_elemento %>
</div>
NOTE: If I do that with a MasterView there is no problem, except that I can only do it for one, not far all, so it's not a solution. I can do it if I don't use StrongTyped View but I can't access the model, so that's why I'm here asking you.
I have to say that I am using MVC 2, is that only working on later versions?
EDIT: I've tested with MVC 4 and I have the same result.
Anyway, thanks for your help and sorry if you have to read a lot. Feel free to ask me anything you need.
Trying to get a form to autofill the City and State textboxes when I enter in the Zip Code.
The code below is what I'm trying to use. If I replace the <asp:TextBox> with a <input type..> it work's but I specifically need to use <asp:TextBox> for my fields. Does anyone have a tips on how I can get this to work?
Here is a jsfiddle of it working with input's: http://jsfiddle.net/7VtHc/5/
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"> </script>
<script type='text/javascript'>
$(window).load(function () {
$(document).ready(function () {
$("#zipTxtBox").keyup(function () {
var el = $(this);
if (el.val().length === 5) {
$.ajax({
url: "http://zip.elevenbasetwo.com",
cache: false,
dataType: "json",
type: "GET",
data: "zip=" + el.val(),
success: function (result, success) {
$("#cityTxtBox").val(result.city);
$("#stateTxtBox").val(result.state);
}
});
}
});
});
});
</script>
<div class="row">
<div class="col-xs-6">
<asp:Label ID="Label13" runat="server" Text="Zip Code" />
<asp:TextBox ID="zipTxtBox" runat="server" />
</div>
<div class="col-xs-3">
<asp:Label ID="Label15" runat="server" Text="City" />
<asp:TextBox ID="cityTxtBox" runat="server" />
</div>
<div class="col-xs-2">
<asp:Label ID="Label16" runat="server" Text="State" />
<asp:TextBox ID="stateTxtBox" runat="server" />
</div>
</div>
in order to use ASP.NET Server Controls you need to use their ID's (if you see the source code, your textbox have a weird id, and not the one you specified in the ID attribute of the control.
If you're using an old version of WebForms (below .NET 3.5 - inclusive) you need to use:
$("#<%= cityTxtBox.ClientID %>").val(result.city);
$("#<%= stateTxtBox.ClientID %>").val(result.state);
the same when you pull the zip code:
$("#<%= zipTxtBox.ClientID %>").keyup( ...
if you have a recent WebForms version (.NET 4+) all you need to set is set ClientIDMode to static and then you can use the normal code as you had, like:
<asp:TextBox ID="cityTxtBox" ClientIDMode="static" runat="server" />
more on static controls in Scott's Guthrie blog entry
I have a problem that's been driving me crazy for days. So I have an html table with items in it. The point is basically to click a button and open a jquery dialog with a message, asking me if I want to delete the selected item. Now the delete part can come next cause as it is I can't even display the dialog with the confirmation message. What I do is click one of the delete icons on my table to delete an item of my choosing, but as the partialview with the dialog finishes loading, jquery throws an undefined function error. The following pattern has already been implemented on another similar funcionality (table with clickable icon, shows dialog) but I can't find out whats wrong here.
Here's the code of the table in the "main" view.
<table width="100%" cellspacing="0" border="0" align="center" cellpadding="3"
style='table-layout: fixed'>
<tr class="tr-header">
<th width="20px">
</th>
<th width="200px">
File Name
</th>
<th width="120px">
Type
</th>
<th width="130px">
Date
</th>
<th width="480px">
Comments
</th>
</tr>
#foreach (var item in Model.Uploads)
{
<tr>
<td align="center">
#using (Ajax.BeginForm("DeleteUpload", "Candidate",
new { id = item.UploadID },
new AjaxOptions { UpdateTargetId =
"DeleteUploadForm",
HttpMethod = "Get" }))
{
#*<a href='#Url.Action("DeleteUpload", new { id = item.UploadID })'>
<img src="#Url.Content("~/icons/delete.png")" alt="Click to delete upload" border="0" /></a>*#
<input type="image" name="DeleteUpload" id="DeleteUpload" src="#Url.Icon("delete.png")"/>
}
</td>
<td align="center">
#(item.FileName);
</td>
<td align="center" nowrap="nowrap">
#item.UploadType
</td>
<td align="center" nowrap="nowrap">
#item.UploadDate
</td>
<td align="justify" style="overflow:auto">
#Html.Raw(Html.Encode(item.Comments).Replace("\n", "<br />"))
</td>
</tr>
}
</table>
<div id="DeleteUploadForm">
</div>
As you notice in the first column I have two ways of calling the controller commented, the one with the input image doesn't do a submit when I click it and the anchor link can call the controller and the partialview where I have the dialog, but jQuery library "crashes" when its all done.
This is the controller.
public ActionResult DeleteUpload(int id)
{
Upload UploadToDelete = CandidateProxy.GetUploadByID(this.CurrentUser.DbInfo, id);
return PartialView(UploadToDelete);
}
Nothing too spectacular there. Then it calls the following partial view.
#model Project.Entities.Uploads
<script src="#Url.Script("jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Script("jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Script("jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.core.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.widget.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery-ui-1.8.23.custom.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.mouse.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.button.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.draggable.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.position.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.resizable.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.ui.dialog.js")" type="text/javascript"></script>
<script src="#Url.Script("ui/jquery.effects.core.js")" type="text/javascript"></script>
<script src="#Url.Script("dialog/DeleteUploadDialog.js")" type="text/javascript"></script>
<div="DeleteUploadDialog">
#using (Html.BeginForm("DeleteUpload", "Home", FormMethod.Post))
{
<fieldset>
<div>
<br />
Do you want to delete the following file? #Model.UploadName
</div>
<input type="submit" name="submit" value="Delete" class="toolbar-button" />
<input type="button" name="submit" value="Cancel" class="toolbar-button" />
</fieldset>
}
</div>
This is the partialview that holds the design for my dialog. It will eventually send to the Controller a request to delete an upload which is easy cause I'm more familiar with server-side coding but this whole front-end thing is very new to me. Finally here's the DeleteUploadDialog.js file where I have written the dialog's properties.
$(function () {
$("#DeleteUploadDialog").dialog({
autoOpen: true,
modal: true,
width: 950,
height: 350,
close: function (event, ui) {
$("#DeleteUploadDialog").remove();
}
});
});
So that's my code. Anything else you'd like to know about it let me know. Thanks in advance!
Making a server round trip just for confirmation is not a good idea. you can take confirmation on client side using below custom confirmation dialog. This will not block your script execution also.
I have created custom confirmation box, you may try this:
function ConfirmationBox(pTitle, pText, pButtonType, pParam, pCallBack, pCancelCallback) {
if (pButtonType == null) pButtonType = "okcancel";
$('<div></div>').appendTo('body').html(pText)
.dialog({
resizable: false,
modal: true,
title: pTitle,
buttons: GetButtons(pButtonType),
autoOpen: true,
width: 'auto'
, Close: function (event, ui) {
$(this).remove();
}
});
$("input[type=submit], input[type=button]").button();
$("#confirmDialog button").button();
return this;
function GetButtons(pButtonType) {
var cBtn;
switch (pButtonType) {
case "yesno":
cBtn = {
"Yes": function () {
if (pCallBack && pCallBack.length > 0) {
window[pCallBack](pParam);
}
$(this).dialog("close");
return true;
},
"No": function () {
if (pCancelCallback && pCancelCallback.length > 0) {
window[pCancelCallback](pParam);
}
$(this).dialog("close");
return false;
}
}
break;
case "okcancel":
cBtn = {
"Ok": function () {
if (pCallBack && pCallBack.length > 0) {
window[pCallBack](pParam);
$(this).dialog("close");
}
return true;
},
Cancel: function () {
if (pCancelCallback && pCancelCallback.length > 0) {
window[pCancelCallback](pParam);
$(this).dialog("close");
}
return false;
}
}
break;
}
return cBtn;
}
}
Parameter details:
pTitle: Title of your dialog
pText: Text of dialog
pButtonType: Here we have 2 option yesno | okcancel
pParam: parameter to callback function
pCallBack: Success callback (function to call on "Yes" click)
pCancelCallback: Cancel callback (function to call on "No" click )
I think that what you are trying to do here is an overhead. You are opening a dialog and removing it on close.. Wouldn't be simpler to do sth like this:
$(buttonDelete).click(function () {
var confirmDelete = confirm("Are you sure you want to delete this item?");
if (confirmDelete === true) {
$.ajax({
url: '/Home/DeleteAttachment',
dataType: "json",
type: "POST",
data: { "id": id },
success: function () {
$(rowToDelete).remove();
}
});
}
});
and
[HttpPost]
public JsonResult DeleteAttachment(int id)
{
DeleteAttachment(id);
return Json("ok");
}
if you really want to return partial you can do sth like this:
$(buttonDelete).click(function () {
var confirmDelete = confirm("Are you sure you want to delete this item?");
if (confirmDelete === true) {
$.ajax({
url: '/Home/DeleteAttachment',
dataType: "html",
type: "POST",
data: { "id": id },
success: function (response) {
$(divId).replace(response);
}
});
}
});
and
[HttpPost]
public PartialViewResult DeleteAttachment(int id)
{
Upload UploadToDelete = CandidateProxy.GetUploadByID(this.CurrentUser.DbInfo, id);
return PartialView(UploadToDelete);
}
Shouldn't it be
autoOpen: false
instead of
autoOpen: true
Then in your click event something like
$("#DeleteUpload").click(function()
{
$("#DeleteUploadDialog").dialog("open");
});
First, I want to let everyone know that I am using an aspx engine not a Razor engine.
I have a table within a form. One of my textbox contains html tags like
</br>Phone: </br> 814-888-9999 </br> Email: </br> aaa#gmail.com.
When I go to build it it it gives me an error that says:
A potentially dangerous Request.Form value was detected from the client (QuestionAnswer="...ics Phone:<br/>814-888-9999<br...").
I tried the validation request="false" but it did not work.
I am sorry I didn't add my html code for you to look at so far. I am pulling some question up where I can edit it, if need be.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
EditFreqQuestionsUser
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(document).ready(function () {
$("#freqQuestionsUserUpdateButton").click(function () {
$("#updateFreqQuestionsUser").submit();
});
});
</script>
<h2>Edit Freq Questions User </h2>
<%Administrator.AdminProductionServices.FreqQuestionsUser freqQuestionsUser = ViewBag.freqQuestionsUser != null ? ViewBag.freqQuestionsUser : new Administrator.AdminProductionServices.FreqQuestionsUser(); %>
<%List<string> UserRoleList = Session["UserRoles"] != null ? (List<string>)Session["UserRoles"] : new List<string>(); %>
<form id="updateFreqQuestionsUser" action="<%=Url.Action("SaveFreqQuestionsUser","Prod")%>" method="post" onsubmit+>
<table>
<tr>
<td colspan="3" class="tableHeader">Freq Questions User Details <input type ="hidden" value="<%=freqQuestionsUser.freqQuestionsUserId%>" name="freqQuestionsUserId"/> </td>
</tr>
<tr>
<td colspan="2" class="label">Question Description:</td>
<td class="content">
<input type="text" maxlength="2000" name="QuestionDescription" value=" <%=freqQuestionsUser.questionDescription%>" />
</td>
</tr>
<tr>
<td colspan="2" class="label">QuestionAnswer:</td>
<td class="content">
<input type="text" maxlength="2000" name="QuestionAnswer" value="<%=freqQuestionsUser.questionAnswer%>" />
</td>
</tr>
<tr>
<td colspan="3" class="tableFooter">
<br />
<a id="freqQuestionsUserUpdateButton" href="#" class="regularButton">Save</a>
Cancel
</td>
</tr>
</table>
</form>
</asp:Content>
before the page is submitted you need to html encode the textbox's value, with window.escape(...)
If you need the un-escaped text on the server side then use HttpUtility.UrlDecode(...) method.
very quick sample:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="SO.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script>
function makeSafe() {
document.getElementById('TextBox1').value = window.escape(document.getElementById('TextBox1').value);
};
function makeDangerous() {
document.getElementById('TextBox1').value = window.unescape(document.getElementById('TextBox1').value);
}
</script>
</head>
<body>
<form id="form1" runat="server" onsubmit="makeSafe();">
<div>
<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Rows="10" ClientIDMode="Static"></asp:TextBox>
</div>
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
<script>
makeDangerous();
</script>
</body>
</html>
Make these changes to your code:
<script type="text/javascript">
$(document).ready(function () {
makeDangerous();
$("#freqQuestionsUserUpdateButton").click(function () {
makeSafe();
$("#updateFreqQuestionsUser").submit();
});
});
// Adding an ID attribute to the inputs you want to validate is simplest
// Better would be to use document.getElementsByTagName and filter the array on NAME
// or use a JQUERY select....
function makeSafe() {
document.getElementById('QuestionAnswer').value = window.escape(document.getElementById('QuestionAnswer').value);
};
// In this case adding the HTML back to a textbox should be 'safe'
// You should be very wary though when you use it as actual HTML
// You MUST take steps to ensure the HTML is safe.
function makeDangerous() {
document.getElementById('QuestionAnswer').value = window.unescape(document.getElementById('QuestionAnswer').value);
}
</script>
Decorate your controller action with the [ValidateInput] attribute:
[ValidateInput(false)]
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
...
}
Client JavaScript:
function codificarTags()
{
document.getElementById('txtDescripcion').value = document.getElementById('txtDescripcion').value.replace(/</g,'<').replace(/>/g,'>');
}
<form id="form1" runat="server" onsubmit="codificarTags();">
Server:
protected void Page_Load(object sender, EventArgs e)
{
txtDescripcion.Text = txtDescripcion.Text.Replace(#"<", #"<").Replace(#">", #">");
}
I would suggest using the AjaxControlToolkit's HTML Editor. I'm implementing that now. If you're textbox is multi-line and big enough to accommodate HTML, why not just bump it up to an HTML editor. Your user will be happier too.
http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/HTMLEditor/HTMLEditor.aspx
Using html in textbox is not a good practice, maybe use linebreaks (Environment.NewLine) or \r\n instead of br ?
.NET Reference
Example (in C#) :
textBox1.Multiline = true;
textBox1.Text = "test" + Environment.NewLine + "test2";
I took a bit of a different approach. I wanted to use html textboxes widely across my application. I made a user control which would avoid editing the javascript every time I added a new control. My entire control is very custom but the heart of the html handling is as seen below.
The UserControl markup has some simple javascript to escape and unescape the textbox.
<script type="text/javascript">
function UnescapeControl(clientId) {
$('#' + clientId).val(window.unescape($('#' + clientId).val()));
}
function EscapeAllControls() {
var escapeControList = JSON.parse('<%= new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(EscapeControlList) %>');
for (var i = 0; i < escapeControList.length; i++)
EscapeControl(escapeControList[i]);
}
function EscapeControl(textClientId) {
document.getElementById(textClientId).value = window.escape(document.getElementById(textClientId).value);
}
</script>
<asp:TextBox ID="Txt_SavableText" CssClass="form-control" Width="100%" runat="server" ></asp:TextBox>
The code behind is responsible for escaping the controls before the post back using RegisterOnSubmitStatement and unescaping them using RegisterStartupScript after the post back.
public partial class SavableTextBox : System.Web.UI.UserControl
{
public List<string> EscapeControlList
{
get
{
if (Session["STB_EscapeControlList"] == null)
Session["STB_EscapeControlList"] = new List<string>();
return (List<string>)Session["STB_EscapeControlList"];
}
set { Session["STB_EscapeControlList"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (EscapeHtmlOnPostback && !EscapeControlList.Contains(GetClientId()))
EscapeControlList.Add(GetClientId());
// When using a script manager, you should use ScriptManager instead of ClientScript.
if (EscapeHtmlOnPostback)
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "UnescapeControl_" + GetClientId(), "UnescapeControl('" + GetClientId() + "');", true);
// Ensure we have our escape script called before all post backs containing escapable controls.
// This is like calling OnClientClick before everything.
if (EscapeControlList != null && EscapeControlList.Count > 0)
this.Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "SaveableTextBoxEscaper", "EscapeAllControls();");
}
public string Text
{
get
{
return Txt_SavableText.Text;
}
set
{
Txt_SavableText.Text = value;
}
}
public string GetClientId()
{
return Txt_SavableText.ClientID;
}
}
Now we can use it anywhere like this while setting EscapeHtmlOnPostback="True".
<%# Register TagPrefix="STB" TagName="SavableTextBox" Src="~/SavableTextBox.ascx" %>
<STB:SavableTextBox ID="Txt_HtmlTextBox" EscapeHtmlOnPostback="True" runat="server" />
Note, when we access Txt_HtmlTextBox.Text during the post back it will already be escaped for us.