MVC Class Level Custom Data-annotation And ModelState Keys?
Apr 10, 2010
I have custom class level validation attribute, inheriting from ValidationAttribute, on my model.
How come it doesn't register a key in the ModelState when its IsValid is false? I can see the the error message in the ModelState.Values collection, but the ModelState.Keys collection only shows an empty string "". Can I provide a key for it - presumably this is because its not assigned to a property?
I wanna be able to use ModelState.Remove in my controller to remove this error upon a certain condition, but I have no Key!
I am a MVC newbie & am lost in various ways validation can be implemented in my application.
I created a custom model-level data annotation validator attribute, but am unable to display its error message in the view. Basically, I have let's say 5 properties in the Entity class Job (model-level custom attribute called UniqueKeywords defined on it):
1) LoginID: value comes in the URL
2) Title: Required property level attribute defined on it
3) CatID1, CatID2, CatID3 - 3 categoryIDs - these are dropdowns in the view with same list of keywords in all 3.
I want to mandate that the values picked by the user in all 3 category dropdowns should be different.
With reference to the code pasted below, here is the explanation of what happens:
When I submit the form without specifying a title or picking anything from any of the 3 category dropdowns, the validation occurs for the property level Required attribute as well as model level uniquekeywords attribute, but the error is displayed only next to the required field "Title". I can confirm that the custom validation also works by filling in some text in the Title field & then re-posting the form...this re-displays the view, but the error message "Category cannot be duplicated" is not displayed.
I have found hints that MVC 2 recognises the 'buddy class' type of property metadata, where data annotation attributes are applied to a 'buddy' metadata class, and the MetadataType on the actual entity class points to that buddy class, as below. However, as below, it seems the only attribute that makes any difference to the rendered UI is DisplayName. Why are the other attributes like DataType, Required, and ReadOnly not working? I.e. why can I enter text in a read only field? Why do I not get an error when a required field is empty? Why does the DataType attribute have no apparent effect? Why does EditorForModel not include validation messages?
[MetadataType(typeof(CustomerMetadata))] public partial class Customer { public class CustomerMetadata { [ScaffoldColumn(false)] public object CustomerId { get; set; } [DisplayName("CustomerNo.")] [ReadOnly(true)] [Required(AllowEmptyStrings = false, ErrorMessage = "Customer No. is required.")] public object CustomerNo { get; set; } } }
I find behaviour the same whether I use an explicit LabelFor and TextBoxFor for each model property, or a single EditorForModel for the whole model.
Wanting to create custom data annotation validation. Are there any useful guides / samples on how to create them?
Firstly: StringLength with minimum and maximum length. I'm aware .NET 4 can do this, but want to do the same in .NET 3.5, if possible being able to define minimum length only (at least x chars), maximum length only (up to x chars), or both (between x and y chars).
Secondly: Validation using modulus arithmetic - if the number is a valid length, I wish to validate using the Modulus 11 algorithm (I have already implemented it in JavaScript, so I guess it would just be a simple porting?)
Update: Solved second problem, was just a case of copying over the JavaScript implementation and making a few tweaks, so don't need a solution for that.
I am creating a custom 'control' which is simply made of two html inputs [type=text] but can't figure out how the validation will work on the view end.
I want to treat these 2 inner controls as asingle control so when a error is added to modelstate both of these inputs are highlighted in the view and a single validation message is shown.
I'm getting started with Astoria/ADO.NET Data Services/WCF Data Services. Looking through a lot of the code samples out there, it appears that the MimeType attribute used to be a method level attribute. After installing the latest update, it is now a class level attribute.
If I have more than one Service Operation that I want to return as a certain MimeType, then it appears now that I have to create a new service for each operation. Is this correct?
Most examples are like this:
[WebGet] [SingleResult] [MimeType("application/pdf")] public IQueryable<byte[]> FooPDF() { var result = from p in this.CurrentDataSource.MyPDFs where p.FooID == 2 select p; return result.Take(1).Select(p => p.PDF); }
I get "Attribute 'MimeType' is not valid on this declaration type. It is only valid on 'class' declarations." when I compile, because now I can't do this.
Now, I have to do this:
[MimeType("FooPDF", "application/pdf")] public class FooService : DataService<FooDBEntities> { public static void InitializeService(DataServiceConfiguration config) { config.SetServiceOperationAccessRule("FooPDF", ServiceOperationRights.All); } [WebGet] [SingleResult] public IQueryable<byte[]> FooPDF() { var result = from p in this.CurrentDataSource.MyPDFs where p.FooID == 2 select p; return result.Take(1).Select(p => p.PDF); } }
What's worse is that I can't add duplicate MimeType attributes to my class.
Google usually solves my problems for me, but this one has me stumped. I have a page with the following code, in which lstPayments is a listview control:
As you can see, I'm trying to get an alert box displayed after a new payment is entered. As I expect, lstPayments_ItemInserted is executed first, and paymentWarning is duly set to true. However, when Page_PreRender subsequently executes, paymentWarning has been re-initialised: it's false again!
The only way I can get the class-level variable paymentWarning to retain it's value between the two event handlers is to declare it static, which I don't want to do for obvious reasons. There must be something I am failing to understand about how class-level variables work in aspx pages.
My current project has many peripheral systems and many different environments (testing, integration, development etc). As expected, we're using .config files to dynamically manage everything.
Instead of updating each relavant key when deploying to an environment, I was hoping there was a way to change 1 key only. Such as:
I've done some searching and haven't come up with an elegant solution. I'm aware that .config files can make use of system variables, but this seems like a bit of a high wire act.
I'm having a hard time understanding why the following code doesn't work. I'm sure it's something remedial that I'm missing or not understanding. I currently have a page that asks for user input. If, based on the input and logged in user, I find data from this page already in the database, I need to update the existing records rather than creating new ones, so I set a class-level bool to true. The problem is, when MyNextButton is clicked, PreviouslySubmitted is still false. So, I'm not sure how to make the value of this variable persist.
public partial class MyForm : System.Web.UI.Page { private bool PreviouslySubmitted; protected void Page_Load(object sender, EventArgs e) { MyButton.Click += (o, i) => { q = from a in db.TableA where (a.SomeField == SomeValue) select a; if(q.Any()) { PreviouslySubmitted = true; //populate the form's fields with values from database for user to revise } } MyNextButton.Click += (o, i) => { //the value of PreviouslySubmitted is false at this point, //even if I made sure it was set to true the previous postback if(PreviouslySubmitted) { //update database } else { //insert into database } }
In page behind classes I am using a private and shared object (list<client> or just client) to temporary hold data coming from database or class library. This object is used temporarily to catch data and than to return, pass to some function or binding acontrol. 1st: Can this approach harm any way ? I couldnt analyse it but a thought was using such shared variables may replace data in it ?2nd: Please comment also on using such variables in BLL (to hold data coming from database) where new object of BLL class will be made everytime.
In page behind classes I am using a private and shared object and variables (list or just client or simplay int id) to temporary hold data coming from database or class library. This object is used temporarily to catch data and than to return, pass to some function or binding a control.1st: Can this approach harm any way ? I couldn't analyze it but a thought was using such shared variables may replace data in it when multiple users may be sending request at a time?
I've just installed MVC 3 and have the following problem. Even if I try to run the sample project, that is included in MVC 3 installation, when I go to the Register form, only the Required attribute causes validation. The Email Format attribute doesn't work,which means I can enter non-email string into the email field and it submits the form without any error messages.
i have a field username which i want to have as a label in the edit.aspx and as a typical textbox in create.aspx . i have applied datannotation class . how would i do that. in the edit mode it is always going model.isvalid ==false . so what i did had a textbox there with the label and hid it . it is working fine now . but is there any clean way this is done in dataannotation
my menu control is bound to a sitemap. I would like to be able to customize the second level of the menu (the dynamic level), so that I can insert an item image, link and text. An example is the top menu in [URL]
Is it possible to achieve using asp.net menu and sitemap ? maybe using the dynamic item template of the menu ?
I'm setting up a web application with multiple forms. Each form is defined within an asp:FormView with the DataSource set to an ObjectDataSource. Each form contains it's own set of fields and always contains one or more blocks of fields, which are the same for multiple forms.
Because this blocks are the same, I decided to define them in a custom usercontrol. The questions that came up with this:
How can I use the same datasource for the input fields in the usercontrol as in the 'higher' asp:FormView?
Is it possible to use DataBinding.Bind() for the input fields in the usercontrol, with this same datasource?
I am attempting to access a textbox control on a master page from a code behind base class but having problems. I have 3 levels of master pages. m1.master is the master page for m2.master which is the master page for m3.master.m3.master has a textbox as shown below
I load css and js files dynamicaly based on which controls are used on particular page. I am doing it by using following code:
[code]....
where AddLinks method adds HtmlLink controls to Page.Header with href attribute set to coresponding css and/or js file.
I would like to add Interface that would force new controls to have AddLinks method but it is impossible since it is a static method. Because my custom controls inherit from Control class I cannot use abstract class and/or virtual methods either. How can I achieve my goal?
Technically I have the Data Annoations working with Linq to SQL classes - the problem is when validation passes. When UpdateModel() tries to do its thing i can an error:The model of type 'MyProject.Models.Employee' could not be updated.What i did was i created a partial class for Employee (that is generated by linq to sql), then stuck a Meta Data class on top of it for the validation
I'd like to inherit all my controllers from a custom base class that I write myself. I can change the line every time I add a new controller, but it would be nicer if I could somewhere specify the default value that gets set there. That way I wouldn't need to worry about forgetting this, and other people who get added to the project later on would have an easier time.
I am using a model but as I want to have clean views I use the viewmodel approach which is like a downsized model which I map in my controller actions before sending to the view or getting it back in a HttpPost attributed action.
My question is: where to put the data annotation attributes. On the viewmodel classes or on the model? If I get it clearly the viewmodel annotations are used for the client side generation of validation right?
Do does that mean I have to put data annotations everywhere on both model and viewmodel?
I use SqlWebEventProvider to log the exceptions to sql server, and it works fine.
I also want to log custom exceptions to aspnet_WebEvent_Events table programmatically. Similar to - [URL]
WebBaseEvent.Raise(new WebErrorEvent("My Error message", null, 5000, e)); I get an error saying "Cannot access constructor 'WebErrorEvent' here due its protection level.
I have a validation attribute that inherits from ValidationAttribute. However, the particular usage of this attribute applies to lists only (IEnumerable really). How can I specify the usage of this property to only be used with items that inherit from IEnumerabe?
I'm building an n-tier application, with the web client and the class library separate. I'm also using the factory pattern of development, using interfaces to act as containers for different objects they are associated with. The problem I'm expreriencing is that I declared a public interface class in the class library and I can create an instance of it in in my aspx pages but whenever I declare it in my custom control code-side, i get an error, like so:
Error 20 The type or namespace name 'IContentMaker' could not be found (are you missing a using directive or an assembly reference?)
notge that I have inherited the class library namespace using the 'using' keyword just in case you are wondering. My code is like so:
using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using TQO_Classes ; //importing the class library project public partial class PageContentMgr : System.Web.UI.UserControl { private IContentMaker _data; //this line throws the error, it works fine on aspx pages
Something is wrong in ASP.NET MVC 2 on client side validation. If I have form for create records in database and all fields are required, validation is triggered only then when I write something in field and delete it. If I go to field, stay this field empty and press Tab key validation isn't triggered.
Here somebody else write about the same problem: [URL]