I have a form in which the user is supposed to enter Name and Wage and click a button Add. When the button "Add" is clicked, that user is supposed to be displayed on a list.
This is how I tried it.
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TimeIsMoney.Models;
namespace TimeIsMoney.Controllers
{
public class HomeController : Controller
{
List<UserModel> users = new List<UserModel>();
public ActionResult Index(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
public ActionResult AddUser(UserModel user)
{
users.Add(user);
return View(users);
}
}
}
View:
#model TimeIsMoney.Models.LoginModel
#{
}
#functions{
public string GetAntiForgeryToken()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
<div id="main-content" class="col-md-8 col-md-offset-2">
<div class="col-md-12 row">
<h1>Time is money my friend!</h1>
</div>
<div class="col-md-12 row">
<h2>1000kr</h2>
</div>
<div class="col-md-12 row">
<button class="btn" onclick="start()">Start</button>
<button class="btn" onclick="reset()">Reset</button>
</div>
<div class="col-md-12 row">
<form >
<input type="text" placeholder="Name" />
<input type="number" placeholder="Hourly wage" />
<input type="submit" value="Add" onclick="AddUser()" />
</form>
</div>
<div class="col-md-12 row">
<div class="col-md-3 col-md-offset-1">
<label>Name:</label>
<ul>
<li>Dave</li>
<li>Pete</li>
</ul>
</div>
<div class="col-md-4">
<label>Wage:</label>
<ul>
<li>500kr/h</li>
<li>500kr/h</li>
</ul>
</div>
</div>
<br />
<br />
</div>
Model:
namespace TimeIsMoney.Models
{
public class UserModel
{
[Required]
[DataType(DataType.Text)]
[DisplayName("Username")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Text)]
[DisplayName("Wage")]
public string Wage { get; set; }
}
}
Am I on the right path?
How can I move on from here?
UPDATE:
public ActionResult AddUser(UserModel user)
{
var list = Session["myUsers"] as List<UserModel>;
list.Add(user);
return View(list);
}
You're mostly on the right path excluding way you're trying to store your users list.
Since ASP.NET MVC controller instance is created for every request and disposed after view is rendered and passed to the browser - it will be new controller holding new List<UserModel> created on every request.
So you have to store it somewhere else (session variables, file on server's disk, database and so on). Usually database is best choice for this.
In the case you want to store it in session variable, you should add something like this into Global.asax:
protected void Session_Start(object sender, EventArgs e)
{
Session["myUsers"] = new List<UserModel>();
}
and then in your controller's methods you will be able to access this list as
var list = Session["myUsers"] as List<UserModel>;
Related
I've a Page entity dependent on Investor entity as investor creates a page:
public class Page
{
[Required, DatabaseGenerated(DatabaseGeneratedOption.Identity), Key]
public Guid Id { get; set; }
[Required(ErrorMessage = "Describe the idea of your blog")]
public string Description { get; set; }
[Display(Name = "Тags")]
[Required(ErrorMessage = "Let people know what content you're going to share")]
public ICollection<Investor> Subscribers { get; set; }
public Guid AuthorId { get; set; }
public Investor Author { get; set; }
}
That's what in my dbContext:
modelBuilder.Entity<Page>()
.HasOne(b => b.Author)
.WithOne(u=> u.Page)
.HasForeignKey<Page>(b => b.AuthorId)
.OnDelete(DeleteBehavior.Restrict);
Here's the controller for creating a Page:
public class PageController : Controller
{
private readonly DataManager _dataManager;
private readonly UserManager<ApplicationUser> _userManager;
public PageController(UserManager<ApplicationUser> userManager, DataManager dataManager)
{
_userManager = userManager;
_dataManager = dataManager;
}
public IActionResult Create(Guid Id)
{
var investor = _dataManager.Investors.GetInvestorById(Id);
if (investor.Page != null)
{
return RedirectToPage("/Account/ProfileCheck", new { Id = investor.User.Id, area = "Identity"});
}
var page = new Page();
return View(page);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Page page)
{
if (ModelState["Description"].Errors.Count() == 0)
{
var currentUserId = _userManager.GetUserId(HttpContext.User);
var investor = _dataManager.Investors.GetInvestorByUserId(currentUserId);
page.Author = investor;
_dataManager.Pages.SavePage(page);
return RedirectToPage("/Account/ProfileCheck", new { Id = investor.User.Id, area = "Identity" });
}
return View(page);
}
}
However, In HttpPost Action that page has an Id and this Id equals to author's Id who created it.
This's the view for Create action
#model FinicWebApp.Domain.Entitites.Page
<form method="post" asp-action="Create">
<div class="border p-3">
<div asp-validation-summary="ModelOnly" class="text-danger" ></div>
<div class="form-group row">
<h2 class="text-black-50 pl-3">Create Page</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-6">
<label asp-for="Description"></label>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-8 text-center row">
<div class="col">
<input type="submit" class="btn btn-info w-75" value="Create"/>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
In my db all the pages' ids equal to investors' ids who created them. But I need pages' ids to be different. How can I get it?
I have a partial view which will be used by multiple views. I am using a select 2 control to populate the account number then when user clicks go button it gets account information.
When the user selects the account and clicks go the value in the controller of the parent comes
as null
Please see the below code.
if you see the below code //accountInfo.AccountSearch.AccountNumber -- this value comes in as null
Partial view - view model
public class AccountSearchViewModel
{
[Display(Name = "Account Number"), DataType(DataType.Text)]
public string AccountNumber { get; set; }
}
Parent view Model
public class AccountInfoViewModel
{
public string AccountName { get; set; }
public string Adddress { get; set;}
public string City { get; set;}
public string Zip { get; set; }
public string PhoneNumber { get; set;}
public AccountSearchViewModel AccountSearch
{
get
{
if(_accountSearch == null)
{
_accountSearch = new AccountSearchViewModel();
}
return _accountSearch;
}
set { _accountSearch = value; }
}
private AccountSearchViewModel _accountSearch;
}
Partial view cshtml
#model Vfs.PsfProWeb.Models.Fleet.AccountSearchViewModel
<div class="col-md-10">
<label> Account Number</label>
<div class="input-group">
<select id="mySelect2" class="form-control accountSelect" text=#Model.AccountNumber></select>
</div>
</div>
Parent view - which calls the partial view
#model Vfs.PsfProWeb.Models.Fleet.AccountInfoViewModel
<div class="card-body pt-2">
<div class="form-row">
<div class="col-11">
#(await Html.PartialAsync("~/Views/Fleet/_AccountNumberSearch.cshtml",Model.AccountSearch))
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-primary" asp-action="GetAccountInformation" asp-controller="AccountInfo">Go</button>
</div>
</div>
</div>
Parent controller
public IActionResult GetAccountInforAccountInfoViewModel accountInfo)
{
try
{
//accountInfo.AccountSearch.AccountNumber -- this value comes in as null
var acctInfo = _accountDomain.GetAcctInfoEntity(accountInfo.AccountSearch.AccountNumber));
return View("~/Views/Fleet/AccountOtb.cshtml", acctInfo);
}
catch (Exception ex)
{
throw;
}
}
The select name should match the model property name like below:
<select id="mySelect2" class="form-control accountSelect" name="AccountSearch.AccountNumber"
text=#Model.AccountNumber></select>
Here is the whole working demo:
View:
#model AccountInfoViewModel
<form asp-action="GetAccountInformation" asp-controller="Home">
<div class="card-body pt-2">
<div class="form-row">
<div class="col-11">
#(await Html.PartialAsync("_partial",Model.AccountSearch))
</div>
<div class="col-md-1">
<button type="submit" class="btn btn-primary" >Go</button>
</div>
</div>
</div>
</form>
#section Scripts
{
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<script>
$(document).ready(function () {
$("#mySelect2").select2();
})
</script>
}
Partial View:
#model AccountSearchViewModel
<div class="col-md-10">
<label> Account Number</label>
<div class="input-group">
<select id="mySelect2" class="form-control accountSelect" text=#Model.AccountNumber
name="AccountSearch.AccountNumber">
<option value="Select" disabled>Select</option>
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
<option value="ccc">ccc</option>
<option value="ddd">ddd</option>
</select>
</div>
</div>
Result:
I am trying to post data from form to action method but looks like model binder is not binding to the entities and I am getting null values in the action method, your help is much appreciated
please find the code snippet below.
Action method
[HttpPost]
public async Task<IActionResult> Update(EditRoleViewModel model)
{
if (ModelState.IsValid)
{
var role = await _Roleame.FindByIdAsync(model.Id);
if (role == null)
{
return RedirectToAction("notfound");
}
role.Name = model.RoleName;
var result = await _Roleame.UpdateAsync(role);
if (result.Succeeded)
{
return RedirectToAction("getAllRoles", "Administrator");
}
}
else {
ModelState.AddModelError(string.Empty, "Error");
}
return View();
}
Model
public class EditRoleViewModel
{
public EditRoleViewModel()
{
names = new List<string>();
}
public string Id;
[Required]
public string RoleName;
public List<string> names;
}
View
#model FirstCoreApplication.Model.EditRoleViewModel
<script src="~/twitter-bootstrap/js/bootstrap.js"></script>
<link href="~/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
#{
ViewBag.Title = "Edit Role";
}
<h1>Edit Role</h1>
<form method="post" class="mt-3" asp-controller="Administrator" asp-action="Update">
<div class="form-group row">
<label asp-for="Id" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Id" disabled class="form-control">
</div>
</div>
<div class="form-group row">
<label asp-for="RoleName" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="RoleName" class="form-control">
<span asp-validation-for="RoleName" class="text-danger"></span>
</div>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Update</button>
<a asp-action="ListRoles" class="btn btn-primary">Cancel</a>
</div>
</div>
<div class="card">
<div class="card-header">
<h3>Users in this role</h3>
</div>
<div class="card-body">
#if (Model.names.Any())
{
foreach (var user in Model.names)
{
<h5 class="card-title">#user</h5>
}
}
else
{
<h5 class="card-title">None at the moment</h5>
}
</div>
<div class="card-footer">
Add Users
Remove Users
</div>
</div>
</form>
enter code here
I've spent couple of hours looking for an error in my code and the reason for the binder not working in my case was using a model with public fields rather than public properties:
public class EditRoleViewModel
{
public EditRoleViewModel()
{
names = new List<string>();
}
public string Id { get; set; }
[Required]
public string RoleName { get; set; }
public List<string> names { get; set; }
}
The form data you post does not match the property of your model.You do not post the parameter names .
public List names { get; set; }
I'm Using Razor Pages For my App, in one part of my app I've used a partial view here is my codes;
public class Permission
{
[Key]
public int PermissionId { get; set; }
public string PermissionTitle { get; set; }
public int? ParentID { get; set; }
}
public class IndexModel : PageModel
{
public PartialViewResult OnGetCreateRole()
{
var ListPermission = permissionService.AllPermission();
return new PartialViewResult()
{
ViewName = "_PCreateRole", // partial's name
ViewData = new ViewDataDictionary<List<Permission>>(ViewData,
ListPermission)
};
}
}
ViewData is a List of Permission class and i've sent ViewData to partial but i dont know how to get ViewData, also my partial use another model, below is my partial:
#model ToMVC.DataLayer.Entities.User.Role
<div class="row">
<div class="col-md-12">
<form asp-page="CreateRole" method="post">
<div class="form-group">
<label class="control-label">Title</label>
<input asp-for="RoleTitle" class="form-control"/>
<p><span class="text-danger" asp-validation-for="RoleTitle"></span></p>
</div>
<div class="form-group">
<input type="submit" value="submit" class="btn btn-primary" />
</div>
//this part needs ViewData
#foreach (var item in ViewData)
{
}
</form>
</div>
</div>
I want to use ViewData in Foreach loop.
A better solution than ViewData would be to simply make a new ViewModel class containing all the information you need for a view.
public class UserRoleAndPermissions{
public UserRoleAndPermissions(){
Permissions = new List<Permissions>();
}
public List<Permission> Permissions {get;set;}
public ToMVC.DataLayer.Entities.User.Role Role {get;set;}
}
And your view
//check your namespace here - this is just an example
#model ToMVC.DataLayer.UserRoleAndPermissions
<div class="row">
<div class="col-md-12">
<form asp-page="CreateRole" method="post">
<div class="form-group">
<label class="control-label">Title</label>
<input asp-for="RoleTitle" class="form-control"/>
<p><span class="text-danger" asp-validation-for="RoleTitle"></span></p>
</div>
<div class="form-group">
<input type="submit" value="submit" class="btn btn-primary" />
</div>
#foreach (var item in Model.Permissions)
{
}
</form>
</div>
</div>
How to get the Partial View object on form submit
Main View:
#model CreateCampaignModel
....
#using (Html.BeginForm("SubmitForm", "Campaign", FormMethod.Post))
{
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Step 2: Creative*</a>
</h4>
<a style="padding-left:90%;" id="lnkEdit">Edit</a>
</div>
#Html.EditorFor(m => Model.campaignCreativeModelList[0])
#foreach (var m in Model.campaignCreativeModelList)
{
<div id="collapse2" class="panel-collapse collapse">
#Html.Partial("~/Views/Campaign/_Creative.cshtml", m)
</div>
}
</div>
}
Creative Partial View:
<div class="panel-body">
<div class="form-group">
#Html.Partial("~/Views/Shared/_ImageVideoUploadView.cshtml", Model.socialJobMediaModel)
</div>
<div class="col-md-10">
<div class="editor-field">
<input type="submit" name="Save Group" value="Review and Submit" class="btn btn-primary" />
</div>
</div>
</div>
My Controller Action:
[HttpPost]
public ActionResult SubmitForm(CreateCampaignModel createCampaignModel)
{
return (View(BindCampaignModel()));
}
I want to return the campaignCreativeModel object to the controller with all the collections of partial views inside partial views.
My Main Model:
public class CreateCampaignModel
{
public List<CampaignCreativeModel> campaignCreativeModelList { get; set; }
public List<ClientAccountCampaignBundlesModel> clientAccountCampaignBundlesModelList { get; set; }
public List<CampaignBundleSchedulesModel> campaignBundleSchedulesModelList { get; set; }
public List<CampaignConfigurationModel> campaignConfigurationModelList { get; set; }
public CampaignConfigurationModel campaignConfigurationModel { get; set; }
}
My model have all the collections related to partial views in the main view.
Screenshot:
I haven't gone through your code completely
[HttpPost]
public ActionResult SubmitForm(list<CreateCampaignModel> createCampaignModelList)
{
return (View(BindCampaignModel()));
}
this is the idea, you can get collection,if you are building the partial view from the model, I haven't tested the code..