#section with RazorEngine - asp.net-web-api2

We are trying to generate templates using RazorEngine and Webapi. If i include section in the cshtml code. Exception is thrown. Is there a different way of doing this.
class Program
{
static void Main(string[] args)
{
var config = new TemplateServiceConfiguration
{
Debug = true,
CachingProvider = new DefaultCachingProvider(t => { })
};
var service = RazorEngineService.Create(config);
Engine.Razor = service;
service.AddTemplate("layout", #"<!DOCTYPE html>
<html> <head>
<style>
body
{
font-size: .85em;
font-family: 'Trebuchet MS' , Verdana, Helvetica, Sans-Serif;
color: #232323;
background-color: #fff;
}
header, footer, nav, section
{
display: block;
}
</style>
<title>#Model.Name</title>
</head>
<body>
<div>
#RenderSection('section1',false)
</div>
<div id='content'>
#RenderBody()
</div>
</body>
</html>");
service.AddTemplate("template", #"#{Layout = ""layout"";}
<h3>#Model.Title</h3>
#section section1{
<text>sample content</text>}");
var bookList = new BookList()
{
Name = "Madhavi",
Title = "Top 10 books",
Books = new List<string>
{
"Harry poter1",
"Harry poter2",
"Harry poter3",
"The hunger game1",
"Harry poter1",
"The Hobbit",
"Eat Pray Love",
"A Tale of Two Cities",
"The Lion, the Witch and the Wardrobe",
"Think and Grow Rich"
}
};
service.Compile("template", bookList.GetType());
var result = service.Run("template", bookList.GetType(), bookList);
Console.WriteLine("Result is: {0}", result);
}
}
public class BookList
{
public string Name { get; set; }
public string Title { get; set; }
public List<string> Books { get; set; }
}
Error Shown
Errors while compiling a Template.
Please try the following to solve the situation:
* If the problem is about missing/invalid references or multiple defines either try to load
the missing references manually (in the compiling appdomain!) or
Specify your references manually by providing your own IReferenceResolver implementation.
See https://antaris.github.io/RazorEngine/ReferenceResolver.html for details.
Currently all references have to be available as files!
* If you get 'class' does not contain a definition for 'member':
try another modelType (for example 'null' to make the model dynamic).
NOTE: You CANNOT use typeof(dynamic) to make the model dynamic!
Or try to use static instead of anonymous/dynamic types.
More details about the error:
- error: (49, 24) Too many characters in character literal
Temporary files of the compilation can be found in (please delete the folder): C:\Users\madhavi\AppData\Local\Temp\RazorEngine_oeduzlw2.nyw
The template we tried to compile is:
------------- START -----------
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-size: .85em;
font-family: 'Trebuchet MS', Verdana, Helvetica, Sans-Serif;
color: #232323;
background-color: #fff;
}
header, footer, nav, section {
display: block;
}
</style>
<title>#Model.Name</title>
</head>
<body>
<div>
#RenderSection('section1',false)
</div>
<div id='content'>
#RenderBody()
</div>
</body>
</html>
------------- END -----------
The generated source code is:
------------- START -----------
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
</auto-generated>
//------------------------------------------------------------------------------
namespace CompiledRazorTemplates.Dynamic {
using System;
using System.Collections.Generic;
using System.Linq;
public class RazorEngine_090e814295334051a2dbe5f2a700d613 : RazorEngine.Templating.TemplateBase<EmailTemplateGeneration.BookList>
{
public RazorEngine_090e814295334051a2dbe5f2a700d613() {
}
public override void Execute() {
WriteLiteral(#"<!DOCTYPE html>
<html>
<head>
<style>
body {
font-size: .85em;
font-family: 'Trebuchet MS', Verdana, Helvetica, Sans-Serif;
color: #232323;
background-color: #fff;
}
header, footer, nav, section {
display: block;
}
</style>
<title>
");
Write(Model.Name);
WriteLiteral("
</title>\r
</head>\r
<body>
\r <div>
\r");
WriteLiteral(" ");
Write(RenderSection('section1',false));
WriteLiteral("\r
</div>\r <div"); WriteLiteral(" id=\'content\'");
WriteLiteral(">
\r");
WriteLiteral(" ");
Write(RenderBody());
WriteLiteral("\r </div> \r
</body>\r
</html>");
}
}
}
------------- END -----------
List of loaded Assemblies:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
Loaded Assembly: C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\14.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
Loaded Assembly: C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\14.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll
Loaded Assembly: C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\14.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll
Loaded Assembly: C:\Users\madhavi\Documents\Visual Studio 2015\TestIntegrationProject\EmailTemplateGeneration\EmailTemplateGeneration\bin\Debug\EmailTemplateGeneration.vshost.exe
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Data.DataSetExtensions\v4.0_4.0.0.0__b77a5c561934e089\System.Data.DataSetExtensions.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Net.Http.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll
Loaded Assembly: C:\Users\madhavi\Documents\Visual Studio 2015\TestIntegrationProject\EmailTemplateGeneration\EmailTemplateGeneration\bin\Debug\EmailTemplateGeneration.exe
Loaded Assembly: C:\Users\madhavi\Documents\Visual Studio 2015\TestIntegrationProject\EmailTemplateGeneration\EmailTemplateGeneration\bin\Debug\RazorEngine.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll
Loaded Assembly: C:\Users\madhavi\Documents\Visual Studio 2015\TestIntegrationProject\EmailTemplateGeneration\EmailTemplateGeneration\bin\Debug\System.Web.Razor.dll
Loaded Assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Dynamic\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Dynamic.dll

When searching for the relevant compiler error you will find: Why I'm getting CS1012: "Too many characters in character literal" and CS0019?
After this info you can look at your source again and detect the error:
#RenderSection('section1',false)
Is translated to
Write(RenderSection('section1',false));
You should use " for strings instead of ' in C#.

Related

Selenium IE Page title is not working. Tried IWebDriver.Title

I asked this question last week and someone marked it as a duplicate. However the duplicate reference did not answer or give solution to my question.
I am trying to get the page title to a complicated html page. I am trying to get the 'By' locator used to find an element. This is the HTML
<!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 id="ctl00_Head1"><title>
Smart Tracking System
</title><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" /><link rel="shortcut icon" type="image/x-icon" href="../images/desktopicon.ico" /><link href="../App_Themes/appthemes/appstyles.css" type="text/css" rel="stylesheet" /><link href="../App_Themes/appthemes/calendarstyles.css" type="text/css" rel="stylesheet" /><link href="../App_Themes/appthemes/tabsstyles.css" type="text/css" rel="stylesheet" /></head>
<body>
When I copy the xpath from Firefox source code, it says the xpath is:
/html/head/title
I am using C# code to do the validation but I keep getting "LoadableComponentException..."
This is my C# code:
public class AccountsOverviewPage : CVALoadableComponent<AccountsOverviewPage>
{
private IWebDriver _driver;
private By textlabelPageHeader = By.XPath("//head[#class='title' and text()='Smart Tracking System']");
public AccountsOverviewPage()
{
_driver = ScenarioContext.Current.Get<IWebDriver>();
}
protected override void ExecuteLoad()
{
}
protected override bool EvaluateLoadedStatus()
{
if (!CVAElements.WaitForElementOnPageLoad(_driver, textlabelPageHeader))
{
UnableToLoadMessage = "Could not load Accounts Overview page within the designated timeout period";
return false;
}
return true;
}
public bool IsAt()
{
return CVAElements.CheckElementIsVisible(_driver, textlabelPageHeader);
}
}
I have even tried doing the validation by Id, and this time I used an element Id that I am sure is there:
private By textlabelPageHeader = By.Id("ctl00_Head1");
and still the validation failed. What am I not doing?? Please any assistance will be greatly appreciated.
UPDATE
This is how I am using the Driver.Title method:
public class AccountsOverviewPage : CVALoadableComponent<AccountsOverviewPage>
{
private IWebDriver _driver;
// error happens on this line:
string textlabelPageHeader = _driver.Title;
public string TextlabelPageHeader
{
get
{
return textlabelPageHeader;
}
set
{
textlabelPageHeader = value;
}
}
public AccountsOverviewPage()
{
_driver = ScenarioContext.Current.Get<IWebDriver>();
}
protected override void ExecuteLoad()
{
}
protected override bool EvaluateLoadedStatus()
{
if (!CVAElements.WaitForElementOnPageLoad(_driver, TextlabelPageHeader))
{
UnableToLoadMessage = "Could not load Accounts Overview page within the designated timeout period";
return false;
}
return true;
}
public bool IsAt()
{
return CVAElements.CheckElementIsVisible(_driver, TextlabelPageHeader);
}
and I getting error: "A field initializer cannot reference the non-static field, method, or property" here
string textlabelPageHeader = _driver.Title;
What you're trying to access - a page title - is not a web element. It's a property of the web page itself. In Selenium, you access the page title by:
String pageTitle = _driver.getTitle();
I program in Java, so that might not be the correct syntax for C#

DotNet.Highcharts Package Issues

I am following a tutorial how-to-use-highcharts-js-with-asp-net-mvc-4
and when I build the application I receive the error
The Type or namespace name 'DotNet' could not be found (are you missing a using directive or and assembly reference?)
I have in my controller
using HighChart.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotNet.Highcharts;
using DotNet.Highcharts.Helpers;
using DotNet.Highcharts.Options;
using DotNet.Highcharts.Enums;
In this the DotNet has a blue squiggly under it.
and the reference "DotNet.Highcharts" in the my references folder.
I am using VS 2012 Professional (if that matters)
Do I need to add something in my webconfig that I am missing or do I need to set a reference path? I have used nuget packages before and not ran across this problem so not sure what I need to do.
What I have done.
Restarted VS
Closed / Reopen project
Start from scratch project (mvc 4 empty) and added in DotNet.Highcharts and Jquery packages from nuget and followed the tutorial I listed above.
Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace HighChart.Models
{
public class TransactionCount
{
public string MonthName { get; set; }
public int Count { get; set; }
}
}
Controller
using HighChart.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotNet.Highcharts;
using DotNet.Highcharts.Helpers;
using DotNet.Highcharts.Options;
using DotNet.Highcharts.Enums;
namespace HighChart.Controllers
{
public class ChartSampleController : Controller
{
//
// GET: /ChartSample/
public ActionResult Index()
{
var transactionCounts = new List<TransactionCount> {
new TransactionCount() { MonthName="January", Count=30},
new TransactionCount() { MonthName="February", Count=40},
new TransactionCount() { MonthName="March", Count=4},
new TransactionCount() { MonthName="April", Count=35}
};
var xDataMonths = transactionCounts.Select(i => i.MonthName).ToArray();
var yDataCounts = transactionCounts.Select(i => new object[] { i.Count }).ToArray();
//instanciate an object o the highcharts type
var chart = new Highcharts("chart")
//define the type of chart
.InitChart(new Chart { DefaultSeriesType = ChartTypes.Line })
//overall title of the chart
.SetTitle(new Title { Text = "Incoming Transactions per hour" })
//small lable below the main title
.SetSubtitle(new Subtitle { Text = "Accounting" })
//load the X values
.SetXAxis(new XAxis { Categories = xDataMonths })
//set the Y Title
.SetYAxis(new YAxis { Title = new YAxisTitle { Text = "Number of Transactions" } })
.SetTooltip(new Tooltip
{
Enabled = true,
Formatter = #"function () { return '<b>' + this.series.name + '</b><br/>'+ this.x +': '+ this.y; }"
})
.SetPlotOptions(new PlotOptions
{
Line = new PlotOptionsLine
{
DataLabels = new PlotOptionsLineDataLabels
{
Enabled = true
},
EnableMouseTracking = false
}
})
//load the Y values
.SetSeries(new[]
{
new Series {Name = "Hour", Data = new Data(yDataCounts)},
//you can add more y data to create a second line
// new series { Name = "Other Name", Data = new Data(OtherData)}
});
return View(chart);
//return View();
}
}
}
View
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-2.1.3.min.js"></script>
<script src="~/Scripts/Highcharts-4.0.1/js/highcharts.js"></script>
</head>
<body>
<div>
#model DotNet.Highcharts.Highcharts
<p>My Chart</p>
#(Model)
</div>
</body>
</html>
Any help will be greatly appreciated! Thanks in advance
Did you add the dll to the references? You will need to do this manually by browsing to the dll location.
In my case, I had to specifically download the "Net 4.0" DLL.
https://dotnethighcharts.codeplex.com/releases/view/121251
I honestly thought the nuget package would take care of this

Bound error in Webgrid

I want to display list of vehicles from db in webgrid .but when i run code there comes error in view.chstml that "datasource must be bound" though i used correct model name and db name .
Model : Vehicles
public List<Vehicles> Listvehicle(string uid)
{
List<Vehicles> svehicle;
using (var session = MvcApplication.Store.OpenSession())
{
svehicle = (from vehc in session.Query<Vehicles>() where vehc.userid == uid select vehc).ToList();
}
return svehicle;
}
Controller
[HttpGet]
public ActionResult Listvehilce(string uid)
{
string userName = "ksundas7#gmail.com";
Register reg = new Register();
string userId = reg.userid(userName);
Vehicles vehcl = new Vehicles();
List<Vehicles> vehclist = vehcl.Listvehicle(userId);
vehclist.ToList();
// List<Vehicles> svehicle = WebGrid.Listvehicle(userId);
return View();
}
View
#model IEnumerable<MvcMembership.Models.Vehicles>
#{
ViewBag.Title = "Listvehicle";
}
<h2>Listvehilce</h2>
#{
var grid = new WebGrid(source: Model, canPage: true, rowsPerPage: 3, selectionFieldName: "selectedRow");
grid.Pager(WebGridPagerModes.NextPrevious);}
<style type="text/css">
.table { margin: 4px; width: 500px; background-color:#FCFCFC;}
.head { background-color: #C1D4E6; font-weight: bold; color: #FFF; }
.webGrid th, .webGrid td { border: 1px solid #C0C0C0; padding: 5px; }
.altRow { background-color: #E4E9F5; color: #000; }
.gridHead a:hover {text-decoration:underline;}
.description { width:auto}
.selectRow{background-color: #389DF5}
</style>
#grid.GetHtml(tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("vehicleid"),// format: (item) => item.GetSelectLink(item.vehicleid)),
grid.Column("Type", " Type"),
grid.Column("Make", "Make"),
grid.Column("Registration", "Registration"),
grid.Column("Colour", "Colour"),
grid.Column("Model", "Model")
))
Error:
A data source must be bound before this operation can be performed.
Anyone can tell me please what is reason of this error.
thanks in advance
Regards
You did not return the list in view.here is updated code.
[HttpGet]
public ActionResult Listvehilce(string uid)
{
string userName = "ksundas7#gmail.com";
Register reg = new Register();
string userId = reg.userid(userName);
Vehicles vehcl = new Vehicles();
List<Vehicles> vehclist = vehcl.Listvehicle(userId);
vehclist.ToList();
// List<Vehicles> svehicle = WebGrid.Listvehicle(userId);
return View(svehicle);
}
Did you check that the model is not null when it is being bound to the webgrid?
Also, you can change this part in the controller:
List<Vehicles> vehclist = vehcl.Listvehicle(userId);
vehclist.ToList();
with this
IEnumerable vehclist = vehcl.Listvehicle(userId);
List already implements the IEnumerable interface.

Tri state check box for Razor

I need a check box to return nullable bool value. What should I do?
Is there any Tri State Check Box for Razer engine?
I found this question, but the link is not valid.
You could create a TriState class, a custom ModelBinder for this class, and the corresponding Display/Edit templates.
The TriState class should have a property to store the representation of the current state, it doesn't matter how: for example with an enum, with an int that can be -1, 0 or 1, or with a nullable bool bool?
The display template should simply show the state. I.e. it can show different images for the states, and perhaps an associated "label".
The edit template should show the state and have an script that allows to rotate the 3 states when clicked.
For example, the edit/display template could be implemented as a span with a text that would be used as a label for the state, and could have different CSS styles to show the image as a background image for the span. That would make it easy to change the image both in the server and in the client side scripts.
For the edit template, the span should also have:
a hidden field that stores the value in a way that the custom ModelBinder can recover (i.e. format as string to store the value, and parse the string to recover it)
an script that handles the click event for the span and changes the sate, i.e. that updates the value in the hidden field, as well as the style that shows the corresponding background image.
So you'd need:
TriState class
Custom ModelBinder for TriState class. Look here, or here.
Templates for display/edit. Read this blog: Brad Wilson: ASP.NET MVC 2 Templates
Syles to show the different images (define a background image and a padding so that the text doesn't overwrite the image). Besides, the style could change the cursor in the clickable version (editor template), and perhaps change the display on hover, to give the user a hint that the element is clickable.
Client side script to change the state (only for the editor template). For this script I'd recommend to add a "data-" attribute and attach it unobtrusively. See my answer to this question.
You could improve this by implementing three additional properties in the class to store the labels to show for the three states. This values could be added as extra "data-" attributes in the span, so that the client side script can change the label depending on the current state.
I posted a possible solution on dotnet/aspnetcore github and here for .NET core 3.1+
Here is a fiddle.
I implemented this simple component in .NET core 3.1+.
Here is a fiddle.
The css is from bootstrap, needed to display an empty box, a checked one and a box "full" to indicate the states 0,1,-1 (can change these values easily):
<style>
[class^="icon-"], [class*=" icon-"] { display: inline-block; width: 14px; height: 14px; margin-top: 1px; *margin-right: .3em; line-height: 14px; vertical-align: text-top; background-image: url(/img/glyphicons-halflings.png); background-position: 14px 14px; background-repeat: no-repeat; }
.bootstrap-checkbox { display: inline-block; position: relative; width: 13px; height: 13px; border: 1px solid #000; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
.bootstrap-checkbox i { position: absolute; left: -2px; top: -3px; }
.icon-stop { background-position: -312px -72px; }
.icon-check { background-position: -288px 0px; }
</style>
and this is the blazor component:
<div #ref=checkboxElement class="bootstrap-checkbox" #onclick="(e) => OnClick(e)"><i class="#ImgClass"></i></div>#Description
#code {
public ElementReference checkboxElement { get; set; }
[Parameter]
public string Description { get; set; }
[Parameter]
public bool? Checked { get; set; }
public string ImgClass { get; set; }
public int Value { get; set; }
protected override void OnInitialized()
{
Value = Checked switch { null => -1, true => 1, false => 0 };
ImgClass = Value switch { -1 => "icon-stop", 1 => "icon-check", _ => "" };
}
public void OnClick(MouseEventArgs e)
{
switch (ImgClass)
{
case "":
ImgClass = "icon-check";
Value = 1;
break;
case "icon-check":
ImgClass = "icon-stop";
Value = -1;
break;
case "icon-stop":
ImgClass = "";
Value = 0;
break;
}
}
}

Less CSS: & reverse parent with multiple classes?

This is the first time I'm finding the & parent selector extremely useful so that I don't need to redefine parents simply to modify a child element.
Of course this is actually easy with LESS, but I have to ask!
<div id="skrollr-body" class="nonav">
<div class="skrollable">
</div>
</div>
#skroller-body {
.skrollable {
margin-top:40px;
.nonav & {
// this parent selector lets me modify
// .skrollable without duplicating it
margin-top:0px;
}
}
}
The output of .nonav & is
.nonav #skroller-body .skrollable
I'm wondering if I can get #skroller-body.nonav .skrollable instead somehow without extra HTML markup (a wrapper div.nonav)?
Currently I'll just duplicate the parent
#skrollr-body {
margin-top:40px;
left:0;
width:100%;
.skrollable {
margin-top:40px;
position:fixed;
z-index:100;
.skrollable {
position:absolute;
.skrollable {
position:static;
}
}
}
&.nonav {
.skrollable {
margin-top:0px;
}
}
}
Or to save redundant output;
#skroller-body.nonav .scrollable { margin-top:0px; }
But the whole point here is CSS code that's easy to maintain and read.
The docs tell us:
The & operator represents the parent selectors of a nested rule and
is most commonly used when applying a modifying class or pseudo-class
to an existing selector
So:
#skroller-body {
&.nonav {
.skrollable {
// stuff
}
}
}
}