I want to use Razor helper in .net core
I use this code
#{
void DrawRow(CategoryModel child, int parentNo)
{
#<text>
<tr style="display: none;">
<td><span class="treegrid-indent"></span><span class="treegrid-expander"></span>#child.Name</td>
</td>
</tr>
</text>;
}
}
but when use this , get error
The "#" character must be followed by a ":", "(", or a C# identifier. If you intended to switch to markup, use an HTML start tag,
You can achieve same requirement using a view component in ASP.NET Core application, like below.
ViewComponent class
[ViewComponent(Name = "DrawRow")]
public class DrawRowComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(DrawRowModel model)
{
return View(model);
}
}
ViewComponent Razor view
#model DrawRowModel
#*display: none;*#
<tr style="">
<td>
<span class="treegrid-indent"></span>
<span class="treegrid-expander"></span>
#Model.child.Name
</td>
</tr>
Model Class(es)
public class CategoryModel
{
public string Name { get; set; }
}
public class DrawRowModel
{
public CategoryModel child { get; set; }
public int parentNo { get; set; }
}
Invoke view component in Test View page
#{
ViewData["Title"] = "Test";
var model = new DrawRowModel { child = new CategoryModel { Name = "Category" }, parentNo = 0 };
}
<h1>Test</h1>
#for (int i = 1; i < 6; i++)
{
model.child.Name = "Category" + i.ToString();
model.parentNo = i;
<table>
#await Component.InvokeAsync("DrawRow", model)
</table>
}
Test Result
Related
I have a written a sample program that shows how I create a Generic LIST and I send that to the VIEW and the VIEW renders the values correctly but when I do a POST the LIST is empty. So Console.WriteLine(TimeEntry.Count) is 0, was kind of expecting 2
public class TimeEntry
{
public DateTime entryTime { get; set; }
}
public class IndexModel : PageModel
{
[BindProperty(SupportsGet = true)]
public List<TimeEntry> TimeEntry { get; set; }
public void OnGet(List<TimeEntry> timeEntry)
{
TimeEntry _timeEntry = new TimeEntry();
_timeEntry.entryTime = DateTime.Now;
timeEntry.Add(_timeEntry);
_timeEntry = new TimeEntry();
_timeEntry.entryTime = DateTime.Now.AddMinutes(10);
timeEntry.Add(_timeEntry);
TimeEntry = timeEntry;
}
public void OnPost(List<TimeEntry> TimeEntry)
{
Console.WriteLine(TimeEntry.Count);
}
}
above is the server side script
#model IndexModel
#{
ViewData["Title"] = "Home page";
}
<form class="form-horizontal" method="post">
<table>
#if (Model.TimeEntry != null)
{
#foreach (var _time in Model.TimeEntry)
{
<tr>
<td>
Entry Time: #_time.entryTime
</td>
</tr>
}
}
</table>
<button type="submit">Post</button>
</form>
You should add some hidden input fields in your form for each table row and bind them to the List<TimeEntry> like this:
<table>
#if (Model.TimeEntry != null)
{
#for (var i = 0; i < Model.TimeEntry.Count; i++)
{
<tr>
<td>
<input type="hidden" name="[#i].entryTime" />
Entry Time: #Model[i].entryTime
</td>
</tr>
}
}
</table>
https://www.learnrazorpages.com/razor-pages/model-binding#binding-complex-collections
So I'm trying to create a little tool where a user can select a set of days. I however need quite a complex model for extra data.
public class DayRange{
...
List<DaySelected> Days
...
}
public class DaySelected{
public bool Selected{ get; set;}
public string DayName {get; set;}
public DaySelected(string Day){
Selected = false;
DayName = day;
}
}
My Razorpage looks like this:
#Model DayRange
...
<form asp-action="RegisterSelection" asp-controller="DayRegister">
<table>
#foreach (var Day in Model.Days)
{
<tr>
<td>
<input asp-for=#Day.Selected />
</td>
</tr>
}
</table>
<button type="submit">Confirm</button>
</form>
My method Registerselection looks like this:
[HttpPost]
public IActionResult RegisterSelection(DayRange dr){
...
}
However, whenever I change any of textboxes, all of the selected bool values remain the same. Can anybody help me on my way? Thanks in advance!
Here is a demo to pass data to action correctly:
Model:
public class DayRange
{
public List<DaySelected> Days { get; set; }
}
public class DaySelected
{
public bool Selected { get; set; }
public string DayName { get; set; }
public DaySelected()
{
}
public DaySelected(string Day)
{
Selected = false;
DayName = Day;
}
}
View:
#Model DayRange
<form asp-action="RegisterSelection" asp-controller="DayRegister">
<table>
#{ var i = 0;}
#foreach (var Day in Model.Days)
{
<tr>
<td>
<input asp-for=#Day.Selected name="Days[#i].Selected" />
#Day.DayName
<input asp-for=#Day.DayName name="Days[#i].DayName" hidden />
</td>
</tr>
i ++;
}
</table>
<button type="submit">Confirm</button>
</form>
result:
<table>
#foreach (DataRow row in Model.Rows)
{
<tr>
#foreach (DataColumn col in Model.Columns)
{
<td>#row[col.ColumnName]</td>
}
</tr>
}
</table>
#Html.ActionLink("Pass", "Insert", "Home")
When clicking the pass link i would like the columns to be inserted into db. Is there any tutorial on how to do this?
Please try this sample.
Create a view model class as follows
public class DataRows
{
public int Column1{ get; set; }
public string Column2 { get; set; }
public double Column3 { get; set; }
}
public class MyModel
{
public virtual DataRows[] DataSet { get; set; }
}
Retrieve all the data using your business logic into MyModel in your controller. I am demonstrating this using a sample code
public TestModel GenerateModel()
{
var model = new TestModel();
model.DataSet = this.GenerateDataGridData().ToArray();
return model;
}
private ICollection<SampleDataSet> GenerateDataGridData()
{
var list = new List<SampleDataSet>()
{
new SampleDataSet() { Column1= 1, Column2= "XXX", Column3= 23 },
new SampleDataSet() { Column1= 2, Column2= "YYY", Column3= 27 },
new SampleDataSet() { Column1= 3, Column2= "ZZ", Column3= 25 }
};
return list;
}
In the Action of your view you will be calling GenerateModel method as follows
public ActionResult MyView()
{
var model = this.GenerateModel();
return this.View(model);
}
Now you restructure your MyView page as follows
#model MyModel
#{
int i = 0;
}
#using (Html.BeginForm("Insert", "Home", FormMethod.Post))
{
<table>
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
</tr>
</thead>
<tbody>
#foreach (var row in Model.DataSet)
{
<tr>
<th>#row.Column1<span>#Html.HiddenFor(x => Model.DataSet[i].Column1)</span></th>
<th>#row.Column2<span>#Html.HiddenFor(x => Model.DataSet[i].Column2)</span></th>
<th>#row.Column3<span>#Html.HiddenFor(x => Model.DataSet[i].Column3)</span></th>
</tr>
i++;
}
</tbody>
</table>
<input type="submit" value="Pass" />
}
Now on submiting the data in the view will be posted to your Insert Action of Home controller and you can insert into your DB using your logic
I hope this will be a solution for your query.
XOn an ASP.NET MVC Website I´m posting a List of models, wrapped in a classe's property, by submitting a form.
When the "List propertys" name contains a
capital letter beside the first one, deserialization seems to fail when posting back, hence the List property of the wrapping class received as parameter in the controller method is null. If the propertie`s name doesn't contain any further capital letters all going fine.
For better comprehension I created an example with two wrapping classes Department & DepartmentX:
namespace CollectionPropertyCamelCase.Models
{
public class Employee
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Department
{
public IList<Employee> Employees { get; set; }
}
public class DepartmentX
{
public IList<Employee> EmployeesX { get; set; }
}
}
namespace CollectionPropertyCamelCase.Controllers
{
public class DepartmentController : Controller
{
// ---> Works fine
public ActionResult Index()
{
var d = new Department()
{
Employees = new List<Employee>()
{
new Employee(){ Name = "Paul", Age = 35},
new Employee(){ Name = "Laura", Age = 27},
new Employee(){ Name = "John", Age = 99}
}
};
return View(d);
}
[HttpPost]
public ActionResult Index(Department d)
{
// All fine: Parameter d`s poperty Employees is an instance of
// List<Employee> conatining three instances of Employee
// providing the values as defined in Index().
return View(d);
}
// <--- Works fine
// ---> Doesn't work
public ActionResult IndexX()
{
var d = new DepartmentX()
{
// this is the troublemaker: Usage of 'X' in the propertyname
EmployeesX = new List<Employee>()
{
new Employee(){ Name = "Paul", Age = 35},
new Employee(){ Name = "Laura", Age = 27},
new Employee(){ Name = "John", Age = 99}
}
};
return View(d);
}
[HttpPost]
public ActionResult IndexX(DepartmentX d)
{
// Not so fine: Parameter d`s poperty EmployeesX is null
return View(d);
}
// <--- Doesn't work
}
}
#* Index.cshtml *#
#model CollectionPropertyCamelCase.Models.Department
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
<table>
#for (int i = 0; i < Model.Employees.Count; i ++)
{
<tr>
<td>
#Html.TextBoxFor(modelItem => Model.Employees[i].Name)
</td>
<td>
#Html.TextBoxFor(modelItem => Model.Employees[i].Age)
</td>
</tr>
}
</table>
<input type="submit" />
}
#* IndexX.cshtml *#
#model CollectionPropertyCamelCase.Models.DepartmentX
#{
ViewBag.Title = "IndexX";
}
<h2>IndexX</h2>
#using (Html.BeginForm())
{
<table>
#for (int i = 0; i < Model.EmployeesX.Count; i++)
{
<tr>
<td>
#Html.TextBoxFor(modelItem => Model.EmployeesX[i].Name)
</td>
<td>
#Html.TextBoxFor(modelItem => Model.EmployeesX[i].Age)
</td>
</tr>
}
</table>
<input type="submit" />
}
Does anyone have a clue how to influence deserialization, so camelcased propery names can be used at that place? Thanks in advance!
I'm trying to make a view model to show a list of checkboxes. A checkbox will be checked when its ID is found in the database. However, my code is generating an error.
CheckFacilityVN
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace XNet.WebUI.Hotel.ViewModel
{
public class CheckFacilityVM
{
public int FacilityID { get; set; }
public string facilityName { get; set; }
public List<FacilityAvailable> facilityAvailable { get; set; }
}
public class FacilityAvailable
{
public bool isCheck { get; set; }
}
}
My controller
public ActionResult Facility()
{
var htl = _hotelService.ShowRoomFacility(2);
var list = new List<FacilityAvailable>();
foreach (var x in htl)
{
list.Add(new FacilityAvailable { FacilityID = htl.FacilityID, facilityName = htl.FacilityName, isCheck = htl.IsActive });
}
return View();
}
My constructor
public Facility ShowRoomFacility(int HotelID)
{
var x = (from d in db.Facilities
where d.FacilityID == HotelID
select d).FirstOrDefault();
return x;
}
How can I make these checkboxes?
Start by adapting your view model:
public class CheckFacilityVM
{
public int FacilityID { get; set; }
public string FacilityName { get; set; }
public bool IsFacilityAvailable { get; set; }
}
and then use this view model:
public ActionResult Facility()
{
var model = _hotelService
.ShowRoomFacility(2)
.Select(htl => new CheckFacilityVM
{
FacilityID = html.FacilityID,
FacilityName = html.FacilityName,
IsFacilityAvailable = htl.IsActive,
})
.ToList();
return View(model);
}
and then write a corresponding view:
#model List<CheckFacilityVM>
#using (Html.BeginForm())
{
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Is available</th>
</tr>
</thead>
<tbody>
#for (var i = 0; i < Model.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(x => x[i].FacilityID)
#Html.HiddenFor(x => x[i].FacilityID)
</td>
<td>
#Html.DisplayFor(x => x[i].FacilityName)
#Html.HiddenFor(x => x[i].FacilityName)
</td>
<td>
#Html.CheckBoxFor(x => x[i].IsFacilityAvailable)
</td>
</tr>
}
</tbody>
</table>
<button type="submit">Save</button>
}
and finally:
[HttpPost]
public ActionResult Facility(List<CheckFacilityVM> model)
{
// process the values from the view model here ...
}