Showing a substring of text that contains HTML - asp.net-core

I am implementing something similar to a blog engine, where on the entry page I would like to see a listing of my posts, and, for each, its title and a short piece of its body content.
This body content is HTML, and is stored in the database as a string, so, it's not enough to just show a substring of it, because it might break the HTML structure.
I guess the algorithm would be: render the string to HTML and extract only the first X characters of it.
Is there any solution for this problem?

Here is a working demo like below:
View:
#model IEnumerable<Post>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Body)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
Controller:
public IActionResult Test()
{
var model = new List<Post>()
{
new Post(){ Title="asp.net core mvc",Body="<html><div><h1>The Model-View-Controller (MVC) architectural pattern separates an application into three main groups of components: Models, Views, and Controllers. This pattern helps to achieve separation of concerns. Using this pattern, user requests are routed to a Controller which is responsible for working with the Model to perform user actions and/or retrieve results of queries. </h1></div></html>"},
new Post(){Title="asp.net core razor pages",Body="<html><div>Razor Pages is designed to make common patterns used with web browsers easy to implement when building an app. Model binding, Tag Helpers, and HTML helpers all just work with the properties defined in a Razor Page class.</div></html>"}
};
foreach(var item in model)
{
item.Body= Regex.Replace(item.Body, #"<[^>]+>| ", String.Empty);
item.Body= item.Body.AsSpan(0, 30).ToString()+"...";
}
return View(model);
}
Result:

Related

Spring WebFlux+Thymeleaf How to display reactive collection size

I am developing a spring boot service to manage a REST server.
The service displays a reactive list on one of the forms.
It is very simple code.
Table in thymeleaf template
<table>
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Alive</td>
</tr>
</thead>
<tbody>
<tr th:each="item : ${items}">
<td th:text="${item.counterpartID}" />
<td th:text="${item.counterpartName}" />
<td th:text="${item.alive}"/>
</tr>
</tbody>
</table>
Controller
#GetMapping("/counterparties")
public String init(Model model) {
IReactiveDataDriverContextVariable reactiveDataDrivenMode =
new ReactiveDataDriverContextVariable(
webClient
.get()
.uri(uriBuilder -> uriBuilder
.path("/findAllCounterpart")
.build())
.retrieve()
.bodyToFlux(Counterpart.class)
, 1);
model.addAttribute("items", reactiveDataDrivenMode);
return "counterparties.html";
}
Now I want to display collection size (numbers of rows in table).
I added to the html temlate tag
<label th:text="'total rows: ' + ${#lists.size(items)}">rows number in table</label>
And I got an unexpected result
total rows: 1
How to display the real number of rows in a reactive collection ?
Thanks.
I decided to use javascript.
<script language="JavaScript">
function countLoadedRows() {
var table = document.getElementById('tableId');
var tbodyRowCount = table.tBodies[0].rows.length;
console.log('total rows: ' + tbodyRowCount);
document.getElementById('totalRowsId').textContent = tbodyRowCount
}
document.addEventListener('readystatechange', countLoadedRows)
</script>
and html tags is
<input type = "button" onclick = "countLoadedRows()" value = "Total rows: "><label id="totalRowsId">???</label>
<table id="tableId">
...
</table>

Display specific data with parameter using Stored Procedure

Hi I have error in regards with my displaying specific data. I passed a parameter through a model and I get error on regarding creating a new instance. here is my code:
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ViewEmployeeSalary(spGetSalaryPerEmployee getsal)
{
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking();
return View(salary);
}
View
This the button where you click to redirect to the details page
#foreach(var item in Model)
{
a class="btn btn-primary btn-sm" asp-controller="Salary" asp-action="ViewEmployeeSalary" asp-route-id="#item.EmployeeId"><span class="glyphicon glyphicon-dashboard" style="vertical-align:middle;margin-top: -5px"></span> Salary Details</a>
}
Here is the page where it views the details
#model PEMCOLoan.DAL.Entities.spModels.spGetSalaryPerEmployee
#{
ViewBag.Title = "Salary Details";
}
<h2>#Html.DisplayFor(model => model.FullName)'s Salary Details</h2>
<table class="table">
<tr>
<td class="form-horizontal">ID:</td>
<td>#Html.DisplayTextFor(model => model.EmployeeID)</td>
</tr>
<tr>
<td class="form-horizontal">Salary Amount:</td>
<td>#Html.DisplayFor(model => model.Salary)</td>
</tr>
<tr>
<td class="form-horizontal">Remarks:</td>
<td>#Html.DisplayTextFor(model => model.Remarks)</td>
</tr>
</table>
I get this error:
I don't really what really happens but stated the I need to create an instance.
I have still a little knowledge about asp.net core and ef core and still studying for this language for now. I really need your help in regards with this since I'm a bit new with this language.
Any suggestion would be a greatly appreciated!
Your controller method needs to return single record as error states. Now it returns a list, so you need to change to something like this:
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking().SingleOrDefault();
//salary now is single record
return View(salary);
And maybe you need to check salary variable is not null before passing it to view, because then you'll have errors there.

How generate MVC View Controls dynamically?

Is possible to generate controls in View depending on data returned from DB
Example
Model
public string Type{ get; set; }
Controller
public ActionResult Index()
{
return View(db.TypeModel.ToList());
}
View
#model IEnumerable<Sample.Models.TypeModel>
#foreach (var item in Model)
{
<tr>
<td>
#*if Item in model is T generate text box, if C generate text..*#
</td>
</tr>
}
There are multiple solutions to this kind of problem, I personally think that you should take a look in EditorFor html helper.
This method generates different HTML markup depending on the data type
of the property that is being rendered, and according to whether the
property is marked with certain attributes. https://msdn.microsoft.com/en-us/library/system.web.mvc.html.editorextensions.editorfor%28v=vs.118%29.aspx?f=255&MSPPError=-2147217396
Your code can look like this...
#model IEnumerable<Sample.Models.TypeModel>
#foreach (var item in Model)
{
<tr>
<td>
#Html.EditorFor(m=> item.Property,item.Type)
</td>
</tr>
}

Foreach property in item from list

I'm revamping a small helpdesk application (moving from ASP classic to MVC4). This is my first full MVC application. I've opted to go with Razor, and I feel like it's pretty intuitive. But I've hit a wall on this part.
I get a list of tickets from the database to display to the user. What I would like is to dynamically create a table. Right now I have put the headers in place manually, which is fine. If there's a way to do that dynamically, though, I'm open to suggestions.
But the crucial piece is to get each property from the ticket. I have a Ticket class that has over 20 properties. I'll be working on whittling those down to the minimum we want to display, but as a starting point, I'm trying to throw them all up on the screen.
I have the following:
#model IList<Helpdesk4.Models.Ticket>
...
#foreach (var ticket in Model)
{
<tr>
#foreach (var item in ticket)
{
<td>item</td>
}
</tr>
}
But I can't run that foreach on ticket. I'm enough of a noob that I don't totally understand why, but I think that the properties have to be loaded and so can't be enumerated by default. So without pulling up each property name, how do I just get each property's value from ticket?
I am using NHibernate for the queries to the db if that makes any difference.
The absolutely clearest and easiest way to do this if to manually add each of the properties values to the row. This does require a small amount of "extra" work, but it is a one time thing, and 20 properties is not that much. It also gives you much finer control over exactly how each property is displayed, if it is aligned right or left, etc.
What you end up with is something like this
#foreach (var ticket in Model)
{
<tr>
<td>
#ticket.FirstProperty
</td>
<td class="align-right">
#ticket.SecondProperty
</td>
<td class="align-center bold">
#Html.DisplayFor(m => ticket.ThirdProperty)
</td>
<td>
<i>#ticket.FourthProperty</i>
</td>
...
</tr>
}
Stylings and such added for emphasis of customizability.
Good luck with your first MVC project!
Foreach only works with an enumerable item, and general classes don't implement IEnumerable. You need to put each item on there yourself. The best way would be to use something like Html.TextBoxFor(m => m.Property) for each property.
edit:
The best way would be to just use Html.LabelFor on the object itself.
#for(int index = 0; index < Model.Count; ++index)
{
<tr>
#Html.LabelFor(m => m[index])
<tr>
}

How to handle Html tags in string - when displayed in MVC page

So I'm retrieving data from the Rally web service and the description field contains html tags.
My MVC page looks like this:
<table width="100%" id="stories">
<tr>
<td>ID</td>
<td>Name</td>
<td>Description</td>
<td>TaskEstimateTotal</td>
</tr>
#foreach (var story in Model.UserStories)
{
<tr>
<td>#story["FormattedID"]</td>
<td>#story["Name"]</td>
<td>#story["Description"]</td>
<td>#story["TaskEstimateTotal"]</td>
</tr>
}
</table>
The html tags appear as text
eg:
<DIV>As a Marketing Analytics And Data Manager</DIV>
I've tried encoding and decoding it but neither of those are producing the desired response. Encoding it will convert the < into < type text.
<td>#HttpUtility.HtmlEncode(story["Description"])</td>
Hopefully it's just something simple I've missed!
Unless I should be stripping out the tags?
Have you tried:
<td>#Html.Raw(story["Description"])</td>
MSDN: http://msdn.microsoft.com/en-us/library/gg480740(v=vs.98).aspx
You can do:
<td>#Html.Raw(story["Description"])</td>
Razor html encodes strings by default.