Pass model value from view to controller? - c#

How I can pass data from view to controller? Please explain how can I pass ID to AAA?
I have model:
public class ABCDE
{
public int ID { get; set; }
public string Name { get; set; }
public int Surname { get; set; }
public List<SelectListItem> MMM { get; set; }
}
My view:
#model IList<Jednoslad.Models.ABCDE>
#{
ViewBag.Title = "title";
Layout = "~/Views/Layout/_Layout.cshtml";
}
#foreach (var m in Model)
{
using (Html.BeginForm("AAA", "BBB"))
{
<div class="moto">
<h1>#m.ID</h1>
<h2>#m.Name</h2>
<input type="submit" name="model" value="AAA"/>
</div>
}
}
My controller:
[HttpPost]
public ActionResult AAA(ABCDE model)
{
return View();
}

Use Html.EditorFor()
using (Html.BeginForm("AAA", "BBB"))
{
<div class="moto">
<h1>#Html.EditorFor(m => m.ID)</hi>
<h2>#Html.EditorFor(m =>m.Name)</h2>
<input type="submit" name="model" value="AAA"/>
</div>
}

Related

Partial view data doesn't get saved in ASP.NET Core MVC

I create class Project in project class I define technology and another i define Class Technology I seed data in technology and after that i create dropdown list in Project Create view using a partial view and when I save data the technology can not be saved
public class Project
{
public int ProjectId { get; set; }
[StringLength(60, MinimumLength = 3)]
public string? ProjectName { get; set; }
public string? Description { get; set; }
public DateTime Start { get; set; }
public DateTime? End { get; set; }
public string? ProjectHead { get; set; }
public string? Status { get; set; }
public string? Technology { get; set; }
}
public class Technology
{
public int TechnologyId { get; set; }
public string? TechnologyName { get; set; }
}
This is my controller:
public async Task<IActionResult> Create([Bind("ProjectId,ProjectName,Description,Start,End,ProjectHead,Status,Technology")] Project project)
{
if (ModelState.IsValid)
{
_context.Add(project);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(project);
}
This is my view of project create:
<div class="row">
<partial name="_Technologypartial" />
</div>
technology Patial
#model TeamManagement.Models.Technology
<div class="row">
<div class="form-group col-md-6">
<label>Technology</label>
<br />
<select asp-for="TechnologyId" class="form-control" asp-items="#(new SelectList(ViewBag.Technology,"TechnologyId","TechnologyName"))">
</select>
</div>
</div>
EDIT
View
<div class="row">
<partial name="_Technologypartial" model="#Model.technology" />
</div>
Controller
{
var list = _context.Technology.ToList();
List<SelectListItem> dropdown = new List<SelectListItem>();
foreach (var item in list)
{
dropdown.Add(new SelectListItem()
{
Text = item.TechnologyName,
Value = item.TechnologyId.ToString()
});
}
PartialViewData model = new PartialViewData();
ViewBag.Technology = dropdown;
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(PartialViewData model)
{
if (ModelState.IsValid)
{
Project project = new Project()
{
ProjectId = model.project.ProjectId,
ProjectName = model.project.ProjectName,
Description = model.project.Description,
Start = model.project.Start,
End = model.project.End,
ProjectHead = model.project.ProjectHead,
Status = model.project.Status,
Technology = model.technology.TechnologyId.ToString()
};
_context.Add(project);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(model);
}
When you select an option in Partial View, After submiting the form, You want save the value of option. I suggest you to use ViewModel to achieve it. Refer to this simple demo:
I simplified your class for testing convenience.
public class Project
{
public string Name { get; set; }
public string? Technology { get; set; }
}
public class Technology
{
public int TechnologyId { get; set; }
public string? TechnologyName { get; set; }
}
Create a View model to pass the value.
public class PartialViewData
{
public PartialViewData()
{
project = new Project();
technology = new Technology();
}
public Project project { get; set; }
public Technology technology { get; set; }
}
DbContext
public class MvcMovieContext : DbContext
{
public MvcMovieContext(DbContextOptions<MvcMovieContext> options) : base(options)
{
}
public DbSet<Technology> technology { get; set; }
}
Controller
public class HomeController : Controller
{
private readonly MvcMovieContext _context;
public HomeController(MvcMovieContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
var list = _context.technology.ToList();
List<SelectListItem> dropdown = new List<SelectListItem>();
foreach(var item in list)
{
dropdown.Add(new SelectListItem()
{
Text = item.TechnologyName,
Value = item.TechnologyId.ToString()
}) ;
}
PartialViewData model = new PartialViewData();
ViewBag.Technology = dropdown;
return View(model);
}
[HttpPost]
public IActionResult Privacy(PartialViewData model)
{
Project project = new Project()
{
Name = model.project.Name,
Technology = model.technology.TechnologyId.ToString()
};
//......
return View();
}
}
View
#model PartialViewData
<form method="post">
<input asp-for="#Model.project.Name" />
<div class="row">
<partial name="_Technologypartial" model="#Model.technology" />
</div>
<button type="submit">submit</button>
</form>
_Technologypartial
#model Technology
<div class="row">
<div class="form-group col-md-6">
<label>Technology</label>
<br />
<select name="technology.TechnologyId" class="form-control" asp-items=#ViewBag.Technology>
</select>
</div>
</div>
Demo:
Edit=================
public IActionResult Create()
{
var list = _context.technology.ToList();
List<SelectListItem> dropdown = new List<SelectListItem>();
foreach(var item in list)
{
dropdown.Add(new SelectListItem()
{
Text = item.TechnologyName,
Value = item.TechnologyId.ToString()
}) ;
}
PartialViewData model = new PartialViewData();
ViewBag.Technology = dropdown;
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(PartialViewData model)
{
if (ModelState.IsValid)
{
//change here
var name = _context.Technology.Where(x => x.TechnologyId == model.technology.TechnologyId).Select(x => x.TechnologyName).FirstOrDefault();
Project project = new Project()
{
ProjectId = model.project.ProjectId,
ProjectName = model.project.ProjectName,
Description = model.project.Description,
Start = model.project.Start,
End = model.project.End,
ProjectHead = model.project.ProjectHead,
Status = model.project.Status,
//change here
Technology = name
};
_context.Add(project);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(model);
}
View
#model PartialViewData
<div class="row">
<partial name="_Technologypartial" model="#Model.technology" />
</div>
_Technologypartial
#model Technology
<div class="row">
<div class="form-group col-md-6">
<label>Technology</label>
<br />
<select name="technology.TechnologyId" class="form-control" asp-items=#ViewBag.Technology>
</select>
</div>
</div>

How to get List<object> as parameter in action in ASP.NET Core MVC

I have a class which its name is "Question.cs" and I have another one that its name is "Answer.cs".
I want to send List of Questions to my action instead of one Question and I don't know how can I do it.
In fact, I don't know how to get the Questions as parameter. Can anyone tell me how I can receive the Questions in the action?
Here are my classes:
public class Question
{
[Key]
public int QuestionId { get; set; }
[Required]
[MaxLength(500)]
public string QuestionTitle { get; set; }
[Required]
[MaxLength(500)]
public string QuestionAnswer { get; set; }
//property
public List<Answer> Answers { get; set; }
}
public class Answer
{
[Key]
public int AnswerId { get; set; }
[Required]
public int QuestionId { get; set; }
[Required]
[MaxLength(500)]
public string AnswerTitle { get; set; }
//property
[ForeignKey("QuestionId")]
public Question Question { get; set; }
}
This is my Razor View (Question.cshtml) :
#using GameShop.Data.Domain.QuestIonsAnswers
#model List<GameShop.Data.Domain.QuestIonsAnswers.Question>
#{
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<form asp-action="Index" method="POST">
#foreach (var item in Model)
{
<div>#item.QuestionTitle</div>
<input asp-for="#item.QuestionAnswer" Value="#item.QuestionId" />
<br />
}
<input type="submit" class="btn btn-primary" value="ثبت">
</form>
As you see, I used a foreach loop which is give me all of the "Questions". So I can't receive just one "Question" in my action. These are my actions:
public IActionResult Index()
{
return View(_context.Questions.ToList());
}
[HttpPost]
public IActionResult Index(Question question)
{
foreach (var item in question)
{
var ans=new Answer(){
QuestionId=item.QuestionId,
AnswerTitle=item.QuestionAnswer
};
_context.Answers.Add(ans);
_context.SaveChanges();
}
return View(_context.Questions.ToList());
}
I think I have to get List<Question> in my second action but I don't know how?
Can anyone help me step by step?
Please refer to the following steps to modify your code:
In the View page, use for loop to loop through the Model and display the value. code like this:
#model List<WebApplication6.Models.Question>
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<form asp-action="Index" method="POST">
#for (var i = 0; i < Model.Count(); i++)
{
<div>#Model[i].QuestionTitle</div>
<input asp-for="#Model[i].QuestionId" type="hidden" />
<input asp-for="#Model[i].QuestionTitle" type="hidden" />
<input asp-for="#Model[i].QuestionAnswer" />
<br />
}
<input type="submit" class="btn btn-primary" value="ثبت">
</form>
In the Post method, change the parameter data type to List<Question>.
[HttpPost]
public IActionResult Index(List<Question> questions)
{
foreach (var item in questions)
{
//var ans = new Answer()
//{
// QuestionId = item.QuestionId,
// AnswerTitle = item.QuestionAnswer
//};
//_context.Answers.Add(ans);
//_context.SaveChanges();
}
return View(_context.Questions.ToList());
}
Then, the result like this:

FormMethod.Post returning 0

I have a problem with a FormMethod Post, I'm trying to post one single value (id) and store it in a Session variable, but the value return 0.
This is my code.
#foreach (var item in Model)
{
using (#Html.BeginForm("Index", "ProductSelec", FormMethod.Post))
{
#Html.HiddenFor(modelItem => item.id, new { value = "#Html.DisplayFor(modelItem => item.id)" })
<div class="AppOpt">
<button type="submit" name="submit" style="background-image: url('../Content/ICONS/SystemApp/#Html.DisplayFor(modelItem => item.img)');border-radius: 20px;background-size: cover;background-repeat: no-repeat;" class="AppImg">
<div class="OptNameRec">
<div class="OptIcon">
<img src='~/Content/ICONS/#Html.DisplayFor(modelItem => item.icon)'>
</div>
<div>
<p>#Html.DisplayFor(modelItem => item.nombre)</p>
</div>
<div class="clear"></div>
</div>
<div class="OptImage"></div>
</button>
</div>
}
}
The form is inside the foreach, becuase I'm creating the elements dinamically from a DB.
I want to store the item.id clicked.
This is my Controller
public ActionResult Index()
{
return View(db.aplicaciones.ToList());
}
public ActionResult ProductFamily()
{
return View();
}
[HttpPost]
public int Index(aplicaciones aplicaciones)
{
Session["appID"] = aplicaciones.id;
return aplicaciones.id;
}
and this is my Model.
public partial class aplicaciones
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public aplicaciones()
{
this.appNfam = new HashSet<appNfam>();
}
public int id { get; set; }
public string nombre { get; set; }
public string icon { get; set; }
public string img { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<appNfam> appNfam { get; set; }
}
I was trying to create another Model, but when I added, the foreach didn't read the values from the database.
I hope you can help me.
Change your controller method to:
[HttpPost]
public int Index(int id)
{
Session["appID"] = id;
return id;
}
Change your Html.BeginForm to be:
#using (Html.BeginForm("Index", "ProductSelec", new { id = item.id },FormMethod.Post, new { })
You should also be able to remove the hidden field since the ID will be posted by itself from your form action.

Partial View returning Null model ASP.NET MVC 4

Within my MainView, I was able to render all the "TaskComment"(model) using _GetForTask partial view. Then within my _GetForTask partial view, I was able to render _TaskCommentForm and successfull passed a new instance of TaskComment model. However, whenever I click the "Submit" button in the _TaskCommentForm partial view, it always returns null. What am I missing here? Thanks a lot.
"TaskComment" model
public partial class TaskComment
{
public int TaskCommentID { get; set; }
public Nullable<int> TaskID { get; set; }
public Nullable<int> AuthorID { get; set; }
public string Comment { get; set; }
public Nullable<System.DateTime> TimeStamp { get; set; }
public virtual Task Task { get; set; }
public virtual Employee Employee { get; set; }
}
Here's my "MainView"
#Html.Action("_GetForTask", "TaskComment", new { TaskID = Model.TaskID })
_GetForTask PartialView
#model IEnumerable<ProjectYesha.Models.TaskComment>
<div id="comments">
<ul>
#foreach (var taskComment in Model)
{
<li>#taskComment.Comment</li>
}
</ul>
#using (Html.BeginForm("_Submit", "TaskComment", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.Action("_TaskCommentForm", "TaskComment", new { TaskID = ViewBag.TaskID })
}
</div>
_TaskCommentForm PartialView
#model ProjectYesha.Models.TaskComment
#Html.HiddenFor(m=> m.TaskCommentID)
#Html.HiddenFor(m=> m.TaskID)
#Html.HiddenFor(m=> m.AuthorID)
#Html.HiddenFor(m=> m.TimeStamp)
#Html.HiddenFor(m=> m.Employee)
#Html.HiddenFor(m=> m.Task)
<div>
#using (Html.BeginForm())
{
#Html.EditorFor(m => m.TaskID)
#Html.EditorFor(m => m.Comment)
<input type="submit" value = "Submit" />
}
</div>
TaskCommentController
public PartialViewResult _GetForTask(Int32 taskID)
{
ViewBag.TaskID = taskID;
List<TaskComment> comments = db.TaskComments.Where(c => c.TaskID == taskID).ToList();
return PartialView("_GetForTask", comments);
}
[ChildActionOnly()]
public PartialViewResult _TaskCommentForm(Int32 taskID)
{
TaskComment comment = new TaskComment()
{
TaskID = taskID ,
};
return PartialView("_TaskCommentForm", comment);
}
[HttpPost]
[ValidateAntiForgeryToken()]
public PartialViewResult _Submit(TaskComment comment)
{
db.TaskComments.Add(comment);
db.SaveChanges();
List<TaskComment> comments = db.TaskComments.Where(c => c.TaskID == comment.TaskID).ToList();
ViewBag.TaskID = comment.TaskID;
return PartialView("_GetForTask", comments);
}

using strongly typed partial views inside another Strongly Typed view

I have NameModel and RegisterModel and SuperClass classes as below: -
Case 1: - Using SuperClass
public class SuperClass
{
public RegisterModel Register{ get; set; }
public NameModel NameInfo { get; set; }
}
public class NameModel
{
[Required]
public string FirstName { get; set; }
public string MiddleName { get; set; }
[Required]
public string LastName { get; set; }
}
public class RegisterModel
{
public NameModel NameInfo{ get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set;}
}
MyNamePartial strongly typed View is as follows :-
#model MyNamespace.Models.NameModel
#{
Layout = null;
}
{
#Html.TextBoxFor(m=>m.FirstName,new { #id="firstName"} )
#Html.TextBoxFor(m=>m.MiddleName,new { #id="middleName"} )
#Html.TextBoxFor(m=>m.LastName,new { #id="lastName"} )
}
My Registration View is strongly typed of Register Model as follows :-
#model MyNamespace.Models.SuperClass
#{
Layout = "~/Views/_Layout.cshtml";
}
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
<div id="form">
#Html.Partial("NameModel",Model.NameInfo)
#Html.TextBoxFor(m=>m.Register.UserName,new { #id="userName"})
#Html.TextBoxFor(m=>m.Register.Password,new { #id="password"})
<input type="submit" value="Register" id="btnRegister" />
</div>
}
Above approach gives object reference error.
Case 2: - Using HTML.Action and no SuperClass
Tried using #Html.Action("MyNamePartialView")instead of #Html.Partial("NameModel",Model.NameInfo),Then I use Controller Action method as below
My Registration View is strongly typed of Register Model as follows :-
#model MyNamespace.Models.RegisterModel
#{
Layout = "~/Views/_Layout.cshtml";
}
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
<div id="form">
#Html.Action("MyNamePartialView")
#Html.TextBoxFor(m=>m.UserName,new { #id="userName"})
#Html.TextBoxFor(m=>m.Password,new { #id="password"})
<input type="submit" value="Register" id="btnRegister" />
</div>
}
Register Controller :-
public ActionResult MyNamePartialView()
{
return PartialView("MyNamePartial", new NameModel());
}
[HttpPost]
[AllowAnonymous]
public ActionResult Register(RegisterrModel model)
{
#ViewBag.sideMenuHeader = "Create an Account";
if (ModelState.IsValid)
{
//Perform Something
return View();
}
return View();
}
The above case doesnt bind the values entered on form. it sets null for NameModel.
I don't want to use EditorFor as i have to supply html and custom attributes to helpers.The binding for the partial view fails.it gives me object reference error in Registration view. How can i use such strongly typed Partial views with such a such Model class hierarchy as explained above ?
The simplest way to do this is to use a child action
#model MyNamespace.Models.Register.SuperModel
#{
Layout = "~/Views/_Layout.cshtml";
}
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
<div id="form">
#Html.Action("MyNamePartialView")
</div>
#Html.TextBoxFor(m=>m.Register.UserName,new { #id="userName"})
#Html.TextBoxFor(m=>m.Register.Password,new { #id="password"})
<input type="submit" value="Register" id="btnRegister" />
}
make your action post accept 2 classes
public ActionResult Register(RegisterModel RegisterInfo, NameModel NameInfo)

Categories

Resources