I am currently using an Ajax tool; HTMLEditorExtender to turn a textbox into a WYSIWYG editor, in a C# ASP.NET project. On the initial page load I place a large amount of formated text and tables into the editor which appears fine; even the tables.
The data is loaded into an asp:panel and the items/display from the panel is what is actually loaded into the extender and displayed.
However, if I want to have a button that saves all of the data that is in the editor to a Session and after the button press still display everything in the WYSIWG editor on the page postback everything that loads in the the textbox is fine except for the tables. They come up with the tags. Is there anyway around this?
The code I am using to initially load the page is this:
ContentPlaceHolder cphMain = (ContentPlaceHolder)this.Master.FindControl("MainContent");
Panel pnlContent = (Panel)cphMain.FindControl("innerFrame");
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(sw);
pnlContent.RenderControl(hw);
txtPN.Text = sb.ToString();
pnlContent.Visible = false;
On the button click I am having this saved:
string strHTMLText = txtPN.Text;
Session["ProgressNoteHTML"] = strHTMLText;
And I am loading it on the postback like this:
txtPN.Text = (string)Session["ProgressNoteHTML"];
ContentPlaceHolder cphMain = (ContentPlaceHolder)this.Master.FindControl("MainContent");
Panel pnlContent = (Panel)cphMain.FindControl("innerFrame");
pnlContent.Visible = false;
Any ideas as to why any postbacks would make the tags appear and in the original page load they do not?
The solution offered by Erik won't work for table tags containing property values. For instance: <table align="right"> will not be decoded. I have also found that <img> tags are encoded by the HTMLEditorExtender as well.
The easier solution is to use the Server.HTMLDecode() method.
TextBox_Editor.Text = Server.HtmlDecode(TextBox_Editor.Text) 'fixes encoding bug in ajax:HTMLEditor
I have the same problem, It seems to have something to do with the default sanitizing that the extension performs on the HTML content. I haven't found a way to switch it off, but the workaround is pretty simple.
Write an Anti-Sanitizing function that replaces the cleansed tags with proper tags. Below is mine written in VB.Net. A C# version would look very similar:
Protected Function FixTableTags(ByVal input As String) As String
'find all the matching cleansed tags and replace them with correct tags.
Dim output As String = input
'replace Cleansed table tags.
output = output.Replace("<table>", "<table>")
output = output.Replace("</table>", "</table>")
output = output.Replace("<tbody>", "<tbody>")
output = output.Replace("</tbody>", "</tbody>")
output = output.Replace("<tr>", "<tr>")
output = output.Replace("<td>", "<td>")
output = output.Replace("</td>", "</td>")
output = output.Replace("</tr>", "</tr>")
Return output
End Function
Related
I'm trying to scrape the team win-loss record data from the NBA website here. Here's an image of the lines of text I want to capture, it is circled in black:
Can someone try scraping this exact data and seeing if it works? I've been at it for hours and nothing is working. I was able to scrape the team names and start times but when I try using jsoup's select function on the record lines, I get 0 results back. It's as if the tags are hidden from the html hierarchy. Is this possible? I'm new to this and I may be doing something wrong.
Code I have tried:
Document document = Jsoup.connect("http://espn.go.com/nba/scoreboard/_/date/20160315").get();
games = document.select("section.sb-score");
for(Element game : games)
{
mHomeTeam = game.select("td.home").select("div.sb-meta").text();
Elements test = game.select("p.record.overall");
mAwayTeam = game.select("td.away").select("div.sb-meta").text();
mHomeTeamRecord = game.select("td.home").select("div.record-container").select("p.record").text();
mAwayTeamRecord = game.select("td.away").select("div.record-container").select("p.record").text();
mGameStartTime = game.select("span.time").text();
Game newGameObj = new Game(mHomeTeam, mAwayTeam, mGameStartTime, mHomeTeamRecord, mAwayTeamRecord);
mGameList.add(newGameObj);
}
The team win-loss record data is loaded by Javascript in the page. Since Jsoup is an HTML parser this is why it's not displaying tags with the select() method.
However, it seems this data is located inside the page directly in a Javascript object called window.espn.scoreboardData.
Here is how to extract this data:
Document doc = Jsoup.connect("http://espn.go.com/nba/scoreboard/_/date/20160315").get();
for(Element script : doc.select("script")) {
String scriptData = script.html();
if (scriptData.contains("window.espn.scoreboardData")) {
// Parse scriptData to extract team win-loss record ...
}
}
I am trying to convert html to word. I have found so many codes over the net but none of them works. They are worked with string builder or some with others. I have given a code. In debugger it goes through all the codes without error but no file is getting downloaded.
public void converToWord(string htmlContent,string name)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/msword";
string strFileName = name + ".doc";
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline;filename=" + strFileName);
StringBuilder strHTMLContent = new StringBuilder();
strHTMLContent.Append("<html xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:word\" xmlns=\"http://www.w3.org/TR/REC-html40\"><head></head><body>");
strHTMLContent.Append(htmlContent);
strHTMLContent.Append("</body></html>");
HttpContext.Current.Response.Write(strHTMLContent);
HttpContext.Current.Response.End();
HttpContext.Current.Response.Flush();
}
i got an error it says {Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
while the button is in update panel and it does not work properly.everything seems fine but it does not get downloaded.it is a very common problem that happens.just put o a trigger to the button that is firing the event and it will start to work just very much fine.
How i can allow client to use html tags in MVC 4?
I would like to save records to the database and when it extract in view allow only some HTML tags (< b > < i > < img >) and others tags must be represented as text.
My Controller:
[ValidateInput(false)]
[HttpPost]
public ActionResult Rep(String a)
{
var dbreader = new DataBaseReader();
var text = Request["report_text"];
dbreader.SendReport(text, uid, secret).ToString();
...
}
My View:
#{
var dbreader = new DataBaseReader();
var reports = dbreader.GetReports();
foreach (var report in reports)
{
<div class="report_content">#Html.Raw(report.content)</div>
...
}
}
You can replace all < chars to HTML entity:
tags = tags.Replace("<", "<");
Now, replace back only allowed tags:
tags = tags
.Replace("<b>", "<b>")
.Replace("</b>", "</b>")
.Replace("<i>", "</i>")
.Replace("</i>", "</i>")
.Replace("<img ", "<img ");
And render to page using #Html.Raw(tags)
If you are trying some property of your view model object to accept Html text, use AllowHtmlAttribute
[AllowHtml]
public string UserComment{ get; set; }
and before binding to the view
model.UserComment=model.UserComment.Replace("<othertagstart/end>",""); //hard
Turn off validation for report_text (1) and write custom HTML encoder (2):
Step 1:
Request.Unvalidated().Form["report_text"]
More info here. You don't need to turn off validation for entire controller action.
Step 2:
Write a custom html encoder (convert all tags except b, i, img to e.g.: script -> ;ltscript;gt), since you are customizing a default behaviour of request validation and html tag filtering. Consider to safeguard yourself from SQL injection attacks by checking SQL parameters passed to stored procedures/functions etc.
You may want to check out BBCode BBCode on Wikipedia. This way you have some control on what is allowed and what's not, and prevent illegal usage.
This would work like this:
A user submits something like 'the meeting will now be on [b]monday![/b]'
Before saving it to your database you remove all real html tags ('< ... >') to avoid the use of illegal tags or code injection, but leave the pseudo tags as they are.
When viewed you convert only the allowed pseudo html tags into real html
I found solution of my problem:
html = Regex.Replace(html, "<b>(.*?)</>", "<b>$1</b>");
html = Regex.Replace(html, "<i>(.*?)</i>", "<i>$1</i>");
html = Regex.Replace(html, "<img(?:.*?)src="(.*?)"(?:.*?)/>", "<img src=\"$1\"/>");
I've got a form in .NET.
when the user presses submit, a sub is launched to check all checkboxes, radiobuttons, etc...
and when there's an issue, i'm adding the specific issue to a stringbuilder
as per below
Dim errors As New StringBuilder
If APACradio.Checked = False And EMEAradio.Checked = False And LATAMCANADAradio.Checked = False Then
errors.AppendLine(" You must select a Region")
End If
If CountryDDL.SelectedValue = "Select" Then
errors.AppendLine(" You must select a Country")
End If
If EmploymentDDL.SelectedValue = "Select" Then
errors.AppendLine(" You must select a Employment Type")
End If
etc....
At the end of the check, i would like a Colorbox to appear, listing the lines of the stringbuilder, one by one.
I've worked with colorbox's inline HRef's before and i love that but this is a bit different as i can not preload my document with the code here.
Colorbox page itself shows samples on how to load a HTML page (sample 5) but my HTML i want to show would be rather in memory than on a disk somewhere
Why not use ColorBox's html property? Example:
$.colorbox({html:function(){
var html = '';
// do your formatting
return html;
}});
I have a simple function that I want to call in the code behind file name Move
and I was trying to see how this can be done and Im not using asp image button because not trying to use asp server side controls since they tend not to work well with ASP.net MVC..the way it is set up now it will look for a javascript function named Move but I want it to call a function named move in code behind of the same view
<img alt='move' id="Move" src="/Content/img/hPrevious.png" onclick="Move()"/>
protected void Move(){
}
//based on Search criteria update a new table
protected void Search(object sender EventArgs e)
{
for (int i = 0; i < data.Count; i++){
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell CheckCell = new HtmlTableCell();
HtmlTableCell firstCell = new HtmlTableCell();
HtmlTableCell SecondCell = new HtmlTableCell();
CheckBox Check = new CheckBox();
Check.ID = data[i].ID;
CheckCell.Controls.Add(Check);
lbl1.Text = data[i].Date;
lbl2.Text = data[i].Name;
row.Cells.Add(CheckCell);
row.Cells.Add(firstCell);
row.Cells.Add(SecondCell);
Table.Rows.Add(row);
}
}
Scott Guthrie has a very good example on how to do this using routing rules.
This would give you the ability to have the user navigate to a URL in the format /Search/[Query]/[PageNumber] like http://site/Search/Hippopotamus/3 and it would show page 3 of the search results for hippopotamus.
Then in your view just make the next button point to "http://site/Search/Hippopotamus/4", no javascript required.
Of course if you wanted to use javascript you could do something like this:
function Move() {
var href = 'http://blah/Search/Hippopotamus/2';
var slashPos = href.lastIndexOf('/');
var page = parseInt(href.substring(slashPos + 1, href.length));
href = href.substring(0, slashPos + 1);
window.location = href + (++page);
}
But that is much more convoluted than just incrementing the page number parameter in the controller and setting the URL of the next button.
You cannot do postbacks or call anything in a view from JavaScript in an ASP.NET MVC application. Anything you want to call from JavaScript must be an action on a controller. It's hard to say more without having more details about what you're trying to do, but if you want to call some method "Move" in your web application from JavaScript, then "Move" must be an action on a controller.
Based on comments, I'm going to update this answer with a more complete description of how you might implement what I understand as the problem described in the question. However, there's quite a bit of information missing from the question so I'm speculating here. Hopefully, the general idea will get through, even if some of the details do not match TStamper's exact code.
Let's start with a Controller action:
public ActionResult ShowMyPage();
{
return View();
}
Now I know that I want to re-display this page, and do so using an argument passed from a JavaScript function in the page. Since I'll be displaying the same page again, I'll just alter the action to take an argument. String arguments are nullable, so I can continue to do the initial display of the page as I always have, without having to worry about specifying some kind of default value for the argument. Here's the new version:
public ActionResult ShowMyPage(string searchQuery);
{
ViewData["SearchQuery"] = searchQuery;
return View();
}
Now I need to call this page again in JavaScript. So I use the same URL I used to display the page initially, but I append a query string parameter with the table name:
http://example.com/MyControllerName/ShowMyPage?searchQuery=tableName
Finally, in my aspx I can call a code behind function, passing the searchQuery from the view data. Once again, I have strong reservations about using code behind in an MVC application, but this will work.
How to call a code-behind function in aspx:
<% Search(ViewData["searchQuery"]); %>
I've changed the arguments. Since you're not handling an event (with a few exceptions, such as Page_Load, there aren't any in MVC), the Search function doesn't need the signature of an event handler. But I did add the "tablename" argument so that you can pass that from the aspx.
Once more, I'll express my reservations about doing this in code behind. It strikes me that you are trying to use standard ASP.NET techniques inside of the MVC framework, when MVC works differently. I'd strongly suggest going through the MVC tutorials to see examples of more standard ways of doing this sort of thing.