Edit HTML file using MVC w/ ACE Editor - c#

I am trying to build a page which can read the contents of a HTML file and output it's data to the screen.
To get the HTML files data I am doing:
ViewBag.PageHtml = System.IO.File.ReadAllText(#"W:\1.html");
Then in the View, I have the following
#Html.Raw(ViewBag.PageHtml)
The HTML data is this:
<html>
<head>
<title>Test Title</title>
</head>
<body>
<p>The body</p>
</body>
</html>
The result of the Html.Raw is this, some how the <html><head> etc tags are being removed.
<title>Test Title</title>
<p>The body</p>
Can someone please explain to me why this is, and how I can prevent it from happening?
Thanks in advance

I managed to solve this myself, the first step was to add a hidden textarea field.
<textarea id="templateHtml" style="display: none">#ViewBag.PageHtml</textarea>
I left the div empty like this
<div id="txtArea"></div>
Then I just used the value of the text area as the value of the ACE Editor.
var el = document.getElementById("txtArea");
editor = ace.edit(el);
editor.session.setValue($("#templateHtml").val());
editor.setTheme("ace/theme/github");
editor.getSession().setMode("ace/mode/html");
editor.setOption("showPrintMargin", false);

This is interesting to see.
It seems as if #Html.Raw sanitizes the input; which is usually a good idea.
In your case however; it seems to not help you that much.
However, having multiple <html>and <body> tags is not allowed. See this question: Multiple <html><body> </html></body> in same file
If you know that these tags are removed, then simply re-add them. With that said however; i think you are having the wrong approach to this.
If all you want to do is return a static HTML-file from a HTML-document, then you could just serve this "as is". If you are looking to do this "dynamically" somehow (maybe from a database or similar) then you should probably do it directly from the controller using a ContentResult.
namespace Project.Controllers
{
public class HomeController : Controller
{
public ContentResult ServePureHtml()
{
string htmlData = System.IO.File.ReadAllText(#"W:\1.html");
return Content(htmlData, "text/html");
}
}
}
You could use this as a partial result as well. Using Html.Action or Html.RenderAction
For instance
<!-- ... -->
<div class="editor-content">
#{
Html.RenderAction("ServePureHtml", "Home");
}
</div>
<!-- ... -->
Also, be cautious of using the ViewBag. Its behavior is usually not amazing.

Related

How can i retrieve the value of this element and assert it after a change is done?

I am working on automating an area of a web page (not able to provide the webpage as the contents are confidential, although will try to give as much insight as possible).
This element has on it an html code preview that will change after some selections are done. Here is the page html of the element:
<div _ngcontent-hje-c241="" class="field" style="position: relative;">
<pre _ngcontent-hje-c241="" class="code-pre">
"
<!doctype html>
<html>
<head>
<meta charset='utf'>
<title></title>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<style type='text/css'>body,html, #video {height:100%;margin:0;overflow:hidden;background-color:#000;}</style>
<script type='text/javascript'>
window.onload = function(event) {
var config = {containerID: 'video', Player: true, wmode: 'direct'};
myplayer = new Test.embed('WmAl', config);
}
</script>
</head>
<body>
<div id='video'></div>
</body>
</html>"
(I have edited and removed any confidentials parts of the string for the html, the html itself was not changed.)
I would need to get the value of the element I found through class="code-pre".
Here is what I have tried:
IWebElement htmlTest = driver.FindElement(By.ClassName("code-pre"));
var defaultHtmlTestValue = htmlTest.GetAttribute("value");
Assert.IsFalse(htmlTest.Equals(defaultHtmlTestValue), "The html has not changed after the Http selection");
The assert passes, altho, i would like to see what is the value that is being taken, as i feel like is not taking the html example i am trying to get.
I have also used Debug.Writeline(htmlTest) to see if it worked, but i got "Internal error in the expression evaluator". This is also an issue i will be trying to fix.
I am quite new to automation and stack overflow. Please let me know if there is a way i can improve this post.
I haven't worked with the html previews but looks like the whole html code is just the inner text of an element with class code-pre.
try doing :
String htmlTest = driver.FindElement(By.ClassName("code-pre")).getTex();
System.out.println(htmlTest);
Assert.assertTrue(htmlTest.Equals(defaultHtmlTestValue), "The html has not changed after the Http selection");
You can easily convert above java code into your language.

Render section inside layout file

I try to understand how works sections in Razor views. I have 2 layout files: _Layout.cshtml and _LayoutChild.cshtml which use the first layout inside. I try to declare sections in _Layout.cshtml and render it in the same file. Markup not appears but when I declare section in _LayoutChild.cshtml everything works. See example below:
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
#RenderSection("A", false)
</head>
<body>
#section A{
<script>
alert("I'm in Layout!");
</script>
}
</body>
</html>
_LayoutChild.cshtml
#{
Layout = "_Layout";
}
#section A{
<script>
alert("I'm in LayoutChild!");
</script>
}
I understand that declaring section in the same file looks strange but I would like to know why it don't work?
While developing web site or application. Every page have some common section like header, footer, sidebar etc. Write and maintain these on every page is a hard job. So, we need a way to put them in one single place. Luckily in MVC we have Layout concept for this. We put all the common code in it and changing content in Views which will render in layout where we call #RenderBody() method.
Why we need sections ?
Some time we wanted to show specific content on some specific pages like newletters only show on blogs and home page, top news or some advertising banners on specific pages. For these type of scenarios sections rescue us in MVC.
How we can use section ?
We need to follow these two steps to used sections in MVC.
Declare Section in Layout, give it a name and tell is it required on
every page or not.
Define it in view
When views render then section content also added where we declare the section.
Code Example
1. Most of the time we need some specific javascript code for view. So we can do it like this
_Layout.cshtml
#RenderSection("scripts", required: false)
view.cshtml
#section scripts{
<script>
alert("I'm in Layout!");
</script>
}
2. News Letter example
_Layout.cshtml
#RenderSection("newletter", required: false)
view.cshtml
#section newletter{
<h3> New Letter </h3>
... rest of the html ...
}

Render MVC View layout from database with Razor Helper

As per requirement, i need to retrieve html page layout from database (that system user can update through system) with some html helpers (Dropdown, TextBox etc).
<html>
<body>
<div>
#Html.DropDown(x=>x.SomeId,Model.ElementCollection)
</div>
<div>
#Html.TextBoxFor(x=>x.Property)
</div>
</body>
</html>
In the above example, i need to get html from database but before render the page i want added some html helper's.So it will work like formal page.
Tried Solution:
For this i have created Custom View Engine and i am replacing text into Render function of IView inherited class.but its not resolving html from helper.
Question:
Is there any to get html from htmlHelper.If yes, then i can simply replace string into action method and return Content from action method?
Suggest please.
I found some useful link, to implement same functionality with Custom View Engine and Virtual Views.
Link1 And Link2
Thanks :)

Including Javascript only if it has not yet been included in .NET MVC

In a .NET MVC partial view, I'd like to do something like this:
<% ScriptCollection.RequireScript("path/to/script.js"); %>
That would require a method in the ScriptCollection object that looks like this:
public void RequireScript(string src)
{
if (!_List.Contains(src))
_List.Add(src);
}
Then, in my Master page, I would have something like this:
<html>
<head></head>
<body>
<!-- Content would go here -->
<% foreach (var script in ScriptCollection) { %>
<script type="text/javascript" src="<%= script %>"></script>
<% } %>
</body>
</html>
My question is this:
How can I make the ScriptCollection object available to be updated by a partial view and also available to be used by a Master page?
Edit:
I do not want to add the required scripts in a controller, nor do I want to use a strongly typed Master page. Though suggestions on doing so are welcome if those methods are considered a best practice.
Edit #2:
This would be easy with extension properties. I could just give the HtmlHelper class the ScriptCollection property. Am I missing something like this that already exists?
I checked out the Telerik assemblies. They're a little overkill for what I need. Also, the open-source license (GPL v2) isn't the type I'm looking for.
I started a project licensed under the MIT open-source license and am hosting it on Google Code. It's a lightweight solution to my problem.
code.google.com/p/script-keeper
You could take a look at Telerik's ScriptRegisterBuilder class implementation which does exactly what you want. Or you can just use it as well. In addition it also has support for:
Combining multiple JS files into one which result in less requests by the browser.
Compressing JS files.
HTTP Caching.
Content Delivery Networks.
release/debug versions of your JS resources depending on your build mode.
Now even when you don't use any of the other stuff Telerik provides you can use the ScriptRegisterBuilder class but then it's advised to disable the automatic jquery & jquery validation script registration. See also the link provided.
Also take a look the StyleSheetRegistrarBuilder class. This is the nephew of the ScriptRegisterBuilder class and handles the CSS assets.
I did noticed the MVC2 tag in your question but my simple example uses razor and is just for making the point. It shouldn't be hard to make it work for MVC2/ASPX as well. Otherwise let me know.
Master
#using Telerik.Web.Mvc.UI
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
#Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("~/Content/Site.css"))
</head>
<body>
#RenderBody()
#Html.Telerik().ScriptRegistrar().jQuery(false).jQueryValidation(false)
</body>
</html>
Partial View
#using Telerik.Web.Mvc.UI
#{
ViewBag.Title = "Home Page";
Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("~/Content/Site2.css"));
Html.Telerik().ScriptRegistrar().DefaultGroup(group => group.Add("~/Scripts/Test.js"));
}
<h2>#ViewBag.Title</h2>
<p>
Bla bla bla
</p>

MVC and Meta Tags for Search Engine Optimization

I am working on mvc2. I want used Meta tags. I am new on the meta tags and seo. How can used meta tags on my page? What is the best way to used meta tags on mvc?
From a programmer/technology point of view: meta tags are just tags.
What the content of your meta tags should be, and how to generate them, is application specific.
Google's article on meta tags
W3schools has a nice simple article
Meta tags play an ever decreasing role in SEO these days.
However, in relation to MVC, you can set your masterpage up along the following lines:
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</title>
<asp:ContentPlaceHolder
ID="MetaPlaceHolder" runat="server">
<meta name="keywords" content="<%= ViewData["keywords"] %>" />
<meta name="description" content="<%= ViewData["description"] %>" />
</asp:ContentPlaceHolder>
// lots os stuff missed out!!
</head>
<body>// more suff missed etc</body>
and then pass the ViewData from your individual controller actions to populate the 'keywords' and 'description' sections. There are other ways, but this one is fairly simple to get up and running without major disruption to your existing codebase.
usage - add the following to each required controller action
public ActionResult Index()
{
// data would obviously come from some datastore but hardcoded for now below
ViewData["keywords"] = "speed, camera, action";
ViewData["description"] = "crime dun wrong";
// other stuff happening too
}
That said, you should more importantly be looking at:
keyword density
outbound/inbound links
img alt tags
page titles
H1/H2 contents
long URL segmentation and applicability
as these play an ever increasing importance in SEO these days. all of the above should be easily searchable on google.
I think Jim is over-complicating it just a bit with the placeholder bit - it's not necessary. Just do this:
In _Layout head section:
<meta name="description" content=#ViewData["Description"]/>
In the controller:
ViewData["Description"] = "My site has all the goodies!!";
Also no need to wrap it in a conditional; it won't throw an error. If you don't set ViewData in the controller the tag will just be empty:
<meta name="description"/>

Categories