I am encountering many problems (validation, serialisation) when using models that embed other models and just wanted to know whether anybody has received issue with this kind of thing before. For example I have an enquiry form which has the following model attached:
Model
namespace
{
public class EnquiryStudent
{
public enquiry enquiry { get; set; }
public student student { get; set; }
}
}
The enquiry and student models (embedded inside enquiry student) are auto generated from the database (I am using database first approach).
Now for example a problem I get here is that I use a view to display a form based on the above model:
View
#using (#Html.BeginForm())
{
<div>
<fieldset>
<fieldset>
<legend>Enquiry</legend>
<div class="editor-label">
#Html.LabelFor(m => m.student.firstname)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.student.firstname)
#Html.ValidationMessageFor(m => m.student.firstname)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.student.surname)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.student.surname)
#Html.ValidationMessageFor(m => m.student.surname)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.student.email)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.student.email)
#Html.ValidationMessageFor(m => m.student.email)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.enquiry.subject)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.enquiry.subject)
#Html.ValidationMessageFor(m => m.enquiry.subject)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.enquiry.enquiry_text)
</div>
<div class="editor-field">
#Html.TextAreaFor(m => m.enquiry.enquiry_text)
#Html.ValidationMessageFor(m => m.enquiry.enquiry_text)
</div>
</fieldset>
<p>
<input type="submit" class="rounded-button-gray-shades" value="Send" />
</p>
</fieldset>
</div>
}
and the client side validation works great for everything except the enquiry text (an attribute of the embedded enquiry within EnquiryStudent model, i.e. it doesn't validate this client side only server side??
Now even stranger if I either change the enquiry_text to be a TextBoxFor instead of TextAreaFor it works great.
Or if I make a text area for another entity by adding a dummy field to the EnquiryStudent model (not embedded in another model) it works fine.
Can somebody please shed some light as like I said this is not the only quirk that I have been having with this kind of model relationship.
Thanks,
Related
#model eDurar.Models.BuyOnlineAddress
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>BuyOnlineAddress</legend>
<div class="editor-label">
Address Details
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Details, new {#required="required" })
#Html.ValidationMessageFor(model => model.Details)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
This is partial view, in the html generated, there is no required attribute
When I manually insert it in the html editor, works fine, but this method usually works for normal views
I haven't loaded any scripts this time
Thanks I got it now, I changed
#Html.EditorFor(model => model.Details, new {#required="required" })
to
#Html.TextBoxFor(model => model.Details, new {#required="required" })
I have a parent view and a partial view, but when it try to load the partial view from the parent view get the following error
The model item passed into the dictionary is of type 'System.Data.Objects.DataClasses.EntityCollection`1[RolMVC3.Models.OFFICE]',but this dictionary requires a model item of type 'RolMVC3.Models.OFFICE'.
partial view:
#model RolMVC3.Models.OFFICE
#Html.HiddenFor(model => model.IdOffice)
#Html.HiddenFor(model => model.IdSCampus)
<div class="editor-label">
#Html.LabelFor(model => model.AddressOffice)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressOffice)
#Html.ValidationMessageFor(model => model.AddressOffice)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneOffice)
</div>
<div class="editor-field">
#Html.EditorFor(model => model..PhoneOffice)
#Html.ValidationMessageFor(model => model..PhoneOffice)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailOffice)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailOffice)
#Html.ValidationMessageFor(model => EmailOffice)
</div>
parent view:
#model RolMVC3.Models.CAMPUS_UNIVERSITY
#{
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)
<h2> #ViewBag.University.Name - #ViewBag.Campus.NameCity </h2>
<fieldset>
<legend>MODIFY OFFICE</legend>
#Html.HiddenFor(model => model.IdUniversidty)
#Html.HiddenFor(model => model.IdCityCampus)
#Html.HiddenFor(model => model.IdCampus)
<div class="editor-label">
#Html.LabelFor(model => model.AddressCampus)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AddressCampus)
#Html.ValidationMessageFor(model => model.AddressCampus)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneCampusSede)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneCampus)
#Html.ValidationMessageFor(model => model.PhoneCampus)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EamailCampus)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EamailCampus)
#Html.ValidationMessageFor(model => model.EamailCampus)
</div>
<fieldset>
<legend>DATA</legend>
#Html.Partial("_Office", Model.OFFICE)
</fieldset>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
controller:
public ActionResult Edit()
{
decimal id;
id = (decimal)Session["Offi"];
ViewBag.University = (from c in db.OFFICE
join s in db.CAMPUS_UNIVERSITY on c.IdCampus equals s.IdCampus
join u in db.UNIVERSIDTY on s.IdUniversity equals u.IdUniversity
where c.IdOffice == id
select u).Single();
ViewBag.Campus = (from c in db.OFFICE
join s in db.CAMPUS_UNIVERSITY on c.IdCampus equals s.IdCampus
join ci in db.CIUDAD on s.IdCaityCampus equals ci.IdCity
where c.IdOffice == id
select ci).Single();
OFFICE office = db.OFFICE.Single(c => c.IdOffice == id);
CAMPUS_UNIVERSITY campus_university = db.CAMPUS_UNIVERSITY.Single(s => s.IdSede == office.IdCampus);
return View(campus_university);
}
blessings
Can you show what RolMVC3.Models.OFFICE and CAMPUS_UNIVERSITY objects look like? I'm guessing your CAMPUS_UNIVERSITY model has something weird going on in it. Is the .OFFICE field tightly cast as an OFFICE object or is it an enumerable? You could probably test this out quickly by passing in Model.OFFICE[0] in the view.
Your controller has the code
OFFICE office = db.OFFICE.Single(c => c.IdOffice == id);
CAMPUS_UNIVERSITY campus_university = db.CAMPUS_UNIVERSITY
.Single(s => s.IdSede == office.IdCampus);
But your View is ONLY using the model CAMPUS_UNIVERSITY. I would assume that the CAMPUS_UNIVERSITY.Office property is a EntityCollection<OFFICE> which does not match the view's requirement of Office.
One solution is to display all the offices:
#foreach(var office in Model.OFFICE)
{
#Html.Partial("_Office", office)
}
or the other is to actually use the Office you created in the controller
Controller (add)
ViewBag.Office = db.OFFICE.Single(c => c.IdOffice == id);
View (change)
#Html.Partial("_Office", ViewBag.Office)
It looks like you are passing a differnt type than what is expecting. From your view, i could undestand that the view is expecting an object of type "OFFICE". Are you sure the modal you are passing to the Partial View call is of same type ? Or are you passing a List of Offices ?
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
I have a mvc 3 form with 2 columns. The left column is a treeview and when a node is selected the div with id='partialView' is updated to show the details of that node. This appears to be work ok.
The edit form (which is a partial view) is loaded in the div with id='partialView'.
Now the problem occurs when the user submits this partial view...now it does post back to the controller and the correct method HOWEVER the result is not returned to the div with id='partialView' but posts to a new page.
So this is the scenario where I want the partial view to post and return back replacing the existing partial view.
Is this possible?
I am including my code below for my partial view...
#model DataModel.Code
#using (Ajax.BeginForm("Edit", "Code", new AjaxOptions {
UpdateTargetId = "partialView",
HttpMethod="POST"
}
)) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Code</legend>
#Html.HiddenFor(model => model.CodeID)
<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>
<div class="editor-field">
#Html.EditorFor(model => model.Note)
#Html.ValidationMessageFor(model => model.Note)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DateModified)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DateModified)
#Html.ValidationMessageFor(model => model.DateModified)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TopicID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TopicID)
#Html.ValidationMessageFor(model => model.TopicID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Special)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Special)
#Html.ValidationMessageFor(model => model.Special)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Html)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Html)
#Html.ValidationMessageFor(model => model.Html)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#Html.Telerik().ScriptRegistrar().jQuery(true)
<script type="text/javascript">
$(document).ready(function () {
});
</script>
Include
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
in your _Layout.cshtml
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.