View returns null value when using two models in MVC - asp.net-mvc

I have a simple MVC program where earlier I was using one model and the code was working fine. here is the code.
View
#model Microsoft.Azure.ActiveDirectory.GraphClient.User
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create User</title>
</head>
<body>
<h2>Create User</h2><br />
#using (Html.BeginForm("Create",
"CreateUsers",
new { id = Model != null ? Model.ObjectId : "" },
FormMethod.Post,
new { enctype = "multipart/form-data" })
)
{
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserPrincipalName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserPrincipalName)
#Html.ValidationMessageFor(model => model.UserPrincipalName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AccountEnabled)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AccountEnabled)
#Html.ValidationMessageFor(model => model.AccountEnabled)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PasswordProfile.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PasswordProfile.Password)
#Html.ValidationMessageFor(model => model.PasswordProfile.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MailNickname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MailNickname)
#Html.ValidationMessageFor(model => model.MailNickname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DisplayName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DisplayName)
#Html.ValidationMessageFor(model => model.DisplayName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.GivenName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.GivenName)
#Html.ValidationMessageFor(model => model.GivenName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Surname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Surname)
#Html.ValidationMessageFor(model => model.Surname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.JobTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.JobTitle)
#Html.ValidationMessageFor(model => model.JobTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Department)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Department)
#Html.ValidationMessageFor(model => model.Department)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</body>
</html>
#if (ViewBag.ErrorMessage == "AuthorizationRequired")
{
<p>You have to sign-in. Click #Html.ActionLink("here", "Create", "Users", new { reauth = true }, null) to sign-in.</p>
}
Controller
public async Task<ActionResult> Create(string blobDetails)
{
#region POPULATE USER DETAIL IN CREATEUSER FIELDS
List<string> userDetails = blobDetails.Split(',').ToList();
User user = new User();
user.UserPrincipalName = userDetails[2] + "#xxx.com";
user.GivenName = userDetails[0];
user.Surname = userDetails[1];
user.DisplayName = userDetails[0] + " " + userDetails[1];
return View(Tuple.Create(user);
#endregion
}
[HttpPost]
public async Task<ActionResult> Create([Bind(Include ="UserPrincipalName,AccountEnabled,PasswordProfile,MailNickname,DisplayName,GivenName,Surname,JobTitle,Department")] User user)
{
ActiveDirectoryClient client = null;
client = AuthenticationHelper.GetActiveDirectoryClient();
string name = user.GivenName;
string username = user.UserPrincipalName;
return RedirectToAction("Index");
}
And this works perfectly fine , I get the values of user.GivenName and user.UserPrincipalName from view and I store it into string. Now what I am doing is that I am including one more model into this and trying to get its value from view so I did something like this:
Model
public class CreateUsers
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string PIDetails { get; set; }
public string BlobDetails { get; set; }
public string UserEmail { get; set; }
}
View
#using WebAppGraphAPI.Models
#model Tuple<Microsoft.Azure.ActiveDirectory.GraphClient.User, CreateUsers>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create User</title>
</head>
<body>
<h2>Create User</h2><br />
#using (Html.BeginForm("Create",
"CreateUsers",
new { id = Model != null ? Model.Item1.ObjectId : ""
},
FormMethod.Post,
new { enctype = "multipart/form-data" })
)
{
#Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.UserPrincipalName)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.UserPrincipalName)
#Html.ValidationMessageFor(tuple => tuple.Item1.UserPrincipalName)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.AccountEnabled)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.AccountEnabled)
#Html.ValidationMessageFor(tuple => tuple.Item1.AccountEnabled)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.PasswordProfile.Password)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.PasswordProfile.Password)
#Html.ValidationMessageFor(tuple => tuple.Item1.PasswordProfile.Password)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.MailNickname)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.MailNickname)
#Html.ValidationMessageFor(tuple => tuple.Item1.MailNickname)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.DisplayName)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.DisplayName)
#Html.ValidationMessageFor(tuple => tuple.Item1.DisplayName)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.GivenName)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.GivenName)
#Html.ValidationMessageFor(tuple => tuple.Item1.GivenName)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.Surname)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.Surname)
#Html.ValidationMessageFor(tuple => tuple.Item1.Surname)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.JobTitle)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.JobTitle)
#Html.ValidationMessageFor(tuple => tuple.Item1.JobTitle)
</div>
<div class="editor-label">
#Html.LabelFor(tuple => tuple.Item1.Department)
</div>
<div class="editor-field">
#Html.EditorFor(tuple => tuple.Item1.Department)
#Html.ValidationMessageFor(tuple => tuple.Item1.Department)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<div class="editor-label">
#*#Html.LabelFor(tuple => tuple.Item2.UserEmail)*#
#Html.EditorFor(tuple => tuple.Item2.UserEmail)
</div>
</body>
</html>
#if (ViewBag.ErrorMessage == "AuthorizationRequired")
{
<p>You have to sign-in. Click #Html.ActionLink("here", "Create", "Users", new { reauth = true }, null) to sign-in.</p>
}
Controller
public async Task<ActionResult> Create(string blobDetails)
{
#region POPULATE USER DETAIL IN CREATEUSER FIELDS
List<string> userDetails = blobDetails.Split(',').ToList();
User user = new User();
user.UserPrincipalName = userDetails[2] + "#gwuadmeaoutlook.onmicrosoft.com";
user.GivenName = userDetails[0];
user.Surname = userDetails[1];
user.DisplayName = userDetails[0] + " " + userDetails[1];
CreateUsers userInfo = new CreateUsers();
userInfo.UserEmail = userDetails[4];
return View(Tuple.Create(user,userInfo));
}
[HttpPost]
public async Task<ActionResult> Create([Bind(Include ="UserPrincipalName,AccountEnabled,PasswordProfile,MailNickname,DisplayName,GivenName,Surname,JobTitle,Department")] User user,[Bind(Include ="UserEmail")] CreateUsers userInfo)
{
ActiveDirectoryClient client = null;
client = AuthenticationHelper.GetActiveDirectoryClient();
string name = user.GivenName;
string username = user.UserPrincipalName;
string Email = userInfo.UserEmail
return RedirectToAction("Index");
}
When I do this I do not get values from View in my controller strings , it shows null. Can you suggest me how can I achieve this.

You could use an object which contains all of the properties you're trying to send to the client. We generally create DTOs for this specific usage. In you're case you'd have:
CreateDto
public class CreateDto
{
public Microsoft.Azure.ActiveDirectory.GraphClient.User User { get; set; }
public CreateUsers UserInfo { get; set; }
}
Then you're controller will be updated as:
public async Task<ActionResult> Create(string blobDetails)
{
#region POPULATE USER DETAIL IN CREATEUSER FIELDS
List<string> userDetails = blobDetails.Split(',').ToList();
User user = new User();
user.UserPrincipalName = userDetails[2] + "#gwuadmeaoutlook.onmicrosoft.com";
user.GivenName = userDetails[0];
user.Surname = userDetails[1];
user.DisplayName = userDetails[0] + " " + userDetails[1];
CreateUsers userInfo = new CreateUsers();
userInfo.UserEmail = userDetails[4];
var dto = new CreateDto() {
User = user,
UserInfo = userInfo
}
return View(dto);
}
[HttpPost]
public async Task<ActionResult> Create([Bind(Include ="UserPrincipalName,AccountEnabled,PasswordProfile,MailNickname,DisplayName,GivenName,Surname,JobTitle,Department")] User user,[Bind(Include ="UserEmail")] CreateUsers userInfo)
{
ActiveDirectoryClient client = null;
client = AuthenticationHelper.GetActiveDirectoryClient();
string name = user.GivenName;
string username = user.UserPrincipalName;
string Email = userInfo.UserEmail
return RedirectToAction("Index");
}
And your view will have:
#using WebAppGraphAPI.Models
#model CreateDto
Later you can reference the information with Model.user and Model.userInfo.
I know this doesn't explain why the Tuple doesn't work. I believe that is best explain by #darin-dimitrov in ado.net mvc3 tuple using in model and single views

Related

Modify property in a list with razor

Say I want to modify a Movie in a view.
We can do it by the code.
#model MvcMovie.Models.Movie
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ReleaseDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ReleaseDate)
#Html.ValidationMessageFor(model => model.ReleaseDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Genre)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Genre)
#Html.ValidationMessageFor(model => model.Genre)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
However it is for one movie. But I have many movies say 5. The movie model is a list. How can I loop through it?
Your controller/view model":
public class MovieViewModel
{
public int ID { get; set; }
public string Title { get; set; }
}
public class HomeController : Controller
{
[HttpPost]
public ActionResult IndexValid3(IList<MovieViewModel> movieViewModel)
{
//set breakpoint here and update db here
return View(movieViewModel);
}
public ActionResult IndexValid3()
{
IList<MovieViewModel> list = new List<MovieViewModel>();
var movieViewModel = new MovieViewModel { ID = 1, Title = "title1"};
var movieViewModel2 = new MovieViewModel { ID = 1, Title = "title2"};
list.Add(movieViewModel);
list.Add(movieViewModel2);
return View(list);
}
View:
#model IList<Testy20161006.Controllers.MovieViewModel>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexValid3</title>
</head>
<body>
<div>
#using (Html.BeginForm())
{
<table>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>#Html.TextBoxFor(m => Model[i].ID)</td>
<td>#Html.TextBoxFor(m => Model[i].Title)</td>
</tr>
}
</table>
<input type="submit" value="submit" />
}
</div>
</body>

Uploading Image in Asp.net mvc Controller

I have a Upload form and I want to pass my information such as an Image and some other field but I don't know how can I upload Image ..
This is My model class
public partial class NewProductCategory
{
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public string ProductPrice { get; set; }
public string ProductImage { get; set; }
public string ProductQuantity { get; set; }
public Nullable<bool> ProductStatus { get; set; }
public Nullable<int> CategoryId { get; set; }
public HttpPostedFileBase user_image_data { get; set; }
public virtual Category Category { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(NewProductCategory productcategory, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
ProductCategory newproductCategory = new ProductCategory();
string path = Path.Combine(Server.MapPath("~/Content/files"), Path.GetFileName(file.FileName));
file.SaveAs(path);
newproductCategory.ProductDescription = productcategory.ProductDescription;
newproductCategory.ProductQuantity = productcategory.ProductQuantity;
newproductCategory.ProductStatus = productcategory.ProductStatus;
newproductCategory.CategoryId = productcategory.CategoryId;
db.ProductCategories.Add(newproductCategory);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CategoryId = new SelectList(db.Categories, "CategoryId", "Name", productcategory.CategoryId);
return View(productcategory);
}
And this is My View Code
#model MvcApplication1.Models.NewProductCategory
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>ProductCategory</legend>
#using (Html.BeginForm("Create", "Temp", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.ProductName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductName)
#Html.ValidationMessageFor(model => model.ProductName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductDescription)
#Html.ValidationMessageFor(model => model.ProductDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductPrice)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductPrice)
#Html.ValidationMessageFor(model => model.ProductPrice)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.user_image_data)
</div>
<div class="editor-label">
#Html.Label("Upload your image")
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.user_image_data, new { Type = "File" })
#Html.ValidationMessageFor(model => model.user_image_data)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductQuantity)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductQuantity)
#Html.ValidationMessageFor(model => model.ProductQuantity)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductStatus)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductStatus)
#Html.ValidationMessageFor(model => model.ProductStatus)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId, "Category")
</div>
<div class="editor-field">
#Html.DropDownList("CategoryId", String.Empty)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
</fieldset>
}
please help me in controller i am getting Null value for File upload
Update Ansawer
#model MvcApplication1.Models.NewProductCategory
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm("Create", "Temp", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ #Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>ProductCategory</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ProductName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductName)
#Html.ValidationMessageFor(model => model.ProductName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductDescription)
#Html.ValidationMessageFor(model => model.ProductDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductPrice)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductPrice)
#Html.ValidationMessageFor(model => model.ProductPrice)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.user_image_data)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.user_image_data, new { Type = "File" })
#Html.ValidationMessageFor(model => model.user_image_data)
</div>
<div class="editor-label">
#Html.Label("Upload your image")
</div>
<div class="editor-label">
#Html.TextBox("file",null,htmlAttributes: new { Type = "file" })
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductQuantity)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductQuantity)
#Html.ValidationMessageFor(model => model.ProductQuantity)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductStatus)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductStatus)
#Html.ValidationMessageFor(model => model.ProductStatus)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId, "Category")
</div>
<div class="editor-field">
#Html.DropDownList("CategoryId", String.Empty)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}

ViewModel does not populate input fields

I have a ViewModel that is used for an edit View. When the data is returned, the ID of the item to be edited does not display on the edit View.
public ActionResult Edit(int id)
{
Parcel parcel = _parcelDao.GetParcel(id);
ParcelEditViewModel viewModel = new ParcelEditViewModel();
viewModel.id = parcel.id;
return View(viewModel);
}
Should I be returning something different to the View?
ViewModel:
public class ParcelEditViewModel
{
public Parcel parcel { get; set; }
public int id { get; set; }
public IEnumerable<SelectListItem> TrackStatus { get; set; }
public ParcelEditViewModel()
{
parcel = new Parcel();
TrackStatus = new List<SelectListItem>
{
new SelectListItem
{
Value = "AwaitingCollection",
Text = "Awaiting Collection"
},
new SelectListItem
{
Value = "OutForDelivery",
Text = "Out For Delivery"
},
new SelectListItem
{
Value = "Delivered",
Text = "Delivered"
}
};
}
public int ParcelStatus { get; set; }
}
View:
//#model ABC.Data.Parcel
#model Abc.ViewModels.ParcelEditViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Parcel</legend>
#Html.HiddenFor(model => model.parcel.id)
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Forename)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Forename)
#Html.ValidationMessageFor(model => model.parcel.Forename)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Surname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Surname)
#Html.ValidationMessageFor(model => model.parcel.Surname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.CompanyName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.CompanyName)
#Html.ValidationMessageFor(model => model.parcel.CompanyName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Address1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Address1)
#Html.ValidationMessageFor(model => model.parcel.Address1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Address2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Address2)
#Html.ValidationMessageFor(model => model.parcel.Address2)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Address3)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Address3)
#Html.ValidationMessageFor(model => model.parcel.Address3)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.Postcode)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.Postcode)
#Html.ValidationMessageFor(model => model.parcel.Postcode)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ParcelStatus)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.parcel.TrackingStatus, Model.TrackStatus)
#Html.ValidationMessageFor(model => model.ParcelStatus)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.TrackingNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.TrackingNumber)
#Html.ValidationMessageFor(model => model.parcel.TrackingNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.parcel.CustomerId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.parcel.CustomerId)
#Html.ValidationMessageFor(model => model.parcel.CustomerId)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
You need to populate all of your view model's properties; not just the ID. The ParcelEditViewModel has no knowledge of what's in your database.
public ActionResult Edit(int id)
{
Parcel parcel = _parcelDao.GetParcel(id);
ParcelEditViewModel viewModel = new ParcelEditViewModel();
viewModel.id = parcel.id;
// Populate other properties! These may not be right.
viewModel.ProductName = parcel.Title;
viewModel.RecipientName; = parcel.RecipientName;
return View(viewModel);
}
There are mapping libraries such as AutoMapper that can help to streamline this.

Passing Model in ViewModel to controller get null (Edit Form)

This edit form was already success, then i want to add add comment to this form, to do this i'm following this article
http://www.arrangeactassert.com/when-to-use-html-renderpartial-and-html-renderaction-in-asp-net-mvc-razor-views/
i create the viewmodel named CaseInternalEditViewModel
public class CaseInternalEditViewModel
{
public CaseInternalEditViewModel()
{
caseComment = new List<CaseComment>();
}
public String caseIDComment { get; set; }
public CaseInternal caseInternal { get; set; }
public List<CaseComment> caseComment { get; set; }
}
and change model in View :
#model myCHMTest.Models.CaseInternalEditViewModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div class="container">
<fieldset>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<legend>CaseInternal</legend>
<div class="container">
#Html.HiddenFor(model => model.caseIDComment)
#Html.HiddenFor(model => model.caseInternal.ID)
#Html.HiddenFor(model => model.caseInternal.CaseID)
#Html.HiddenFor(model => model.caseInternal.StatusID)
#* #Html.HiddenFor(model => model.caseInternal.CreatedNIK)*#
#Html.HiddenFor(model => model.caseInternal.CreatedBy)
#Html.HiddenFor(model => model.caseInternal.CreatedDt)
#Html.HiddenFor(model => model.caseInternal.SLA)
#Html.HiddenFor(model => model.caseInternal.SLAFlag)
#Html.HiddenFor(model => model.caseInternal.DatCreated)
#Html.HiddenFor(model => model.caseInternal.DayResolved)
#Html.HiddenFor(model => model.caseInternal.CategoryID)
<div class="sixteen columns">
<div class="fbbluebox">
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.CaseID)
#Html.DisplayFor(model => model.caseInternal.CaseID)
#Html.ValidationMessageFor(model => model.caseInternal.CaseID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.caseInternal.Title)
#Html.ValidationMessageFor(model => model.caseInternal.Title)
</div>
</div>
<hr />
</div>
<div class="one-third column">
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.BranchID)
</div>
<div class="editor-field">
#Html.DropDownList("BranchID")
#Html.ValidationMessageFor(model => model.caseInternal.BranchID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.ProjectID, "InternalProject")
</div>
<div class="editor-field">
#Html.DropDownList("ProjectID", null, new { #onchange = "javascript:cascadingdropdown();" })
#Html.ValidationMessageFor(model => model.caseInternal.ProjectID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.SubProjectID, "InternalSubProject")
</div>
<div class="editor-field">
#Html.DropDownList("SubProjectID", String.Empty)
#*#Html.DropDownListFor(model => model.SubProjectID, new SelectList(Enumerable.Empty<SelectListItem>()))*#
#Html.ValidationMessageFor(model => model.caseInternal.SubProjectID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.PengaduanID, "InternalPPengaduan")
</div>
<div class="editor-field">
#Html.DropDownList("PengaduanID", String.Empty)
#Html.ValidationMessageFor(model => model.caseInternal.PengaduanID)
</div>
</div>
<div class="one-third column">
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.CreatedNIK)
</div>
<div class="editor-field">
#* #Html.TextBoxFor(model => model.caseInternal.CreatedNIK, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.CreatedNIK)*#
<input type="text" name="InitialNIK" value="#Model.caseInternal.CreatedNIK" disabled="disabled"/>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.CreatedBy)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.CreatedBy, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.CreatedBy)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.CreatedDt)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.CreatedDt, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.CreatedDt)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.AssignGroupID)
</div>
<div class="editor-field">
#Html.DropDownList("AssignGroupID", null, new { #onchange = "javascript:memberdropdown();" })
#Html.ValidationMessageFor(model => model.caseInternal.AssignGroupID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.AssignMemberID)
</div>
<div class="editor-field">
#Html.DropDownList("AssignMemberID", String.Empty)
#Html.ValidationMessageFor(model => model.caseInternal.AssignMemberID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.StatusID)
</div>
<div class="editor-field">
#Html.DropDownList("StatusID",null, new { #disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.StatusID)
</div>
</div>
<div class="one-third column">
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.SLA)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.SLA, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.SLA)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.SLAFlag)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.SLAFlag, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.SLAFlag)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.DayResolved)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.DayResolved, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.DayResolved)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.DatCreated)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.caseInternal.DatCreated, new { disabled = "disabled" })
#Html.ValidationMessageFor(model => model.caseInternal.DatCreated)
</div>
</div>
<div class="sixteen columns">
<div class="fbgreybox" >
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.Description)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.caseInternal.Description, new { style = "width: 100%; height: 100px;" })
#Html.ValidationMessageFor(model => model.caseInternal.Description)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.caseInternal.LinkCase)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.caseInternal.LinkCase)
#Html.ValidationMessageFor(model => model.caseInternal.LinkCase)
</div>
</div>
<p>
<input type="submit" value="Save" class="uibutton large confirm"/>
#Html.ActionLink("Back to List", "Index", "CaseInternal", new { #class = "uibutton" })
</p>
</div>
</div>
}
</fieldset>
</div>
#using (Ajax.BeginForm("Comment", "CaseInternal", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid", OnSuccess = "done" }))
{
#*<input type="text" id="caseEka" name="caseEka" />*#
#Html.HiddenFor(model => model.caseIDComment)
<input type="text" id="Comment" name="Comment"/>
}
<div id="myGrid">
#Html.Partial("_showComment", Model.caseComment)
</div>
<script type="text/javascript">
function done() {
document.getElementById('Comment').value = '';
}
function cascadingdropdown() {
var idDept = $("#ProjectID").val();
var subProject = $('#SubProjectID').val();
var urlemp = '#Url.Action("GetSubProjectFromProjectID")';
var select = $('#SubProjectID');
$.ajax({
type: "POST",
url: urlemp,
data: { id: idDept },
error: function (jqXHR, textStatus, errorThrown) {
alert("error" + jqXHR.responseText);
},
success: function (returndata) {
if (returndata.ok) {
select.empty();
$.each(returndata.data, function (index, itemData) {
if (subProject == itemData.ID) {
select.append($('<option selected="selected"></option>').val(itemData.ID).html(itemData.SubProjectName));
} else {
select.append($('<option></option>').val(itemData.ID).html(itemData.SubProjectName));
}
});
select.show('slow');
// $("#ProjectID").attr("disabled", "disabled");
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
}
function getNameNik() {
window.alert("AAAASSDSD");
var idDept = $("#CreatedNIK").val();
var urlemp = '#Url.Action("GetNameNik")';
$.ajax({
type: "POST",
url: urlemp,
data: { id: idDept },
error: function (jqXHR, textStatus, errorThrown) {
alert("error" + jqXHR.responseText);
},
success: function (returndata) {
if (returndata.ok) {
$('#nikLabel').text("");
$.each(returndata.data, function (index, itemData) {
$('#nikLabel').text(itemData.FirstName + " " + itemData.LastName);
});
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
}
function memberdropdown() {
var idDept = $("#AssignGroupID").val();
var subProject = $('#AssignMemberID').val();
var urlemp = '#Url.Action("GetMemberFromGroupID")';
var select = $('#AssignMemberID');
$.ajax({
type: "POST",
url: urlemp,
data: { id: idDept },
error: function (jqXHR, textStatus, errorThrown) {
alert("error" + jqXHR.responseText);
},
success: function (returndata) {
select.empty();
if (returndata.ok) {
$.each(returndata.data, function (index, itemData) {
if (subProject == itemData.ID) {
select.append($('<option selected="selected"></option>').val(itemData.ID).html(itemData.UserName));
} else {
select.append($('<option></option>').val(itemData.ID).html(itemData.UserName));
}
});
select.show('slow');
// $("#ProjectID").attr("disabled", "disabled");
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
}
function start() {
cascadingdropdown();
memberdropdown();
}
window.onload = start;
// window.onload = memberdropdown;
</script>
and here my controller:
public ActionResult Edit(string id)
{
CaseInternal caseinternal = db.CaseInternals.Find(id);
caseinternal.NullSafeTrimStrings();
ViewBag.PengaduanID = new SelectList(db.InternalPPengaduans, "ID", "PPengaduanName", caseinternal.PengaduanID);
ViewBag.ProjectID = new SelectList(db.InternalProjects, "ID", "ProjectName", caseinternal.ProjectID);
ViewBag.SubProjectID = new SelectList(db.InternalSubProjects, "ID", "SubProjectName", caseinternal.SubProjectID);
ViewBag.CategoryID = new SelectList(db.MasterCategories, "ID", "CategoryName", caseinternal.CategoryID);
ViewBag.AssignGroupID = new SelectList(db.MasterGroups, "ID", "GroupName", caseinternal.AssignGroupID);
ViewBag.AssignMemberID = new SelectList(db.MasterAssignUsers, "ID", "UserName", caseinternal.AssignMemberID);
ViewBag.BranchID = new SelectList(branchObject.A2BR, "BRCODE", "BRNAME", caseinternal.BranchID);
ViewBag.StatusID = new SelectList(db.MasterStatus, "ID", "StatusName", caseinternal.StatusID);
CaseInternalEditViewModel caseInternalEdit = new CaseInternalEditViewModel();
caseInternalEdit.caseInternal = caseinternal;
caseInternalEdit.caseIDComment = caseinternal.CaseID;
var commentCase = db.CaseComments.Where(p => p.CaseID == caseinternal.CaseID).OrderByDescending(p => p.CreatedDt);
foreach (CaseComment cas in commentCase)
{
caseInternalEdit.caseComment.Add(cas);
}
return View(caseInternalEdit);
}
[HttpPost]
public ActionResult Edit(CaseInternalEditViewModel caseinternalEdit)
{
//CaseInternalEditViewModel caseinternalEdit
CaseInternal caseinternal = caseinternalEdit.caseInternal;
if (ModelState.IsValid)
{
db.Entry(caseinternal).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.PengaduanID = new SelectList(db.InternalPPengaduans, "ID", "PPengaduanName", caseinternal.PengaduanID);
ViewBag.ProjectID = new SelectList(db.InternalProjects, "ID", "ProjectName", caseinternal.ProjectID);
ViewBag.SubProjectID = new SelectList(db.InternalSubProjects, "ID", "SubProjectName", caseinternal.SubProjectID);
ViewBag.CategoryID = new SelectList(db.MasterCategories, "ID", "CategoryName", caseinternal.CategoryID);
ViewBag.AssignGroupID = new SelectList(db.MasterGroups, "ID", "GroupName", caseinternal.AssignGroupID);
ViewBag.AssignMemberID = new SelectList(db.MasterAssignUsers, "ID", "UserName", caseinternal.AssignMemberID);
ViewBag.BranchID = new SelectList(branchObject.A2BR, "BRCODE", "BRNAME", caseinternal.BranchID);
ViewBag.StatusID = new SelectList(db.MasterStatus, "ID", "StatusName", caseinternal.StatusID);
return View(caseinternalEdit);
}
the modelstate is always invalid, because some field is null, field2 in dropdownlist is null when passing to controller.
is the viewbag the problem? should i change the name of viewbag?
#Html.EditorFor(model => model.caseInternal.Title)
is rendered to
<input class="text-box single-line" id="caseInternal_Title" name="caseInternal.Title" type="text" value="ViewModel" />
but dropdownlist
<select id="BranchID" name="BranchID"><option selected="selected" value="001">KANTOR PUSAT NON OPERASIONAL </option>
the different is the name, the branch should be caseinternal.branchID maybe it will work, but how to do that?
You have:
#Html.DropDownList("BranchID")
You want:
#Html.DropDownListFor(model => model.caseInternal.BranchID)
OR if you really don't want to use a DropDownListFor() for whatever reason....
#Html.DropDownList("caseInternal_BranchID")

Validation stopped working on use of formmethod.post

I am trying to post external URL for eg. (www.msn.com) on press of submit button.But when I do that none of my valdation works...it simply make an entry without any data in my external url
2. Also its not going to controller when i press submit button.
I don't know if I am doing anything wrong...
Here is my code for View:
#model n.Models.PopupDemoModel
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Demo","Home", FormMethod.Post, new { #action = "https://www.msn.com?encoding=UTF-8/post" }))
{
#Html.ValidationSummary(true)
<fieldset>
<input type=hidden name="oid" value="">
<input type=hidden name="retURL" value = "test" />
<input type="hidden" name="debug" value=1 />
<input type="hidden" name="debugEmail" value = "a#test.com" />
<div class="editor-label grid_2">
#Html.LabelFor(model => model.first_name)
</div>
<div class="editor-field grid_3">
#Html.TextBoxFor(model => model.first_name, new { #class = "demo-field-longer" })
</div>
<div class="grid_3 error long" style="margin-left:250px">
#Html.ValidationMessageFor(model => model.first_name)
</div>
<div class="clear"></div>
<div class="editor-label grid_2">
#Html.LabelFor(model => model.email)
</div>
<div class="editor-field grid_3">
#Html.TextBoxFor(model => model.email, new { #class = "demo-field-longer" })
</div>
<div class="grid_3 error long" style="margin-left:250px">
#Html.ValidationMessageFor(model => model.email)
</div>
<div class="clear"></div>
<div class="editor-label grid_2">
#Html.LabelFor(model => model.phone)
</div>
<div class="editor-field grid_3">
#Html.TextBoxFor(model => model.phone, new { #class = "demo-field-longer" })
</div>
<div class="grid_3 error long" style="margin-left:250px">
#Html.ValidationMessageFor(model => model.phone)
</div>
<div class="clear"></div>
<div class="editor-label grid_2">
#Html.LabelFor(model => model.company)
</div>
<div class="editor-field grid_3">
#Html.TextBoxFor(model => model.company, new { #class = "demo-field-longer" })
</div>
<div class="grid_3 error long" style="margin-left:250px">
#Html.ValidationMessageFor(model => model.company)
</div>
<div class="clear"></div>
<div class="clear"></div>
<div class="grid_2 sub-spacer"> </div>
<div class="editor-field grid_2 submit">
<input type="submit" value="Submit" id="demo-submit-button"/><br />
#ViewData["DemoMessage"]
</div>
</fieldset>
Here is my model:
public class PopupDemoModel
{
[Required]
[Email]
[DisplayName("Email address")]
public string email { get; set; }
[Required]
[DisplayName("Phone number")]
public string phone { get; set; }
[Required]
[DisplayName("Contact name")]
public string first_name { get; set; }
[Required]
[DisplayName("Company name")]
public string company { get; set; }
public string MessageSent
{
get { return "We'll contact you shortly."; }
}
}
It's doing exactly what you told it to.
The HTML <form> tag sends a POST request to the URL in the action attribute.
Html.BeginForm() creates a <form> tag with an action attribute that points to your controller.
When you set the action attribute explicitly, you replace the value from MVC and make it go directly to that URL.
If you want to do something with your data on server side before posting to another website, remove the action attribute so you will be posting to the same URL as at the beggining. In the action that is handling the POST from this form and doing the validation prepare your data. When you're ready, use WebRequest class to send this data to another website using POST method.

Resources