How to use ViewDataDictionary with Html.Partial in asp.net core? - asp.net

My case looks like this:
Model:
public class Book
{
public string Id { get; set; }
public string Name { get; set; }
}
public class Comment
{
public string Id { get; set; }
public string BookId { get; set; }
public string Content { get; set; }
}
Controller:
public IActionResult Detail(string id)
{
ViewData["DbContext"] = _context; // DbContext
var model = ... // book model
return View(model);
}
View:
Detail view:
#if (Model?.Count > 0)
{
var context = (ApplicationDbContext)ViewData["DbContext"];
IEnumerable<Comment> comments = context.Comments.Where(x => x.BookId == Model.Id);
#Html.Partial("_Comment", comments)
}
Comment partial view:
#model IEnumerable<Comment>
#if (Model?.Count > 0)
{
<!-- display comments here... -->
}
<-- How to get "BookId" here if Model is null? -->
I've tried this:
#Html.Partial("_Comment", comments, new ViewDataDictionary { { "BookId", Model.Id } })
Then
#{
string bookid = ViewData["BookId"]?.ToString() ?? "";
}
#if (Model?.Count() > 0)
{
<!-- display comments here... -->
}
<div id="#bookid">
other implements...
</div>
But error:
'ViewDataDictionary' does not contain a constructor that takes 0
arguments
When I select ViewDataDictionary and press F12, it hits to:
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{
public ViewDataDictionary(IModelMetadataProvider metadataProvider, ModelStateDictionary modelState);
}
I don't know what are IModelMetadataProvider and ModelStateDictionary?
My goal: Send model comments from view Detail.cshtml to partial view _Comment.cshtml with a ViewDataDictionary which contains BookId.
My question: How can I do that?

Another way to use this is to pass the ViewData of the current view into the constructor. That way the new ViewDataDictionary gets extended with the items you put in using the collection initializer.
#Html.Partial("MyPartial", new ViewDataDictionary(ViewData) { { "BookId", Model.Id } })

Use the following code to create a ViewDataDictionary
new ViewDataDictionary(new Microsoft.AspNetCore.Mvc.ModelBinding.EmptyModelMetadataProvider(), new Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary()) { { "BookId", Model.Id } }

On .NET Core I use ViewDataDictionary with a parameter, like:
#Html.Partial("YourPartial", new ViewDataDictionary(ViewData) { { "BookId", Model.Id } })

Related

There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'DepartmentId'

There is no ViewData item of type 'IEnumerable' that has the key DepartmentId
I have already tried to show the departmentlist using the model
TestController.cs
public ActionResult Drop()
{
SampleEntities db3 = new SampleEntities();
List<tblDepartment> department = db3.tblDepartments.ToList();
ViewBag.DepartmentList = department;
return View();
}
Drop.cshtml
#model WebApplication7.Models.EmployeeViewModel
#{
ViewBag.Title = "Drop";
}
<h2>Drop</h2>
<div class="container-fluid" style="width:40%">
#Html.DropDownListFor(model=>model.DepartmentId,ViewBag.DepartmentList as
SelectList,"--Select--",new {#class="form-control" })
</div>
in your model create a new class. Try to use ViewModel
public class tblDepartmentVW
{
public int tblDepartmentid{ get; set; }
public IEnumerable<tblDepartment> tblDepartments{ get; set; }
//other data
}
In your Controller
public ActionResult Drop()
{
SampleEntities db3 = new SampleEntities();
tblDepartmentVW deptmodel= new tblDepartmentVW {
tblDepartments =db3.tblDepartments.ToList(),
//fill your properties from database
}
return View(deptmodel);
}
Check this link for more detail

Create DropDownListFor from List<myType>

I have the following classes:
public class Nationality
{
public int ID { get; set; }
public string name { get; set; }
}
public class PersonalData
{
public List<Nationality> availableNationalities { get; set; }
public PersonalData()
{
availableNationalities = new List<Nationality>();
}
}
In my view, I want to create a DropDownlistFor using the availableNationalities field on the PersonalData.
Follows a piece of view code and an example what I'm trying to do:
#model PersonalData
#Html.DropDownListFor(
model => model.personalData.nationality,
new SelectList(Model.availableNationalities, "ID", "name"),
"Choose please an option",
new { required = "required" }
)
Thank you in advance
Your code will throw an exception as there is no personalData property on your PersonalData view model.
Add one more property in your view model to store the selected option value
public class PersonalData
{
public int SelectedNationality { set;get;}
public List<Nationality> AvailableNationalities { get; set; }
public PersonalData()
{
AvailableNationalities = new List<Nationality>();
}
}
Now in your view you can use the select tag helper (in your ASP.NET Core app)
#model PersonalData
<form asp-controller="Home" asp-action="Create">
<select asp-for="SelectedNationality"
asp-items="#(new SelectList(Model.AvailableNationalities ,"Id","Name"))">
<option>Please select one</option>
</select>
<input type="submit"/>
</form>
If it is a Non core app, you can use the DropDownListFor helper
#Html.DropDownListFor(
a=> a.SelectedNationality,
new SelectList(Model.AvailableNationalities, "ID", "name"),
"Choose please an option",
new { required = "required" }
)
Assuming your GET action method set the AvailableNationalities property on your PersonalData viewmodel object before sending it to the view.
public IActionResult Create()
{
var vm=new PersonalData
{
AvailableNationalities = new List<Nationality>
{
new Nationality { Id=1, Name="USA"},
new Nationality { Id=2, Name="Canada"},
}
};
return View(vm);
}
If all you care about is rendering a SELECT element in the view, you may simply use a List<SelectListItem> instead of List<Nationality> as explained in this post

How to keep the values filled in a form and recover after navigating to another controller

I am facing this situation. I have a form that I filled with three values. Then by clicking on a button I'm in another controller and I create an XmlDocument object I recovered via TempData. Once completed action coming back to my form naturally when all data has disappeared. My question is, how do I fill out the form, keep these values, and once the XML created to fill my database with the form data and XML created.
Layout controller
public class LayoutController : Controller
{
[HttpGet]
public ActionResult Create()
{
var Layout = new LayoutModel();
return View(Layout);
}
[HttpPost]
public ActionResult Create(LayoutModel Layout)
{
if (Layout == null)
{
return Content("le LayoutModel est nul");
}
else
{
TempData["DocName"] = Layout.Nom;
if (TempData["xmlAssociated"] != null)
{
Layout.xmlAssociated = (string)TempData["xmlAssociated"];
ManageXML.Models.COracleConn.GetInstance().InsertLayout(Layout);
}
else
{
return Content("On a pas recuperé l'XML");
}
return RedirectToAction("ListOfTopsAndMarges", "Entete_Marge");
}
}
}
XMLRecord controller
public class XMLRecordController : Controller
{
[HttpGet]
public ActionResult HandleForm()
{
var file = new XMLRecord()
{
Records = new List<XMLRecord>(){ new XMLRecord(){ Type="", Contenu="" }}
};
return View(file);
}
[HttpPost]
public ActionResult HandleForm(XMLRecord file)
{
if (file == null)
{
return HttpNotFound();
}
else
{
file.DocName = (string)TempData["DocName"];
string recup = file.GenerateXML(file);
TempData["xmlAssociated"] = recup;
return RedirectToAction("Create", "Layout");
}
}
}
public class LayoutModel
{
public string Nom { get; set; }
public string Type { get; set; }
public string Contenu { get; set; }
public string xmlAssociated {get; set;}
}
I want to retain my Type, my Contenu and my Nom properties even if I am going to another controller
Thnak for your help #Heymega

How to bind bropdown list in Razor View (If view is not bound with any model)

Can anybody suggest me how bind a dropdown list in MVC Razor view. I am using MVC 4. I have a view that is not bound with any model class.
public class Util {
public List<EmployeeType> GetEmpTypes() {
return (new List<EmployeeType>(){
new EmployeeType(){ID=101, Text="Permanent"},
new EmployeeType(){ ID=102, Text="Temporary"}
});
}
}
public class EmployeeType {
public int ID { get; set; }
public string Text { get; set; }
}
I have this sample code. I am new to MVC Now after this I don't know how to bind the collection returned by GetEmployeeTypes() Method to a dropdown list
Your class with method
public class Util {
public List<EmployeeType> GetEmpTypes() {
return (new List<EmployeeType>(){
new EmployeeType(){ID=101, Text="Permanent"},
new EmployeeType(){ ID=102, Text="Temporary"}
});
}
}
Your model class with properties
public class EmployeeType {
public int ID { get; set; }
public string Text { get; set; }
}
This is sample action
public ActionResult ViewName()
{
Util xxx=new Util();
List<SelectList> SelectedItems =new List<SelectList>();
List<EmployeeType> items =xxx.GetEmpTypes();
foreach (var t in items )
{
SelectListItem s = new SelectListItem();
s.Text = t.Text;
s.Value = t.ID;
SelectedItems.Add(s);
}
ViewBag.xxxxx= SelectedItems;
return view();
}
In View
#Html.DropDownList("xxxxx", new SelectList(ViewBag.xxxxx, "Text", "Value"))
This above code just like a key, i don't tested for that code ran successfully. you can get some idea for how to bind dropdown from my code.
I had a Class like this to get all EmployeeTypes
public class Util
{
public List<EmployeeType> GetEmpTypes()
{
return (new List<EmployeeType>(){
new EmployeeType(){ID=101, Text="Permanent"},
new EmployeeType(){ ID=102, Text="Temporary"}
});
}
}
public class EmployeeType
{
public int ID { get; set; }
public string Text { get; set; }
}
In Controller I have written code to get the List of Employee Types
Util obj = new Util();
var v = obj.GetEmpTypes();
ViewBag.EmployeeTypes = v;
return View();
In the View I have written code to bind dropdown.
#Html.DropDownList("EmployeeTypes",new SelectList(ViewBag.EmployeeTypes,"ID","Text"));
Thanks #Ramesh Rajendran ( Now I understood the concept to bind dropdown)
*strong text*you should create the model selectlist like here:
public static List<EmployeeType> GetEmpTypes() {
return (new List<EmployeeType>(){
new EmployeeType(){ID=101, Text="Permanent"},
new EmployeeType(){ ID=102, Text="Temporary"}
});
}
public static SelectList GetMyEmpTypes
{
get { return new SelectList(GetEmpTypes(), "ID", "Text"); }
}
then you access this method in dropdown list like
#Html.DropDownList("Name",yourProjectNameSpace.Util.GetMyEmpTypes())
when you will submit your form then it value bidden with Name get post to controller.
it is not necessary to bind with model class.you can receive the value on controller with the name that you have given in view like:
#Html.DropDownList("Name",yourProjectNameSpace.YourClass.GetEmpTypes())
Now you can recive the name value at controller like:
public ActionResult test(String Name)
{
return view();
}
and make your method static i.e GetEmpTypes() so that you can access it from view.

ASP.net MVC: How do I define a razor inline template in code?

I'm using razor inline template to define the grid columns format.
This work great if you are defining the inline template inside a razor view.
How can I do the same (defining the column list with inline templates) in code in the controller?
Here is the sample code. You can also get view code using this. See also this for extending the grid,
public class HomeController : Controller
{
public class Employee
{
public string Name { get; set; }
public string Description { get; set; }
public int Price { get; set; }
}
public ActionResult Index()
{
var myClasses = new List<Employee>{
new Employee { Name="A" , Price=1, Description="A A"},
new Employee { Name="B" , Price=2, Description="B B"},
new Employee { Name="C" , Price=3, Description="C C"}};
var grid = new WebGrid(source: myClasses);
var html = grid.GetHtml(
columns: grid.Columns(
grid.Column("Name", "Product", style: "product"),
grid.Column("Description", format: item => new System.Web.WebPages.HelperResult(writer =>
{
WriteLiteralTo(writer, "<i>");
WriteTo(writer, item.Description);
WriteLiteralTo(writer, "</i>");
})),
grid.Column("Price", format: item => new System.Web.WebPages.HelperResult(wrtier =>
{
WriteLiteralTo(wrtier, "$");
WriteTo(wrtier, item.Price);
}))
)
);
return View();
}
private void WriteLiteralTo(TextWriter writer, object content)
{
writer.Write(HttpUtility.HtmlEncode(content));
}
public static void WriteTo(TextWriter writer, object content)
{
writer.Write(HttpUtility.HtmlEncode(content));
}
}

Resources