Rendering dynamic HTML content into variable in Razor - asp.net-mvc

I want to render dynamic HTML content into a variable to later pass it to a function. The reason is, that I receive the actual content through another platform and I can print it out using an internal function. This function accepts values to put into placeholders.
Example:
This is my content:
{mytable}
Blah
Now I can set any content on mytable. Good.
The content I want to put there is currently the following.
#using System.Data
#model Dictionary<string, DataView>
<table>
#foreach (var group in Model)
{
<tr>
<th colspan="3">#group.Key</th>
</tr>
foreach (DataRowView data in group.Value)
{
<tr>
<td>#data.Row["col1"]</td>
<td>#data.Row["col2"]</td>
<td>#data.Row["col3"]</td>
</tr>
}
}
</table>
Well. What is the best way to actually render the above output into a variable? I firstly thought of just appending every HTML line into a string, but it sounds rather inefficient and weak to me.
I'm not an expert in ASP.NET, I come from PHP and I know a bit about output buffers. Is this a possible way? What would you recommend?

You could create a ViewHelper:
#helper RenderTable(Dictionary<string, System.Data.DataView> model)
{
<table>
#foreach (var group in Model)
{
<tr>
<th colspan="3">#group.Key</th>
</tr>
foreach (System.Data.DataRowView data in group.Value)
{
<tr>
<td>#data.Row["col1"]</td>
<td>#data.Row["col2"]</td>
<td>#data.Row["col3"]</td>
</tr>
}
}
</table>
}
Then call it:
#{
string output = RenderTable(someData).ToHtmlString();
}

Create strongly typed partial view and add this partial view in actual view
See below link
http://www.codeproject.com/Tips/617361/Partial-View-in-ASP-NET-MVC

Related

How to retrive data from ViewData in foreach loop

Hi I have get records in ViewData["TutorList"] = GetData.Tables[0];
Here GetData DataSet and in that table[0] is bind with ViewData["TutorList"]
#foreach (var item in (DataTable)ViewData["TutorList"])
{
<tr>
<td>#item["Name"].ToString()</td>
</tr>
}
How Can I get all the records in foreach
The following code should give you want you want
#foreach (DataRow item in ((DataTable)ViewData["TutorList"]).Rows)
{
<tr>
<td>#item["Name"].ToString()</td>
</tr>
}
But I would suggest that you use a view model specific to the view and use the associated Html helpers in your view.

Partial View is not rendering td elements inside foreach razor tag

I am using a List of Products as a Model for my Partial view. In the partial view I am using a foreach loop to get the values of Product class and trying to render it to users. In the partial view I've written this code:
#model Project.ViewModel.ListofProductsVM
#using Project.Models
<table>
<tr>
<th>
Name
</th>
<th>
Cost
</th>
</tr>
#{
foreach (Products prod in Model.products)
{
<tr>
<td>#prod.Name.ToString()</td>
<td>#prod.Cost.ToString()</td>
</tr>
}
}
</table>
I can see the headers "Name" and "Cost" in the page but Product Name and its Cost is not rendering. When I am checking the source code in HTML it is showing me this HTML only:
<table>
<tr>
<th>
Name
</th>
<th>
Cost
</th>
</tr>
</table>
While debugging I can see the values are correctly getting passed to Partial Views. Even the "#prod.Name" and "#prod.Cost" is showing me the correct value. But it is not rendering it to HTML. I don't understand what I am doing wrong here. Thanks in advance.
The #{ } means that this is c# code block, you can fix the problem by writing your foreach loop code this way:
#foreach (Products prod in Model.products)
{
<tr>
<td>#prod.Name.ToString()</td>
<td>#prod.Cost.ToString()</td>
</tr>
}
and if you want to stick with your way then you have to specify to render that as html like:
#{
foreach (Products prod in Model.products)
{
#:<tr>
#:<td>#prod.Name.ToString()</td>
#:<td>#prod.Cost.ToString()</td>
#:</tr>
}
}
I had a similiar problem. In my case, all I needed was to add "#" before the foreach nested in an if statement. This is a pared down snippet of my working code
C# Model class:
public class MyModel
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
CSHTML file:
#model List<MyProject.Models.MyModel>
#if (Model.Count > 0)
{
<div class="row" >
<table>
#foreach (var item in Model)
{
<tr>#item.FirstName #item.LastName</tr>
}
</table>
</div>
}
But it's the same answer that another user gave you.

Why is DisplayForModel not showing the expected output?

I have a simple razor page, where the first part correctly shows information from each element in my model in a table. After that I'm trying to use DisplayFor to show me every property in the model, but it generates 123 for each iteration. What am I doing wrong?
#model System.Data.Entity.IDbSet<DBFramework.MyPerson>
#{
ViewBag.Title = "Home Page";
}
<p></p>
<table border="1">
<thead>
<tr>
<th style="width:300px;">Name</th>
<th style="width:300px;">Age</th>
</tr>
</thead>
#foreach (var p in Model)
{
<tr>
<td>#Html.Label(p.Name)</td>
<td>#Html.Label(p.Age.ToString())</td>
</tr>
}
</table>
#foreach (DBFramework.MyPerson x in Model)
{
#Html.DisplayForModel(x)<br/>
}
Creates the following output:
Name Age
Mike 40
Penny 1
Kunal 30
123
123
123
Try this:
#foreach (var item in Model)
{
#Html.DisplayFor(model => item)
}
DisplayFor and DisplayForModel are used with templates in Views\Shared\DisplayTemplates.
When you call DisplayForModel, it will take the page model (Model) and if you specify a parameter, will try to load the template with the name provided (if string) or add the object as additional data in ViewData. When you called:
#foreach (DBFramework.MyPerson x in Model)
{
#Html.DisplayForModel(x)<br/>
}
You told it - Display Model which is type System.Data.Entity.IDbSet<DBFramework.MyPerson> and add MyPerson in the template ViewData. Do this 3 times. You also didn't give him a hint to select a DisplayTemplate and it will try to use convention to find it.
As Bappi Datta said, if you want to display a template for MyPerson, you need to call:
#foreach (var item in Model)
{
#Html.DisplayFor(model => item)
}
However, you need a MyPerson display template created which accepts #model DBFramework.MyPerson to render the item or it will simply do a .ToString() by default I believe.

pass model to view using viewbag

i want to send two model in my view
and in other page maybe and need more
controller
ViewBag.Users = db.Users.ToList();
and in View
#using Documentation.Models
#{
var Users = (Documentation.Models.User)ViewBag.Users;
}
<table>
#foreach (var item in Users) {
<tr>
<td>
#Html.DisplayFor(item.username)
</td>
</tr>
}
</table>
but i get no answer , i know my code is not right
i got this error
foreach statement cannot operate on variables of type 'Documentation.Models.User' because 'Documentation.Models.User' does not contain a public definition for 'GetEnumerator'
you should cast viewbag.model to List of User. Not to User.
#{
var Users = (List<User>)ViewBag.Users;
}

Unable to pass the same object with different result to partial view on the Home/Index controller in mvc 3

public ActionResult Index()
{
List<pInfo> pobj = new List<pInfo>();
pobj = (from pid in db.pInfoes
orderby pid.pId descending
select pid).ToList();
return View(pobj);
}
public ActionResult toprank() ///partial view
{
List<pInfo> pobj = new List<pInfo>();
pobj = (from pid in db.pInfoes.Where(c => c.DateCreated < DateTime.Now)
orderby pid.Score descending
select pid).Take(3).ToList();
return PartialView("toprank", pobj);
}
\\\ Index.csHtml
#model IEnumerable<TestProj.pInfo>
<table>
<tr>
<td>
#foreach (var item in Model)
{
<table>
<tr>
<td>
<iframe width="560"
height="300"
src="#item.pUrl"
frameborder="0"></iframe>
</td>
</tr>
</table>
}
</td>
<td>
#{Html.RenderPartial("toprank", model);}
</td>
</tr>
</table>
I am passing different result set for same Model i.e pInfo. on partial view and Index actionresult on the Home Controller. When I am trying to render the partial view on the Index view page I am getting the same result-set from the Index action result two times one in the table and another in the #{Html.RenderPartial("toprank", model);} ... I am sure I am missing some basic understanding of how the partial view works but unable to figure it out for last 3 hrs. If I change the url to partial view i.e (home/toprank ) then I get the resultset I want but its not coming on the Home/Index page
Please let me know if my design concept is wrong.. I am starting to feel that this is probably the wrong approach to get this working..
if you want to see the toprank() called you need to use Html.Action not partial, change the view to this :
<td>
#Html.Action("toprank")
</td>

Resources