MVC Custom Dropdown From Model With Custom HtmlHelper?
Mar 31, 2011
i am just having a play with HtmlHelpers in MVC, very useful stuff and now i am trying to create one for dropdowns based on passing in a model ( any ) what the property is for the value and same for text.
I have a view that is strongly typed and its model is of type LogOnModel. That LogOnModel has anotated properties like this one:
[Required(ErrorMessage = "Please enter your password")] [DataType(DataType.Password)] [Display(Name = "Password", Description = "Your secreet password")] public string Password { get; set; }
All of them has Display anotation with Display.Descripion property set. I want to create HtmlHelper extension method that will output <span> containg the value of Display.Description property. So for example if I called my extension method DescriptionFor than this code:
<%: Html.DescriptionFor(m => m.Password) %>
should produce following html: <span>Your secreet password</span>
What I'm trying to do is rather basic, but I might have my facts mixed up. I have a details page that has a custom class as it's Model. The custom class uses 2 custom objects with yet another custom object a property of one of the 2. The details page outputs a fair amount of information, but allows the user to post a comment. When the user clicks the post button, the page gets posted to a Details action that looks something like this:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Details(VideoDetailModel vidAndComment) { ....} [Code]....
The only fields on the form that is posted are CommentText and VideoId. Here is what the VideoDetailModel looks like.
public class VideoDetailModel { public VideoDetailModel() { [Code].... I suppose if I added more form fields for the properties I need, they would get posted, but I only need 1 form entry field for the CommentText. If I could get the same Model objects value that were sent to the page to post with the page, it looks like the solution is rather simple. I think using the RenderPartial in the middle of a form is problematic somehow to how the form gets written in html. I can't really put my finger on why things went bonkers, but if I do my RenderPartials before my form and then begin my form with the text entry field and the hidden VideoId, the default ModelBinder works just fine. I was beginning the form, writing the hidden VideoId, rendering several partial views, create my CommentText field, and then closed the form out. The CommentText field would get bound just fine. The hidden VideoId would not. Maybe I missed a rule somewhere about using RenderPartial.
For completeness, the partial view I was rendering took a Comment object and just wrote out it's CommentText data. Several of these objects would exist for a single Video object. All of this data was in a custom type and passed into the View (the main view) as it's Model. This partial view did not have a form and did not have any data entry fields.
When you render one of the "built in" html helpers (say "TextBoxFor") with ":" (so it's encoded) it renders fine.However if I render the following (a custom file input helper) with ":", the markup are displayed.I understand why. Just don't know how to prevent this (no, I want to stay with ":" and not use "=")(I looked at the source code for the built in ones, but can't see what I'm missing: ttp://aspnet.codeplex.com/SourceControl/changeset/view/23011#288010 )
I am trying to understand a little more about implementing a custom model validator. I have implemented a custom model validator (derived from DataAnnotationsModelValidator<T>) for my custom validation attribute in order to do validation on the client side as well. There is not much documented about DataAnnotationsModelValidator. Besides, implementing client-side validation when is it a good idea or needed to implement a custom model validator for a custom attribute?
A separate question - in trying to understand how and when a custom model validator is used by the framework I noticed that my custom validator is always created with the context (2nd parameter in DataAnnotationsModelValidator<T>'s constructor) being a ViewContext, although it is declared as ControllerContext. Will a validator ever be created with something else than a ViewContext, and if so, when?
'm building a custom MetadataProvider and I'd like to access the actuall model value in the CreateMetadata method.
[Code]....
When the current model value is of type string, the model value can be found in metadata.Model. But when the model is of reference type the value is null.
So I have one custom model binder that inherits from DefaultModelBinder, where I am overriding the BindProperty() method to handle a type of field we've created. I also have one controller that we'd like to override BindModel() on, since we're handling an object in session for multiple views with that controller.
So I have CustomModelBinder : DefaultModelBinder, and then in the class where we override BindModel() i have that inheriting from CustomModelBinder. SpecialModelBinder: CustomModelBinder
But I have set a breakpoint in our override of BindProperty() in CustomModelBinder, and this never gets hit when using the controller that is also overriding BindModel(). Can I not inherit like this? What's happening here?
edit: in global.asax: ModelBinders.Binders.Add(typeof(ClassA), new SpecialModelBinder()); ModelBinders.Binders.Add(typeof(ClassB), new CustomModelBinder()); ModelBinders.Binders.Add(typeof(ClassC), new CustomModelBinder()); ModelBinders.Binders.Add(typeof(ClassD), new CustomModelBinder()); public class CustomModelBinder : DefaultModelBinder { // this will be hit in controllers that handle classes B, C, and D, but will not be hit in controller that handles ClassA protected override void BindProperty(...){} } public class SpecialModelBinder : CustomModelBinder { // this will be hit when working in controller that handles ClassA only public override object BindModel(...){} }
I am working on the example from Steven Sanderson's book 'Pro ASP.NET MVC Framework'. The cart class is coming up as empty in my Index action method of CartController class.
i am creating a MVC2 application for pubs and bars. I have a model 'Opening_Time' with the following properties:
int Day,time OpeningTimetime ClosingTimeWhen adding/editing an Opening_Time, I want to validate an Opening_Time, to check the user isn't adding one for an existing Day (ie they can't have two entries for the same day).
How/Where is the best place to do this?
Preferably, I want to do it a Model level, so I can use Model.IsValid and the Html.Form helpers
I am trying to build a custom composite control, which allows me to add custom content to each child control. It's a similar concept to what you have with a GridView and TemplateColumn. The markup used to place the control on the page would end up being something like this:
[Code]....
I have the code below, which allows me to put that markup on the page without throwing any errors, and it renders all the correct HTML, except it doesn't render the contents of the ColumnTemplate. I have replaced the Render() code with a comment because it's quite long winded and doesn't add anything important here:
[Code]....
I have tried to follow examples on MSDN and other forums but I can't make this work. I think I'm missing the code to render the contents of the template, but I don't know how to hook that up.
I'm working on an ASP.NET MVC 2 project with some business entities that have metadata dataannotations attributes applied to them (Validation attributes, Display attributes, etc.).
Something like:
[Code]....
Using the metadata from different views is no problem, as long as I am using my business entities as viewmodels or as part of a viewmodel like this:
[Code]....
However, sometimes I need to code a view for editing some, but not all fields of an entity. For those fields I want to reuse the metadata already specified in my user entity. The other fields should be ignored. I'm talking about custom view models like this:
[Code]....
That's where I am running into problems. The custom view model above leads to an exception when the view is generated, because it has no password property.
The associated metadata type for type 'Zeiterfassung.Models.ViewModels.Users.UserNameViewModel+UserModel' contains the following unknown properties or fields: Password. make sure that the names of these members match the names of the properties on the main type.
Also, even if this exception did not occur, I expect to get into even more trouble with model validation on form submit because Password is marked as required in my business entity.
I can think of several workarounds, but none seem really ideal. In any case I can't change the database layout so that the password field would be in a separate entity in my example above.
public class SectionModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (bindingContext.ModelType.IsAssignableFrom(typeof(Section)) && value != null) { if (Utilities.IsInteger(value.AttemptedValue)) return Section.GetById(Convert.ToInt32(value.AttemptedValue)); else if (value.AttemptedValue == "") return null; } return base.BindModel(controllerContext, bindingContext); } }
Now within my controller i can say:
[HttpPost] public ActionResult Create(FormCollection collection) { var category = new Category(); if (!TryUpdateModel(category, "Category") return View(new CategoryForm(category, _sectionRepository().GetAll())); }
This validates nicely and the correct value for the section is assigned when the model is updated, however it does not select the correct value if another property doesn't validate.
I have a question about model binding. Imagine you have an existing database entity displayed in a form and you'd like to edit some details, some properties eg createddate etc are not bound to the form, during model binding, these properties are not assigned to the model as they are not on the http post data or querystrong etc, hence their properties are null. In my controller method for update , Id just like to do
public ActionResult Update( Entity ent) { //Save changes to db }
but as some properties are null in ent, they override the existing database fields which are not part of the form post data, What is the correct way to handle this? Ive tried hidden fields to hold the data, but model binding does not seem to assign hidden fields to the model.
I was wondering if anyone can point me in the right direction? I have a POCO model and I am using Code First CTP. In my application, I set the database to be recreated whenever the model changes.
I would like to write custom functionality to access the model (POCO) metadata same way as EF sees it and use that to generate some source files (using T4). I would like to access the processed model not having to worry about finding properties that hold primary keys or any other conventions (implicit or not). What is the way to go about it?
I am new to MVC framwork and have a big project on my hand.The MVC given a inbuilt membership provider .But I want to a custom database account management of users like admin user,subadmin user and site users.provide me functionlity(total step by step ) about login module with work with stored procedure and how i validate valid user login in the site and redirect from home page with displaying username etc.
I have implemented a custom ModelMetadataProvider so that I can decorate my view models with some custom attributes and everything was working fine until I made use of a Partial View. The following code in my view works fine: -
<%: Html.DisplayFor(x => x.Results) %>
Results is a List which renders a custom display template and is also decorated with a custom attribute. Using breakpoints, after the above line and prior to the code within the custom display template, the overridden CreateMetadata method in my custom ModelMetadataProvider is invoked. If I look at the attributes collection parameter I can see that it does contain my custom attribute thus everything working as expected. However, if I replace the above with the following line of code in my view then it breaks: -
<% Html.RenderPartial("ApplicationSearchResults", Model.Results, new ViewDataDictionary()); %>
All the Partial View contains is: -
<%: Html.DisplayFor(x => x) %>
Again using breakpoints, after the above line and prior to the code within the custom display template, the overridden CreateMetadata method in my custom ModelMetadataProvider is invoked. But this time if I look at the attributes collection parameter my custom attribute is not there.