Post from MVC view don't get bind to controller model - asp.net-mvc

I have a partial view which is displayed on modal window:
public ActionResult Details(string test)
{
var model = _taskService.GetDocumentTasks(test);
return PartialView("_Details", new CustomViewModel { TaskList = model.ToList() });
}
public class CustomViewModel
{
public DocumentStatus Status { get; set; }
public IList<DocumentTask> TaskList { get; set; }
}
I am able to loop TaskList in the view and draw form fields like this:
#model CustomViewModel
#using (Html.BeginForm())
{
#for (int i = 0; i < Model.TaskList.Count(); i++)
{
#Html.HiddenFor(m => m.TaskList[i].TaskId)
<div class="col-sm-6 col-md-4">
<img src="#Html.EditorFor(m => m.TaskList[i].DocumentPath)">
.. other form items here
</div>
}
<input class="btn btn-primary" type="submit" value="Save" />
}
This displays the form fields but when I click the submit button the modal which is sent to the controller is null. I have tried a few different ways of binding it but no success. The model on on the below controller is always null. Any idea how to bind the submitted form details to controller model?
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Details(CustomViewModel model)
{
}
Thanks.

This will work. I made some minor changes, so please follow this:
Controller/Model:
public class HomeController : Controller
{
public class TaskService
{
public Collection<DocumentTask> GetDocumentTasks(string test)
{
Collection<DocumentTask> aCollection = new Collection<DocumentTask>();
var documentTaska = new DocumentTask { TaskId = "patha", DocumentPath = "~/Images/w.JPG" };
var documentTaskb = new DocumentTask { TaskId = "pathb", DocumentPath = "~/Images/w.JPG" };
var documentTaskc = new DocumentTask { TaskId = "pathc", DocumentPath = "~/Images/w.JPG" };
var documentTaskd = new DocumentTask { TaskId = "pathd", DocumentPath = "~/Images/w.JPG" };
aCollection.Add(documentTaska);
aCollection.Add(documentTaskb);
aCollection.Add(documentTaskc);
aCollection.Add(documentTaskd);
return aCollection;
}
}
public class DocumentStatus { }
public class DocumentTask
{
public string TaskId { get; set; }
public string DocumentPath { get; set; }
public string UserDataToProveItWorking { get; set; }
}
public class CustomViewModel
{
public DocumentStatus Status { get; set; }
public IList<DocumentTask> TaskList { get; set; }
}
TaskService _taskService = new TaskService();
public ActionResult Overview()
{
return View();
}
public ActionResult Details(string test)
{
var model = _taskService.GetDocumentTasks(test);
return PartialView("_Details", new CustomViewModel { TaskList = model.ToList() });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Details(CustomViewModel model)
{
return View("Overview");
}
View Overview.cshtml:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Overview</title>
</head>
<body>
<div>
#Html.ActionLink("GetPartialView", "Details", new { test = "aTestValue"})
</div>
</body>
</html>
Partial View _Detials.cshtml
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Overview</title>
</head>
<body>
<div>
#Html.ActionLink("GetPartialView", "Details", new { test = "aTestValue"})
</div>
</body>
</html>

Related

Model returning null from a View with multiple models

I have two models, LoginModel and DatabaseModel. Combining them, I have created DatabaseCombinedWithOtherModel. The View, Login.cshtml is Strongly-Typed with the combined model. On running the Login.cshtml, the LoginModel returns null
I have all the necessary get and set methods
Here is the Controller class
namespace ReadingCat.Controllers
{
public class LoginController : Controller
{
private int userid;
// GET: Login
[HttpGet]
public ActionResult Login()
{
return View(new DatabaseCombinedWithOtherModel());
}
[HttpPost]
public ActionResult Login(DatabaseCombinedWithOtherModel model)
{
string realPassword = "";
string paswordFromUser = "";
string query = "SELECT password, userid FROM USERS WHERE username
= '" + model.loginModel.username + "'";
DataSet dataSet = model.databaseModel.selectFunction(query);
if (realPassword == paswordFromUser)
{
userid =
Convert.ToInt32(dataSet.Tables[0].Rows[0].ItemArray[1]);
model.loginModel.userid = userid;
return View("~/Views/Profile/Profile.cshtml",
model.loginModel);
}
else
return View();
}
}
}
Here is the Model:
namespace ReadingCat.Models
{
public class DatabaseCombinedWithOtherModel
{
public DatabaseModel databaseModel { get; set; }
public LoginModel loginModel { get; set; }
}
}
And here is the View:
#model ReadingCat.Models.DatabaseCombinedWithOtherModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
<!-- Main css -->
<link rel="stylesheet" href="~/css/login.css">
</head>
<body>
<div class="login-page">
<div class="form">
<form class="register-form">
</form>
#using (Html.BeginForm("Login", "Login", FormMethod.Post))
{
<form class="login-form">
#Html.TextBox("Username", null, new { placeholder = "Username",
#class = "login.css" })
#Html.ValidationMessageFor(model => model.loginModel.username);
#Html.Password("Password", null, new { placeholder = "Password",
#class = "login.css" })
#Html.ValidationMessageFor(model => model.loginModel.password);
<div class="form-submit">
<button type="submit" value="Submit" class="submit"
id="submit" name="submit">Login</button>
</div>
<p class="message">Not registered? Create an account</p>
</form>
}
</div>
</div>
<img class="coffee-image" src="~/images/coffee.gif" alt="">
It is giving the following error
System.NullReferenceException: 'Object reference not set to an instance
of
an object.'
ReadingCat.Models.DatabaseCombinedWithOtherModel.loginModel.get returned
null.
I think this error about not fully declare DatabaseCombinedWithOtherModelthis model.
Please try this code.
private int userid
DatabaseCombinedWithOtherModel modelobj = new DatabaseCombinedWithOtherModel();
// GET: Login
[HttpGet]
public ActionResult Login()
{
return View(modelobj);
}
And also try this thing that before call the model in view firstly add some
values in objects from controller side pass return View(modelobj);and then call in view side.
Since you are not seting the loginmodel, it will be null Which will throw the exception.
Either initialize the loginModel in the otherModel's constructor or in the Login get action.
Try
namespace ReadingCat.Models
{
public class DatabaseCombinedWithOtherModel
{
public DatabaseModel databaseModel { get; set; }
public LoginModel loginModel { get; set; }
}
public DatabaseCombinedWithOtherModel()
{
loginModel = new LoginModel();
databaseModel = new DatabaseModel();
}
}
or
[HttpGet]
public ActionResult Login()
{
var vm = new DatabaseCombinedWithOtherModel()
vm.loginModel = new LoginModel();
vm.databaseModel = new DatabaseModel();
return View(vm);
}
The mentioned error goes away if #Html.Textbox is replaced with #Html.EditorFor. Then, another error arises with the DatabaseModel. It returns null. So I created a different object of DatabaseModel and worked with that.

How to use RadioButton to render View

I have a controller as shown below.
public ActionResult Index()
{
return View(db.FEE_TYPES.ToList());
}
By default it will render a View called Index. However, I have three views I want to Render
Index
Index2
Index3
I want to have three RadioButtons on the View
RadioButton1
RadioButton2
RadioButton3
When RadioButton1 is clicked, Render Index.
When RadioButton2 is clicked, Render Index2
When RadioButton3 is clicked, Render Index3
Please how do I achieve this?
I have Created a Demo from your Code Reference.
First i have create a Model with 3 properties in it.
Model
public class DemoModel
{
public string Radio1 { get; set; }
public string Radio2 { get; set; }
public string Radio3 { get; set; }
}
After creating a Model i have created a Controller with name RadioRenderController in that controller i have added 4 Action Method in that Index returns Main View.
And Remaining 3 Action Methods [ GetView1 , GetView2 , GetView3 ] return partial View.
Controller
using System.Web.Mvc;
using WebApplication6.Models;
namespace WebApplication6.Controllers
{
public class RadioRenderController : Controller
{
// GET: RadioRender
public ActionResult Index()
{
DemoModel DemoModel = new Models.DemoModel();
return View(DemoModel);
}
public ActionResult GetView1()
{
return PartialView("_DemoView1");
}
public ActionResult GetView2()
{
return PartialView("_DemoView2");
}
public ActionResult GetView3()
{
return PartialView("_DemoView3");
}
}
}
View
#model WebApplication6.Models.DemoModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
function GetView1() {
$("#viewPlaceHolder").load("/RadioRender/GetView1");
}
function GetView2() {
$("#viewPlaceHolder").load("/RadioRender/GetView2");
}
function GetView3() {
$("#viewPlaceHolder").load("/RadioRender/GetView3");
}
</script>
</head>
<body>
<div>
#Html.RadioButtonFor(m => m.Radio1, "1", new { #onclick = "GetView1();" }) Radio1
</div>
<div>
#Html.RadioButtonFor(m => m.Radio1, "2", new { #onclick = "GetView2();" }) Radio2
</div>
<div>
#Html.RadioButtonFor(m => m.Radio1, "3", new { #onclick = "GetView3();" }) Radio3
</div>
<div id="viewPlaceHolder"></div>
</body>
</html>
Partial Views
Output

Pass value in asp.net mvc

I am trying to pass data of method to another method. Can you help me please?
Here is my code: return View(model); model should be pass public ActionResult ShowData(Student model) method.
public ActionResult ShowData(int? ID)
{
var model = new StudentModel
{
StudentData = stdDef
};
return View(model);
}
[HttpPost]
public ActionResult ShowData(Student model) {
This is how it is done. Please pay attention to my comments in the code:
Controller/Model:
public class StudentModel
{
public string StudentData { get; set; }
}
public class HomeController : Controller
{
public string PassDataToMe(StudentModel model)
{
return model.StudentData;//no view defined
}
public ActionResult ShowData(int? ID)
{
var stdDef = "stdDef";
var model = new StudentModel
{
StudentData = stdDef
};
return View(model);
}
[HttpPost]
//!changed this to studentmodel
public ActionResult ShowData(StudentModel model)
{
//this is how you pass limited bytes of data that are not encrypted
return RedirectToAction("PassDataToMe", model);
}
View:
#model Testy20161006.Controllers.StudentModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ShowData</title>
</head>
<body>
<div>
#using (Html.BeginForm())
{
#Html.LabelFor(r => r.StudentData);
#Html.TextBoxFor(r=>r.StudentData);
<input type="submit" value="submit" />
}
</div>
</body>
</html>

how to use #Html.DropDownListFor with custom datatype

I have following model & simple drop down in the view. I want to populate the customer name in the drop down. I tried following code but it did not work, can anybody what is wrong with this code.
Model
public class customer
{
public int id { get; set; }
public string name { get; set; }
public string address { get; set; }
}
//////////////////////////
#{
Layout = null;
}
#model IEnumerable<MvcApplication1.customer>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
#Html.DropDownListFor(m=>m.name, new SelectList(Model,"id","name"));
</div>
In your attempt of doing this, you have made some basic mistakes. First try to understand what's going behind the scene in MVC and what those keywords mean.
you have defined
#model IEnumerable<MvcApplication1.customer>
then you have the following code
#Html.DropDownListFor(m=>m.name, new SelectList(Model,"id","name"));
here, your m denotes the #model which you have initialised as an IEnumerable<MvcApplication1.customer>. You are trying to access a property called name in IEnumerable (m => m.name) and IEnumerable doesn't have such property. if you want to access your model like that for some reason, your #model should be a Customer object. Then you can access it like #Html.DropDownListFor(m=>m.name, new SelectList(Model,"id","name"));
in a comment, you've said that this code #Html.DropDownList("name", new SelectList(Model, "id", "name")); works fine. Yes, it works because you are creating a new html select element with the Id "name" and it list anything that is in the Model as select options.
Okay, enough explanation.
This is the solution that I suggest for your problem.
In you controller action, implement the code flow as follows.
var dropdownDataList = //select your data from the database or any place as a list;
var dropdownOptions = dropdownDataList.Select(d => new {
id = d.valueforid,
name = d.valueforname
});
ViewBag.DropdownListOptions = new SelectList(dropdownOptions, "id", "name");
return View();
now in your view, do the following.
#{
Layout = null;
}
#model MvcApplication1.customer
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
#Html.DropDownListFor(m=>m.name, (SelectList)ViewBag.DropdownListOptions)
</div>
</body>
</html>
try to go through these articles in MSDN.
http://msdn.microsoft.com/en-us/library/gg416514(v=vs.108).aspx
hope this helps.
Cheers,
Amila
There are many samples on this exact question on Stack Overflow. I have answered it many times before.
Use a view model to represent your data on the view, do not pass your domain object to the view. A view model has on the properties that you need on the view, in this case I am only going to work with a drop down of your customers.
Your view model could look like this:
public class CustomerViewModel
{
public int CustomerId { get; set; }
public IEnumerable<Customer> Customers { get; set; }
}
Your customer class:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
Your controller:
public class CustomerController : Controller
{
private readonly ICustomerRepository customerRepository;
public Customer(ICustomerRepository customerRepository)
{
this.customerRepository = customerRepository;
}
public ActionResult Create()
{
CustomerViewModel viewModel = new CustomerViewModel
{
Customers = customerRepository.GetAll()
};
return View(viewModel);
}
}
Your view:
#model YourProject.ViewModels.Customers.CustomerViewModel
#Html.DropDownListFor(
x => x.CustomerId,
new SelectList(Model.Customers, "Id", "Name", Model.CustomerId),
"-- Select --"
)
#Html.ValidationMessageFor(x => x.CustomerId)
I hope this helps.
try this
change your model to something like this
public class customer
{
public int id { get; set; }
public string SelectedName { get; set; }
public IEnumerable<SelectListItem> Names { get; set; }
public string address { get; set; }
}
In controller
[HttpGet]
public ActionResult Customer()
{
var names=//collect names from database
var model = new Customer
{
Names = names.Select(m=> new SelectListItem
{
value = m.whatever value you want to get(probably Id)
text = m.name you want to display
})
};
return View(model);
}
and in view
#model MvcApplication1.customer
#Html.DropDownListFor(model => model.SelectedName, Model.Names)

MVC display foreign key from another table

Controller:
public ActionResult Details(int id)
{
ViewBag.AccountType = new BusinessLayer.AccountTypeManager().GetAccountTypes();
return View(new BusinessLayer.AccountManager().getAccount(id));
}
View:
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.AccountType)</div><br />
This current view displays the AccountType ID. How can I display the AccountType Name which is being passed by the ViewBag.AccountType (IEnumerable)
something like following
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.AccountType)</div>
#{
var TypeNames = ViewBag.AccountType as IEnumerable<string>;
foreach(var item in TypeNames)
{
<div>item</div>
}
}
Mode elegant way
public class AccountTypeVewModel
{
public IEnumerable<string> typeNames { get; set; }
public Account account { get; set; }
}
controller
public ActionResult Details(int id)
{
AccountTypeVewModel model = new AccountTypeVewModel();
model.typeNames = new BusinessLayer.AccountTypeManager().GetAccountTypes();
model.account = new BusinessLayer.AccountManager().getAccount(id);
return View(model);
}
view
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.account.AccountType)</div>
#{
foreach(var item in Model.typeNames)
{
<div>item</div>
}
}

Resources