Selected item list and other object - asp.net-mvc-3

I'm new in asp.net mvc3 programming and I'm trying to build a specific form. I need to have a form with the user field (which I have) but also a list of object (in that case SStatus).
My form :
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Création d'utilisateur</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Lastname)
#Html.ValidationMessageFor(model => model.Lastname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Firstname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Firstname)
#Html.ValidationMessageFor(model => model.Firstname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Login)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Login)
#Html.ValidationMessageFor(model => model.Login)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<p>Status</p>
#{
//The error was form here
#{
var list = ViewBag.listStatus as List<SStatus>;
}
#if (list != null)
{
foreach(var status in list)
{
<option value=#status.ID>#status.Name</option>
}
}
</select>
}
<p>
<input type="submit" value="Création" />
</p>
</fieldset>
}
The list call :
public ActionResult CreateUserView()
{
RestClient client = new RestClient(Resource.Resource.LocalUrlService);
RestRequest request = new RestRequest("/status/all", Method.GET);
var response = client.Execute(request);
if(response.StatusCode == HttpStatusCode.OK)
{
List<SStatus> listSatus = JsonHelper.FromJson<List<SStatus>>(response.Content);
ViewBag.listStatus = listSatus;
}
return View();
}
And the form post:
[HttpPost]
public ActionResult CreateUserView(Uuser userToCreate, string list)
{
//list got the ID of SStatus.
if (ModelState.IsValid)
{//Stuff}
}
So the question is : How get the selected list item ?
Regards.

Use a view model pattern. I still don't see how your Uuser object is sent to the view (via the default [HttpGet] action, but I think I see what you're trying to accomplish.) If you refactor this way, you'll still get to use the built-in validation, automagic model binding, etc.
public class CreateUserViewModel
{
public Uuser User { get; set; }
public string Status { get; set; }
}
Then your action parameter should be of type CreateUserViewModel e.g.
[HttpPost]
public ActionResult CreateUserView(CreateUserViewModel vm)
{
if(ModelState.IsValid)
{
{//Stuff}
}
I believe you'll need a name attribute on the <select> element in order for it to be posted.
<p>Status</p>
#{
<select name="Status">
Although, you're going to run into trouble if the model isn't valid. Your view should be strongly typed against CreateUserViewModel e.g.
#model YourModelNamespace.CreateUserViewModel
So, your Lastname property might look like this (note the .User)
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Création d'utilisateur</legend>
<div class="editor-label">
#Html.LabelFor(model => model.User.Lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.User.Lastname)
#Html.ValidationMessageFor(model => model.User.Lastname)
</div>
And finally, I guess you could keep the possible list of status in the ViewBag, but you'll want to set the selected value to #Model.Status. You may want to consider changing CreateUserViewModel.Status to a List<SelectListItem> that you can populate from your controller e.g. your GET action should return View(CreateUserViewModel)
public ActionResult CreateUserViewModel()
{
CreateUserViewModel vm = new CreateUserViewModel();
vm.User = // set user
vm.Status = new List<SelectListItem>()
{
new SelectListItem()
{
Value = "status1",
Text = "status 1",
Selected = false
},
new SelectListItem()
{
Value = "status2",
Text = "status 2",
Selected = true
},
};
return View(vm); // this is the correct way to strongly type your view
}

Related

Update entity in mvc4

i want to update existing row in database, the problem is that i have 4 properties that user is not supposed to update. If i try code bellow it throws error "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." thx
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id, Name, Author, Price")]Book book)
{
book.NewBookId = db.Book.Single(x => x.Id == book.Id).NewBookId;
book.UsedBookId = db.Book.Single(x => x.Id == book.Id).UsedBookId;
book.TextBook = db.Book.Single(x => x.Id == book.Id).TextBook;
book.WorkBook = db.Book.Single(x => x.Id == book.Id).WorkBook;
if (ModelState.IsValid)
{
db.Book.Attach(book);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(book);
}
View
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Author)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Author)
#Html.ValidationMessageFor(model => model.Author)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</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>
The Book with the same key already exists.
You are trying to update the existing book, right?
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id, Name, Author, Price")]Book model)
{
if (ModelState.IsValid)
{
var book = db.Book.SingleOrDefault(x => x.Id == model.Id);
if(book != null)
{
book.Name = model.Name;
book.Author = model.Author;
book.Price= model.Price;
db.SaveChanges();
return RedirectToAction("Index");
}
ModelState.AddModelError("Id", "Couldn't find book id.")
}
return View(model);
}

Display message using view bag without refreshing view

I have a view A From ControllerA Which has two buttons 1. Create 2. Update
Upon clicking update or Create its opening a new partial viewB As popup from another controller B.
What iam trying to get is If a record is created successfully in b I am now closing the popup. Apart from closing the popup I want to display a message in view A.
I am trying like this:
Controller B
public ActionResult Create(FormCollection args)
{
var obj = new ProjectManagernew();
var res = new ProjectViewModelNew();
try
{
UpdateModel(res);
if (obj.AddUpdateOrderField(res))
{
ViewBag.RecordAdded = true;
ViewBag.Message = "Project Added Successfully";
}
return View(res);
}
catch (Exception)
{
//ModelState.AddRuleViolations(res.GetRuleViolations());
return View(res);
}
}
And in the view A:
#if(ViewBag.Message!=null)
{
#ViewBag.Message
}
View B:
#model DreamTrade.Web.BL.ViewModels.ProjectViewModelNew
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout_Popup.cshtml";
}
#if (ViewBag.RecordAdded != null && (bool)ViewBag.RecordAdded)
{
<script type="text/javascript">
parent.$.nmTop().close();
$('#jqgprojectnew').text("Record added successfully");//jqgprojectnew is the name of grid in view A
</script>
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Project</legend>
#Html.HiddenFor(model => model.ProjectID)
<div class="editor-label">
#Html.LabelFor(model => model.ProjectDetail)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectDetail)
#Html.ValidationMessageFor(model => model.ProjectDetail)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectRef)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectRef)
#Html.ValidationMessageFor(model => model.ProjectRef)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectName)
#Html.ValidationMessageFor(model => model.ProjectName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StatusList)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.ProjectStatusId,new SelectList(Model.StatusList,"SourceStatusId","Description"),"Please Select")
#Html.ValidationMessageFor(model => model.ProjectStatusId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CustomerList)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Id,new SelectList(Model.CustomerList,"Id","Name"),"Please Select")
#Html.ValidationMessageFor(model => model.Id)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<div>
Back to list
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
please let me know where iam doing wrong
Include a label field where you want to show the message.
<label id=mylabel></label>// Add this before jqgrid
Modify the code to:
#if (ViewBag.RecordAdded != null && (bool)ViewBag.RecordAdded)
{
<script type="text/javascript">
parent.$.nmTop().close();
$('#mylabel').text("Record added successfully");
</script>
}

Required data annotation is not working on a DropDownlist inside my asp.net mvc3

i have defined the following in my validation model class
public class Visit_Validation
{
[Display(Name = "Assign to Doctor")]
[Required(ErrorMessage= "Please select a Doctor")]
public string DoctorID { get; set; }}
Then i have created the DoctorID Selectlist as follow:-
public ActionResult Create(int patientid)
{
Visit visit = new Visit();
var allusers = Membership.GetAllUsers();
ViewBag.DoctorID = new SelectList(allusers, "Username", "Username");
return View(visit);
}
and finally i define the dropdownlist at the view as follow:-
<div class="editor-label">
#Html.LabelFor(model => model.DoctorID)
</div>
<div class="editor-field">
#Html.DropDownList("DoctorID", String.Empty)
#Html.ValidationMessageFor(model => model.DoctorID)
</div>
but the problem i am facing is that incase the user leave the DoctorID dropdownlist empty then the [Required(ErrorMessage= "Please select a Doctor")] error will not be displayed? so what might be going wrong?
BR
Update:-
here is the full view code:-
<h2>Create</h2>
#section scripts{
<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>Visit</legend>
<div class="editor-label">
#Html.LabelFor(model => model.VisitTypeID, "VisitType")
</div>
<div class="editor-field">
#Html.DropDownList("VisitTypeID", String.Empty)
#Html.ValidationMessageFor(model => model.VisitTypeID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Date)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Date, new { value = "FL", disabled = "disabled" })
#Html.ValidationMessageFor(model => model.Date)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Note)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Note)
#Html.ValidationMessageFor(model => model.Note)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DoctorID)
</div>
<div class="editor-field">
#Html.DropDownList("DoctorID", String.Empty)
#Html.ValidationMessageFor(model => model.DoctorID)
</div>
<div class="editor-label">
Visit Status
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.VisitStatu.Description, new { value = "FL", disabled = "disabled" })
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CreatedBy)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.CreatedBy, new { value = "FL", disabled = "disabled" })
#Html.ValidationMessageFor(model => model.CreatedBy)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
here is the Post action method code:-
[HttpPost]
public ActionResult Create(Visit visit)
{
if (ModelState.IsValid)
{
visit.StatusID = repository.GetVisitStatusByDescription("Assinged");
visit.CreatedBy = User.Identity.Name;
visit.Date = DateTime.Now;
repository.AddVisit(visit);
repository.Save();
return RedirectToAction("Index");
}
ViewBag.DoctorID = new SelectList(Membership.GetAllUsers(), "Username", "Username");
ViewBag.StatusID = new SelectList(repository.FindAllVisitStatus(), "StatusID", "Description");
ViewBag.VisitTypeID = new SelectList(repository.FindAllVisitType(), "VisitTypeID", "Description");
return View(visit);
}
In order for validation to be triggered you need to have your POST controller action take the model as parameter:
[HttpPost]
public ActionResult Create(Visit visit)
{
...
}
or use the TryUpdateModel method:
[HttpPost]
public ActionResult Create()
{
Visit visit = new Visit();
if (!TryUpdateModel(visit))
{
// validation failed
}
...
}
When the form is submitted to this controller action the default model binder will invoke the validation rules contained in this Visit model. If your controller action never works with this model there's nothing out there that will ever interpret the data annotations that you put on it.

ASP.Net MVC 3 how to UpdateUser account?

i want to update user account in my project. i have a view like this :
#using (Html.BeginForm("edit/" + #Model.SysUsers[0].UserID, "cpanel/sysuser",
FormMethod.Post))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>#Model.SysUsers[0].UserID</legend>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SysUsers[0].UserName)
#Html.ValidationMessageFor(model => model.SysUsers[0].UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserEmail)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SysUsers[0].UserEmail)
#Html.ValidationMessageFor(model => model.SysUsers[0].UserEmail)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserComment)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SysUsers[0].UserComment)
#Html.ValidationMessageFor(model => model.SysUsers[0].UserComment)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserLocked)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SysUsers[0].UserLocked)
#Html.ValidationMessageFor(model => model.SysUsers[0].UserLocked)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserApproved)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SysUsers[0].UserApproved)
#Html.ValidationMessageFor(model => model.SysUsers[0].UserApproved)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysUsers[0].UserOffice)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.SysUsers[0].UserOffice, new
SelectList(Model.GetawayOffice, "OfficeCode", "OfficeDesc",
Model.SysUsers[0].UserOffice))
#Html.ValidationMessageFor(model => model.SysUsers[0].UserOffice)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
and the controller is like this :
public ActionResult Edit(string id)
{
model.SysUsers = repo.SelectSystemUser(id).ToList();
model.Office = reps.Office().ToList();
return View(model);
}
[HttpPost]
public ActionResult Edit(string id, FormCollection collection)
{
//update in System_User Table
Guid UserId = new Guid(id.ToString());
var SysUser = db.System_User.Single(s => s.User_UserId == UserId);
SysUser.User_Office = collection["SysUsers[0].UserOffice"];
//update aspnet_membership, like comment, email, isLocked, isApproved
...
}
i can update Office in Sytem_User table, but how can I update aspnet_membership (its for updting comment, email, isLocked, isApproved) ?
i think that i must use
membership.UpdateUser(MembershipUser User)
but can someone give me an example how to use membership.UpdateUser ?
now i can update user comment and user email, i use this :
var usermembership = Membership.GetUser(UserId);
usermembership.Comment = collection["SysUsers[0].UserComment"];
Membership.UpdateUser(usermembership);
usermembership.Email = collection["SysUsers[0].UserEmail"];
Membership.UpdateUser(usermembership);
but, i cant update user locked and user approve. how to update thoose ?
thank you
Membership.UpdateUser Method
Updates the database with the information for the specified user.
MembershipUser u = Membership.GetUser(User.Identity.Name);
u.Email = someValue;
Membership.UpdateUser(u);
Have a look at http://msdn.microsoft.com/en-us/library/system.web.security.membership.updateuser.aspx
Possible dupe of ASP.Net MVC 3 Membership.UpdateUser(MembershipUser user)
Hmm - I think you are on the right track. Perhaps have a look around for examples of apps that use membership.
Here I am using WebForms to change a password:
user = Membership.GetUser(txtUsername.Text);
string generatedPassword = user.ResetPassword();
user.ChangePassword(generatedPassword, txtPassword.Text);
Good luck.
I think a way would be the one to write your onw membershipuser implementation.
Look at this post "How to: Implement a Custom Membership User".
If you don't like to implement every method you can create a descendant class and write only the methods you need to behave differently, then declare your new provider in the web.config

How do I bind relational data to a model in ASP.net MVC?

I am trying to make an editor for an object in ASP.net MVC 3. It looks something like this:
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.foo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.foo)
#Html.ValidationMessageFor(model => model.foo)
</div>
#if (Model.Items.Count > 0)
{
<table>
#foreach (var ii in Model.Items)
{ #Html.EditorFor(item => ii) }
</table>
}
In this example, Items is a list of another kind of object. The problem is, when the model is posted back from being edited in the view, the data changes to Model.Items aren't there, while the data changes to Name and foo work. How can I make it so that the data for Items binds correctly?
Model class:
public class HomeControllerModel
{
public string Name { get; set; }
public string foo { get; set; }
public List<string> Items { get; set; }
public HomeControllerModel()
{
Items = new List<string>();
}
}
Controller class:
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
var model = new HomeControllerModel();
model.Name = "LukLed";
model.foo = "bar";
model.Items.Add("AAA");
model.Items.Add("BBB");
model.Items.Add("CCC");
return View(model);
}
[HttpPost]
public ActionResult Index(HomeControllerModel model)
{
return View(model);
}
View:
#using MvcApplication4.Controllers
#model HomeControllerModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
<form action="/Home/Index" method="post">
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.foo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.foo)
#Html.ValidationMessageFor(model => model.foo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Items)
</div>
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>
You don't have to iterate through Items.

Resources