Model not being passed to controller - asp.net-core

One of my asp.net core pages isn't passing its model back to the controller. I've investigated similar threads in stackoverflow but none could solve my issue - what's different in this particular case?
In the attached MVC, I fill the input box "Enter here some text", then I click on button "CLICK HERE". The debugger enters correctly the controller but the variable "TEST" returns null.
Any geniuses out there able to help me out?
My Model:
namespace MyProgram.Models._04_ModuleTasker
{
public class TaskerViewModel
{
public SelectList SelectListLocations;
public SelectList SelectListUsers;
public SelectList SelectListFilters;
public string SelectedCompanyLocationDesc;
public string SelectedUserId;
public string SelectedFilter;
}
}
My View:
#model MyProgram.Models._04_ModuleTasker.TaskerViewModel
#{
ViewData["Title"] = "AllTasks";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container-fluid">
<div class="PageTitle">
Tasker
<hr class="TitleHR" />
</div>
<div style="text-align:center;margin-top:20px" class="text-body">
<form asp-controller="Tasker" asp-action="ShowActiveTasksPOST" method="post" role="form">
<input type="text" asp-for="SelectedUserId" /> Enter here some text <br />
<input type="submit" class="btn btn-success InputShortWidth LoginButton" value="CLICK HERE" />
</form>
</div>
</div>
My Controller:
[HttpPost]
public async Task<IActionResult> ShowActiveTasksPOST(TaskerViewModel taskerViewModel)
{
string TEST = taskerViewModel.SelectedUserId;
return RedirectToAction("Index", "Home");
}

To make the binding works, you need to convert the fields to properties with with setters and getters. E.g.:
public string SelectedCompanyLocationDesc { get; set; }
public string SelectedUserId { get; set; }
public string SelectedFilter { get; set; }

Related

Changing attributes of HTML element in server-side code in Razor Pages

I want to be able to access and modify attributes of HTML elements of a page in my server side code (I am using ASP.NET Core Razor Pages 6.0).
For example: a .cshtml file, I have a simple element like this:
<div class="mb-3 mt-3">
<label asp-for="User.firstname" class="form-label">First Name:</label>
<input asp-for="User.firstname" class="form-control" placeholder="First Name">
</div>
How do I access & change attributes of the above <input> element inside the OnGet or OnPost server-side methods?
I need to do so as I want to add a class to that <input> element, or make it read-only (depending on certain conditions in my server code).
In older versions of .NET, I believe this was possible by giving an HTML element an ID, and writing runat="server". Then, one could access the element in the code-behind via its ID and change its attributes. How is this done now in Razor Pages?
Should I not be able to do the same because of the asp-for tag helper which I used inn my code above? But how?
Thank you for your help!
you can achieve sending Value to the server with
This at razor page:
<form method="post">
<div class="form-group">
<input name="title" class="form-control" placeholder="Type title here.." />
<button type="submit" class="btn btn-primary">Post</button>
</form>
This at Model Page
public async Task<IActionResult> OnPostAsync(string title)
{
//do your stuff
}
Put breakpoint at public async Taks and viola.
I believe this should do the trick. You can change it for yourself.
Here is a whole working demo you could follow:
Model
public class User
{
public string firstname { get; set; }
}
Page(.cshtml file)
#page
#model IndexModel
<form method="post">
<div class="mb-3 mt-3">
<label asp-for="User.firstname" class="form-label">First Name:</label>
<input asp-for="User.firstname" class="form-control" placeholder="First Name">
</div>
<input type="submit" value="Post"/>
</form>
PageModel(.cshtml.cs file)
1.For model binding of the element, one way is that you can use [BindProperty]:
public class IndexModel : PageModel
{
[BindProperty]
public User User { get; set; }
public void OnGet()
{
}
public void OnPost()
{
//do your stuff.....
}
}
2.The second way is that you can add parameters like below:
public class IndexModel : PageModel
{
public User User { get; set; }
public void OnGet()
{
}
public void OnPost(User User)
{
}
}

Editing single entry and show multiple in ASP.NET MVC

I am very new to this and I am trying to show multiple entries to show and have a single button for each entry to edit them. I thought it would be really easy but For some reason I am not getting the clicked entity. Is there way of getting modified entity without running javascript?
Any help will be appreciated. I couldn't find any example code that does this. There are many examples that returns all the entries but not the single element.
Here is my entity class Resource:
public class Resource
{
[Required]
public string title { get; set; }
[Required]
public int value { get; set; }
[Key]
[Required]
public int id { get; set; }
}
On the controller side I have:
[HttpGet]
public IActionResult Index()
{
return View(resources);
}
[HttpPost]
public IActionResult Index(Resource resource)
{
return View(resource);
}
Here is the View and EditorTemplates
#model learningMVC.Models.Resource[]
#{
ViewData["Title"] = "index";
}
<h1>index</h1>
<fieldset>
#Html.EditorFor(x => x);
</fieldset>
#addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
#model learningMVC.Models.Resource
<div>
First Name:<br />
<form asp-action="Index" asp-controller="Home">
<input asp-for="id" class="form-controller" />
<input asp-for="value" class="form-controller" />
<input asp-for="title" class="form-controller" />
<input type="submit" value="Save" class="btn btn-primary" id="btnSubmit_#Model.id" />
</form>
</div>
In your case, you should use particalview instead of editfor, you can see my demo below.
_ResourcesPartical.cshtml:
#model Resource
<div>
<form method="post" asp-action="Index">
First Name:<br />
<input asp-for="id" class="form-controller" />
<input asp-for="value" class="form-controller" />
<input asp-for="title" class="form-controller" />
<input type="submit" value="save" />
</form>
</div>
Your Index view:
#model List<Resource>
#foreach(var m in Model)
{
#await Html.PartialAsync("_ResourcesPartical", m)
}
Controller:
[HttpGet]
public IActionResult Index()
{
//here you get your data.below is my fake data.
var resources= new List<Resource>
{
new Resource
{
id = 1,
title = "aa",
value = 3
},
new Resource
{
id = 2,
title = "bb",
value = 4
}
};
return View(resources);
}
[HttpPost]
public IActionResult Index(Resource resource)
{
return RedirectToAction("Index");
}
Test result:

How to get autocomplete text box value when post in ASP.NET with DevExtreme

I need to get the value of the text when I post the form in ASP.NET Core app.
In my HTML file I have this DevExtreme control:
<div class="form-group">
<label asp-for="#Model.Account.FullName" class="control-label"></label>
#(Html.DevExtreme().Autocomplete()
.DataSource(d => d.Mvc().Controller("Offer").LoadAction("GetFullNames"))
.ShowClearButton(true)
.Placeholder("Type name")
)
</div>
I'm getting all other values from the form through this line:
<div class="form-group">
<input asp-for="#Model.Account.Email" class="form-control" />
</div>
The Devextreme docs don't give any information how to extract the typed value in this field.
I'm not sure if it can be done with jQuery since my front-end knowledge is limited.
I'm using this Get method to fill the autocomplete box, but my issue is how to get the value when the autocomplete is inside the form and I'm submitting the form.
[HttpGet]
public object Get(DataSourceLoadOptions loadOptions)
{
return DataSourceLoader.Load(_context.Account, loadOptions);
}
Are you going to submit the form and bind the field value to the Account model in the httpost action? If so, you should add the Name attribute to the Autocomplete widget.
Maybe you can refer to the below codes:
Model:
public class TestModel
{
public Account Account { get; set; }
}
public class Account
{
public string FullName { get; set; }
}
View:
#model TestModel
<h2>Home</h2>
<form asp-action="Test">
<div class="form-group">
<label asp-for="#Model.Account.FullName" class="control-label"></label>
#(Html.DevExtreme().Autocomplete()
.DataSource(d => d.Mvc().Controller("Offer").LoadAction("GetFullNames"))
.ShowClearButton(true)
.Placeholder("Type name")
.Name("FullName")
)
<input type="submit" value="submit" class="btn btn-primary" />
</div>
</form>
OfferController:
public class OfferController : Controller
{
[HttpGet]
public object GetFullNames(DataSourceLoadOptions loadOptions)
{
List<string> names = new List<string>
{
"aa", "ab", "bb", "bc", "cc", "cd"
};
return DataSourceLoader.Load(names, loadOptions);
}
}
HomeController:
[HttpPost]
public IActionResult Test(Account account)
{
return Ok(account);
}
Result:

how use two modeles in one method?

the ModelState is Invalid.I Think I pass Model Wrongly.Any Idea?
controller:
[Authorize]
[HttpPost]
public async Task<IActionResult> SendComment([Bind("CommentID,Comment,Date,AdminId")]AdminReport adminReport,int ReportID)
{
var x = _userReport.UserReports.Find(ReportID);
x.IsViewed = true;
adminReport.UserId = x.UserId;
adminReport.AdminId = _userManager.GetUserId(HttpContext.User);
if (ModelState.IsValid){
_adminReport.Add(adminReport);
await _adminReport.SaveChangesAsync();
return View(); }
return RedirectToAction("SendDoneAdmin");
}
its how I pass a Model:
<div class="card-footer">
<form asp-controller="Admin" asp-action="ُSendComment" method="post">
<input type="hidden" value="#report.ReportID" name="ReportID" />
<button type="submit" class="btn btn-primary">SendComment</button>
</form>
Model:
[Key]
public int CommentID { get; set; }
[Required]
public string Comment { get; set; }
public string AdminId { get; set; }
public string UserId { get; set; }
}`
Your quotation no clear but must know for pass data via Form tag
must all input inside Form tag
Controller
public async Task<IActionResult> SendComment()
{
// write your code....
return View(new AdminReport()); // must return new object
}
POST
Normal write again your action SendComment no any change
HTML
for pass AdminReport model must write flied inside form tag
<form asp-controller="Admin" asp-action="Viewed" method="post">
<input type="hidden" value="#report.ReportID" name="ReportID" />
/* for example */
<input type="hidden" asp-for="model.Comment" />
<button type="submit" class="btn btn-primary">SendComment</button>
</form>
No Problem if you have another view but must return View(new AdminReport());
If you want remove validation for comment prop use below code.
// remove all key
foreach (var key in ModelState.Keys).ToList())
ModelState.Remove(key);
// or for one
ModelState.Remove("comment ");
You put this [Requiried] attribute on the Comment:
[Required]
public string Comment { get; set; }
You will have to include that input in your form in order for the validation to pass.
You can add that field like this:
<div class="card-footer">
<form asp-controller="Admin" asp-action="Viewed" method="post">
<input type="hidden" value="#report.ReportID" name="ReportID" />
<input type="text" name="Comment" />
<button type="submit" class="btn btn-primary">SendComment</button>
</form>

Validations with ViewModel - MVC4

I am trying to implement both Create and List actions in a single View. I was being suggested to use ViewModel. I am getting the object reference error. Also some good example on how to achieve this will help.
My Model Class
public class Employee
{
public int ID { get; set; }
[Required(ErrorMessage="Please enter name")]
public string Name { get; set; }
}
My View Model Class
public class EmployeeVM
{
public Employee Employee { get; set; }
public List<Employee> Employees { get; set; }
}
My Controller
[HttpPost]
public ActionResult Create(EmployeeVM emp, string Name)
{
if (ModelState.IsValid) //my modelstate is valid even when the value is empty string; it then gives an Object reference not set error
{
emp.Employee.Name = Name;
repository.SaveRole(emp);
return RedirectToAction("Index");
}
else
{
return View(emp);
}
}
My View
#model ERP.Domain.Entity.EmployeeVM
<body>
<div class="jumbotron">
#using (Html.BeginForm("Create", "MyController", FormMethod.Post))
{
#Html.ValidationSummary(true)
<label>
Name</label>
<input id="txtName" type="text" name="Name" class="btn btn-default" />
#Html.ValidationMessageFor(model => model.Employee.Name)
<input type="submit" value="Save" class="btn btn-primary" />
}
</div>
Also I was suggested in StackOverflow to go with ViewModel approach if I want to use both Create and List in the same View? Is it the right approach. Some example may help.