Form not passing values on POST - asp.net-mvc

Here's my view code:
#model pedidosOnlineMVC.Models.ViewModel.AdmView
#using pedidosOnlineMVC.Models
#{
Layout = "~/Views/Administrador/_LayoutAdm.cshtml";
List<Usuario> lu = pedidosOnlineMVC.Controllers.UsuarioController.favoreds(Model.adm.estabelecimento.Estabelecimento_Id);
}
#using (var f = Html.Bootstrap().Begin(new Form()))
{
using (var p = Html.Bootstrap().Begin(new Panel()))
{
using (var t = Html.Bootstrap().Begin(new Table()))
{
using (var h = t.BeginHeader())
{
using(var hr = h.BeginHeaderRow())
{
#hr.Cell("Usuário")
#hr.Cell("Status")
}
}
using(var b = t.BeginBody())
{
for(int i=0;i<lu.Count;i++)
{
using(var c = b.BeginRow())
{
#f.FormGroup().CustomControls(Html.HiddenFor(model => model.Usuario_Id[i], lu[i].Usuario_Id))
#c.Cell(lu[i].nome)
#c.Cell(f.FormGroup().CustomControls(Html.Bootstrap().CheckBoxFor(model=>model.checkAuts[i])))
}
}
}
}
using (var pf = p.BeginFooter())
{
#f.FormGroup().CustomControls(#Html.HiddenFor(model => model.adm.Administrador_Id, Model.adm.Administrador_Id))
#f.FormGroup().CustomControls(Html.Bootstrap().SubmitButton().Text("Autorizar"))
}
}
}
And I had a similar problem here: cshtml page not passing date value on post, but what I did then doesn't work here.
I tried looking in the network window in the developer tools and I can see the ID values (Administrador_ID and Usuario_ID) being sent on post, but they never reach my controller.
Here's the code for the controller:
[HttpPost]
public ActionResult autCli(AdmView adm)
{
return null;
}
It has no code in it because I still didn't get it to work, but the parameters should still work when debugging, but I get NULL in every attribute instead.
If anyone can help, I'd appreciate it.
AdmView model, as requested:
public class AdmView
{
public Administrador adm { get; set; }
public Produto prod { get; set; }
public virtual List<bool> checkAuts { get; set; }
public virtual List<int> Usuario_Id { get; set; }
}

Try to use the FormCollection to pass data from view to controller.
Just like this:
[HttpPost]
public ActionResult autCli(FormCollection collection)
{
strint Usuario_Id = collection["Usuario_Id"]; //You can get data with this way...
return View();
}
Check this question for more info.

Add [HttpPost] before your ActionResult method.

Related

"TagHelper" does not create elements in created html tag

I am trying to divide listed items into pages by special tags that must be established by custom TagHelper
I have a class to hold data for page and items that will be processed
namespace SportWeb.Models.ViewModels
{
public class PagingInfo
{
public int TotalItems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages { get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); } }
}
}
I am wraping it inside an other modelviewdata
namespace SportWeb.Models.ViewModels
{
public class ProductListViewModel
{
public IEnumerable<Product> Products { get; set; }
public PagingInfo PagingInfos { get; set; }
}
}
Then insert it into Controller Class to retrieve data and establishing logic
public class ProductController : Controller
{
private IProductRepository _iProductRepository;
int PageSize = 4;
public ProductController(IProductRepository iProductRepository)
{
_iProductRepository = iProductRepository;
}
public IActionResult List(int itemPage = 1) => View(new ProductListViewModel
{ Products = _iProductRepository
.List.OrderBy(p => p.ProductID)
.Skip((itemPage - 1) * PageSize)
.Take(PageSize),
PagingInfos = new PagingInfo {
CurrentPage = itemPage,
ItemsPerPage = PageSize,
TotalItems= _iProductRepository.List.Count()} });
}
}
And creating my TagHelper class
namespace SportWeb.InfraSturcture
{
[HtmlTargetElement("div", Attributes = "page-model")]
public class PageLinkTagHelper :TagHelper
{
private IUrlHelperFactory _iUrlHelperFactory;
public PageLinkTagHelper(IUrlHelperFactory iUrlHelperFactory)
{
_iUrlHelperFactory = iUrlHelperFactory;
}
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
public PagingInfo PageModel { get; set; }
public string PageAction { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
IUrlHelper urlHelper = _iUrlHelperFactory.GetUrlHelper(ViewContext);
TagBuilder result = new TagBuilder("div");
for (int i=1; i<PageModel.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a");
tag.Attributes["href"] = urlHelper.Action(PageAction, new { itempPage = i });
tag.InnerHtml.Append(i.ToString());
result.InnerHtml.AppendHtml(tag);
}
output.Content.AppendHtml(result.InnerHtml);
}
}
}
and here is View page codes
ViewData["Title"] = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#model ProductListViewModel
#addTagHelper SportWeb.InfraStructure.*,SportStore
<h1>List</h1>
#foreach (var p in Model.Products)
{
<div>
<h3>#p.Name</h3>
#p.Description
<h4>#p.Price.ToString("c")</h4>
</div>
}
<div page-model="#Model.PagingInfos" page-action="List"></div>
ViewImport codes below
#using SportWeb.Models
#using SportWeb.Models.ViewModels
#using SportWeb.Entity
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#addTagHelper SportWeb.InfraStructure.*, SportWeb
But when program runs, navigation panel is not appearing on the page
Here navigation panel is not appearing
And When I open page source it seems Tag helper does not work , created tags are not added by the codes.
source page
I do not understand why my tag helper does not work at all. Do you have any idea about where I am making mistake ?
Edit : I am working with CORE 3.0 features. Can it be caused that problem ?
I tried to reproduce your scenario and it worked. I tried with NET Core 2.2 and Visual Studio 2017 15.9.11 and with .NET Core 3.0 Preview 5 with Visual Studio 2019 16.0.3.
Most likely the problem lies on your side. Try to troubleshoot. Start with checking if the tag helper is executed at all. Place a breakpoint in Process() method in your PageLinkTagHelper. See if it is being hit while running the application.
Double check if you are adding the tag helper properly. Properly added tag helper will have Visual Studio IntelliSense, like this:
#addTagHelper *, SportWeb this is answer of problem write it in ViewImport

System.NullReferenceException when trying to iterate list in view

Im a bit new at mvc, and i dont find out what am i miss. When i launch the login, in the view at foreach (var item in Model) <- the Model gets null, and stops with a System.NullReferenceException. A dont really have a clue why, and i hope somebody can give some advice what's wrong with the following code or where to start looking for the error.
The model:
public class LoginModels
{
public string UserLogin { get; set; }
public string Address { get; set; }
public string Password { get; set; }
public List<string> emailSubject { get; set; }
}
The controller:
public ActionResult Login(string address, string password, LoginModels model)
{
using (Imap imap = new Imap())
{
try
{
imap.ConnectSSL("imap.gmail.com");
imap.Login(address, password);
imap.SelectInbox();
List<long> uids = imap.Search(Flag.All);
model.emailSubject = new List<string>();
foreach (long uid in uids)
{
var eml = imap.GetMessageByUID(uid);
IMail email = new MailBuilder().CreateFromEml(eml);
model.emailSubject.Add(email.Subject);
}
Session["user"] = new LoginModels() { UserLogin = address, Address = address };
return RedirectToAction("Index", "Home", model.emailSubject);
}
catch (Exception e)
{
ViewBag.exceptionMessage = e;
return View("LoginFailed");
}
}
The view:
#using TheOnlineArchivator.Models;
#model List<TheOnlineArchivator.Models.LoginModels>
#{
ViewBag.Title = "Home";
}
#{
var user = Session["user"] as LoginModels;
if (user != null)
{
<h2>You are logged on as #user.Address</h2>
<table>
#foreach (var item in Model)
{
foreach (var elem in item.emailSubject)
{
<tr>
<td>#elem</td>
</tr>
}
}
</table>
}
}
It looks like you forgot to pass an instance of List<TheOnlineArchivator.Models.LoginModels> to the view when you rendered this view inside your controller action. What you have shown so far is your Login controller action but you didn't show us your Home/Index action. Inside this action you should make sure that you are passing a non-null model to the view:
public class HomeController : Controller
{
public ActionResult Index()
{
List<LoginModels> model = ... go get your model from somewhere and make sure it is not null
return View(model);
}
}

How to clear text from a search textbox after search is complete in MVC

I have two dropdown lists and two textboxes
Search By: ByHtml.DropDownList("Search1", "Please Select...")
Html.TextBox("searchString1")
Search By: Html.DropDownList("Search2", "Please Select...")
#Html.TextBox("searchString2")
<input type="submit" value="Filter" />
When I make my selection from whichever DDL and type text into the textbox and hit filter my search returns, however after the search the text remains in the textbox, is there a way of clearing it after the search so that the textbox is empty again? I tried
ModelState.Remove("");
but it didn't work.
A sample from My controller code is
public class MainController : Controller
{
private DBEntities db = new DBEntities();
// GET: /Main/
public ActionResult Index(string searchString1, string searchString2, string Search1, string Search2)
{
//Create a Dropdown list
var SearchOptionList = new List<string>();
SearchOptionList.Add("LandLord");
SearchOptionList.Add("Postcode");
SearchOptionList.Add("Street Address");
ViewBag.Search1 = new SelectList(SearchOptionList);
ViewBag.Search2 = new SelectList(SearchOptionList);
var mylist = from m in "mydatabase" select m;
//This statement runs if the user selects a parameter from Search2 and leaves Search1 empty
if (String.IsNullOrEmpty(Search1) && !String.IsNullOrEmpty(Search2))
{
if (Search2 == "Postcode")
{
mylist = mylist.Where(s => s.Postcode.Contains(searchString2));
}
if (Search2 == "LandLord")
{
mylist = mylist.Where(s => s.Name.Contains(searchString2));
}
if (Search2 == "Street Address")
{
mylist = mylist.Where(s => s.StreetAddress.Contains(searchString2));
}
}
return View(mylist.ToList());
}
Your should have a view model containing properties searchString1 and searchString2 and the select lists
public class SearchVM
{
public string searchString1 { get; set; }
public string searchString2 { get; set; }
public SelectList SearchList1 { get; set; }
public SelectList SearchList2 { get; set; }
}
Controller
public ActionResult Search()
{
SearchVM model = new SearchVM();
model.SearchList1 = new SelctList(...);
model.SearchList2 = new SelctList(...);
return View(model);
}
View
#model SearchVM
#using(Html.BeginForm())
{
....
#Html.DropDownListFor(m => m.searchString1, Model.SearchList1, "--Please select--")
#Html.DropDownListFor(m => m.searchString2, Model.SearchList2, "--Please select--")
....
}
Post
[HttpPost]
public ActionResult Search(SearchVM model)
{
// to clear all modelstate and reset values
ModelState.Clear();
model.searchString1 = null;
model.searchString2 = null;
// or to clear just one property and reset it
ModelState.Remove("searchString1");
model.searchString1 = null;
// repopulate select lists if your returning the view
return View(model);
}
At the end of my public ActionResult Index method but before return View() I placed the following code which worked perfectly
ModelState.Remove("searchString1");
ModelState.Remove("searchString2");
ModelState.Remove("Search1");
ModelState.Remove("Search2");
I know is an old question, but I fall in the same issue. So I put my solution.
View:
#Html.TextBox("Search", null, new { #autofocus = "autofocus" })
Controller:
ViewBag.Search= null;
ModelState.Remove("Search");
return View(list.ToList());
Hope to help someone

ASP MVC Button Click

I would like to click on button and use Next method in Controller, but i dont want go to another view! I want stay here in VIEW and my property should be change. This idea doesnt work :(( How can i do it??
Its my controller
public class VisitsController : Controller
{
Terminarz terminarz = new Terminarz();
Daty data = new Daty();
public VisitsController()
{
terminarz.aktualnaData = DateTime.Now.Date;
terminarz.pierwszyDzienTyg = data.pierwszyDzienTygodnia(terminarz.aktualnaData);
terminarz.ostatniDzienTyg = data.ostatniDzienTygodnia(terminarz.aktualnaData);
}
[ActionName("index")]
public ActionResult Index()
{
ViewBag.data = terminarz.aktualnaData;
ViewBag.pierwszyDzien = terminarz.pierwszyDzienTyg.ToString("dd/MM/yyyy ");
ViewBag.ostatniDzien = terminarz.ostatniDzienTyg.ToString("dd/MM/yyyy ");
ViewBag.wtf = terminarz.pierwszyDzienTyg.AddDays(7).ToString("dd/MM/yyyy ");
return View();
}
[NonAction]
public ActionResult Next()
{
terminarz.pierwszyDzienTyg = terminarz.pierwszyDzienTyg.AddDays(7);
terminarz.ostatniDzienTyg = terminarz.ostatniDzienTyg.AddDays(-7);
return View("index");
}
}
my model
public partial class Terminarz
{
public DateTime aktualnaData { get; set; }
public DateTime pierwszyDzienTyg { get; set; }
public DateTime ostatniDzienTyg { get; set; }
public string nazwa { get; set; }
}
my view
#ViewBag.pierwszyDzien<br />
#ViewBag.ostatniDzien<br />
#ViewBag.wtf
#using (Html.BeginForm(FormMethod.Post))
{
#Html.ActionLink("dalej","Next", "Visits")
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
By default, all public methods in a controller can be called from an HTTP request. NonAction prevents the public method from being called from your form post. Remove the NonAction attribute from the Next method, and it should execute as expected.
You may also have to update your return to match a relative path something like this:
return View("~/Views/Index.cshtml");
Your form is also not being submitted. You are using a link inside of the form. Try this:
#using (Html.BeginForm("Next", "VisitsController", FormMethod.Post))
{
<button type="submit">Next</button>
}

Model property is empty

I am trying to move from webForms to Asp.net-MVC and have some problems. I am trying to figure why this is not working, I am getting this error: "Object reference not set to an instance of an object"
I have the class 'Pages':
namespace _2send.Model
{
public class Pages
{
public string PageContent { get; set; }
public string PageName { get; set; }
public int LanguageId { get; set; }
}
}
I am inserting the value to 'Pages.PageContent' property with this class:
namespace _2send.Model.Services
{
public class PagesService : IPagesService
{
public void GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
SqlDataReader dr;
Pages pages = new Pages();
using (dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
dr.Close();
}
}
}
The Controller method looks like this:
private IPagesService _pagesService;
public FooterLinksPageController(IPagesService pagesService)
{
_pagesService = pagesService;
}
public ActionResult GetFooterLinksPage()
{
_pagesService.GetFooterlinksPage();
return View();
}
I am trying to write the property in the view like this:
#model _2send.Model.Pages
<div>
#Model.PageContent;
</div>
When debugging, the method is fired and the dataReader is inserting the value to the 'PageContent' property, but I am still getting this error from the view.
Thanks!
return View();
You didn't pass a model.
You need to pass the model as a parameter to the View() method.
You need to rewrite service method to return Pages:
public Pages GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
Pages pages = new Pages();
using (var dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
return pages;
// Because you use using, you don't need to close datareader
}
}
}
And then rewrite your action method:
public ActionResult GetFooterLinksPage()
{
var viewmodel = _pagesService.GetFooterlinksPage();
return View(viewmodel);
}
You can return a model:
var viewmodel = new _2send.Model.Pages().
//here you configure your properties
return View(viewmodel);

Resources