This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi, When I try to save some Entities through a DD website, I receive a message that a field is required. The field in question is nullable in the database and in the lightspeed model designer and "validate presence" is false. There is a length validation on the field. My intention is that this field is optional but that it has an enforced maximum length if someone does choose to use it. I have stored the same Entity successfully in a seperate piece of code so I thought this might be a problem with the LightSpeed Dynamic Data library. Or maybe I have misunderstood how the DD validation should work? Thanks, Chris
|
|
|
This was indeed a problem with our dynamic data library. We were marking columns as optional only if they were of Nullable<T> type, which of course is never the case for strings. The 24 July nightly build will contain a fix for this. Thanks for your patience with these issues, and please let us know if it still isn't behaving the way you need after the fix. (One issue we have noticed is that this seems to provide less useful feedback in cases where the field *is* mandatory: we would welcome your feedback as to whether this is affecting your users so we can prioritise it.) |
|
|
Hi, I've looked at this fix more closely now and I actually havn't been able to get DD to produce any validation messages for text fields. I've tried all sorts of combinantions of nullable, requirePresence and length validation definitions but the closest I can get to validation is the exception that LightSpeed throws when trying to insert the data to the database. In exploring the DD namespace, I've spotted that the string validation attribute seems to be limited to a "maximum" so I guess you'd need to create a regular expression validation field to represent a string that can be in a range of n - m characters in length? It looks like .NET 4.0 will add built-in support for minimum length validation. I can continue development despite this issue but we will want to demo something approaching a working admin website in a few weeks so it would be great if you can come up with a further fix before then. Thanks, Chris |
|
|
Hi Chris, I'm sorry if I'm being dumb, but I'm not quite sure from your message exactly what you are asking us to do. Is the problem that insertion fails but no message appears (and you want a message to appear)? Is it that you want DD to validate client-side but it's not doing so? Also, I assume the scenario is still that you want the text field to be optional but with a maximum length -- but you also mention minimum-length validation -- is that part of your requirement? We're very happy to provide fixes and enhancements for you, just want to be sure that we're addressing the right problem(s)! |
|
|
No problem Ivan, I'll try to clarify. 1) I want the text field to be optional unless the "validate presence" attribute is true. If possible, other validation attributes shouldn't over-ride that setting. For example, if a "validate length" attribute is used that sets a maximum length, validation should only fail an empty / null string if "validate presence" is true. validation attributes such as URI and e-mail should follow the same rule - validation fails an empty / null string only if "validate presence" is true. Likewise with numerical values - if "validate presence" is false, it shouldn't matter that null falls outside the range of the "validate value" field. (NB: I haven't tested all these possibilities so it's possible that the "validate length" attribute is the only one that needs a bit of improvement). 2) I mentioned the minimum length because I thought that any solution would be better if it could support any of the valid expressions that one can write in the "validate length" attribute. However, I currently only need to enforce maximum lengths, and if (for simplicity or speed) one uses just the StringLengthAttribute, DD 3.5 SP1 supports only maximum lengths so I have no problem if support for minimum lengths is postponed until a later date (maybe LS 3.0 on .NET 4.0?). 3) As I understand it, DD validation on the client side is pretty much a free bonus feature that comes from having the validation on the server side. So yes, at the moment the insertion fails but this failure is simply reported back to the user as an exception message. On the client-side this manifests as a script error (though I suspect it would be a standard ASP .NET server-side error if I disabled all client-side AJAX features). I would like DD to perform the validation rather than waiting until the Save request reaches the LS core. I think this involves setting attributes (e.g. StringLengthAttribute) on the DD meta model that the Mindscape.LightSpeed.Web.DynamicData namespace provides. It would be possible (if tedious) to set these DD attributes in my own code but I really want the validation logic to be attached to the model rather than to a specific front-end application / website. Let me know if I've still not explained something well enough and thanks again for all the improvements you've been making for me - I hope it's not just our project that benefits in the end. Chris |
|
|
1. In the 2.2 RTM, email and URI validation accepted nulls but not String.Empty. In order to support data binding and dynamic data scenarios, we have now added an optional IsRequired flag to both of these validations: if you set this to False then String.Empty will be accepted as valid. Other validations, such as range validation, will also accept null. However it's a bit trickier to support String.Empty on range validation because by the time the value gets to LightSpeed it's already been converted to (say) an integer. In this case, we might need to add some smarts in the dynamic data layer to handle empty string to nullable numeric value conversions -- I'd hope that DD is sensible enough to do this already but I'll investigate. We will have to think about the length validation scenario. If someone specifies a minimum length of 1, then they clearly don't want to allow an empty string; but dynamic data and data binding don't distinguish the null (ValidatePresence) and empty (ValidateLength) cases. A possible workaround for your case would be to create a custom validation attribute that allowed strings that were empty, but I realise this would be inconvenient. 2. Thanks for the clarification. We'll try to get you something that handles minimum lengths if we can do so without too much trouble, otherwise we'll pend it in the interests of ensuring that you get the more important max-length validation. 3. We already set MaxLength on the DD metamodel (the ColumnProvider): this works but doesn't provide helpful error messages. Emitting the DataAnnotations-style attributes is a bit trickier. We can't emit them in our generated code because not all projects will reference the required DLL. I will have a dig around with ContextConfiguration.MetadataProviderFactory and see if we can inject the DataAnnotations stuff that way. I will try to do it in a way that doesn't clash with your use of the DD Futures InMemoryMetadataManager but there may be a bit of trial and error involved! Thanks very much for the helpful feedback and we'll try to get this stuff to you over the next few days. |
|
|
Hello Chris, Nightly builds dated 4 August and above, available from about 1430 GMT, will include support for DataAnnotations validations, which will get you the client-side validation experience you're looking for. In order to obtain this you will need to specify a MetadataProviderFactory when creating the ContextConfiguration, using the new EntityDataAnnotationProvider class: model.RegisterContext( If you also want to customise the types using metadata classes or the Futures in-memory metadata manager, you can pass an "inner provider" to the EDAP constructor: MetadataProviderFactory = t => new EntityDataAnnotationProvider( At present the EDAP supports the following LightSpeed validations: ValidatePresence We emit DD validation attributes for ValidateEmailAddress and ValidateUri but Dynamic Data does not process these (they always return IsValid = true). This is a Dynamic Data issue. We can look at creating custom DataAnnotations attributes for these and for ValidateComparison if required. We will probably not be able to map ValidateUnique because that really does depend on the LightSpeed infrastructure for checking the database. We don't yet provide a way to map custom LightSpeed validation attributes to DataAnnotations validation attributes. Let us know if this is something that would be relevant to you. We have not yet addressed #1 except as noted above, so you may still see empty fields being rejected because of another validation even when ValidatePresence is not applied. As always we welcome feedback and bug reports, and we appreciate your patience and help in improving this part of the product. |
|
|
Hi, Thanks for working on those improvements. Unfortunately, I've not really been able to test them in much detail because LightSpeed throws an exception whenever I put a length validation on a property. For example, a test Entity with one property will throw the following exception if a length validation of "<= 255" is set on that property: [FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.] System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args) +7483117 System.String.Format(IFormatProvider provider, String format, Object[] args) +107 Mindscape.LightSpeed.Web.DynamicData.<ToDataAnnotation>d__1.MoveNext() +315 System.Linq.<SelectManyIterator>d__14`2.MoveNext() +273 System.Linq.Buffer`1..ctor(IEnumerable`1 source) +259 System.Linq.Enumerable.ToArray(IEnumerable`1 source) +81 Mindscape.LightSpeed.Web.DynamicData.DataAnnotationBuilder.GetAnnotationAttributes() +132 Mindscape.LightSpeed.Web.DynamicData.EntityDataAnnotationTypeDescriptor.GetProperties() +154 System.Web.DynamicData.MetaColumn.get_PropertyDescriptor() +34 System.Web.DynamicData.MetaColumn.get_Attributes() +27 Microsoft.Web.DynamicData.AdvancedFilterRepeater.IsFilterableColumn(MetaColumn column) in C:\Visual Studio Projects\Wildscreen Warehouse\Libraries\DynamicDataFutures0716\DynamicData\Futures\Controls\AdvancedFilterRepeater.cs:19 Microsoft.Web.DynamicData.AdvancedFilterRepeater.<GetFilteredColumns>b__0(MetaColumn c) in C:\Visual Studio Projects\Wildscreen Warehouse\Libraries\DynamicDataFutures0716\DynamicData\Futures\Controls\AdvancedFilterRepeater.cs:11 System.Linq.WhereEnumerableIterator`1.MoveNext() +161 System.Linq.Buffer`1..ctor(IEnumerable`1 source) +259 System.Linq.<GetEnumerator>d__0.MoveNext() +108 System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) +347 System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) +51 System.Web.UI.WebControls.Repeater.DataBind() +75 System.Web.DynamicData.FilterRepeater.DataBind() +22 System.Web.DynamicData.FilterRepeater.Page_InitComplete(Object sender, EventArgs e) +37 System.EventHandler.Invoke(Object sender, EventArgs e) +0 System.Web.UI.Page.OnInitComplete(EventArgs e) +8698006 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +467 I'm out of the office for a couple of days now but if you come up with any further improvements in the mean time then I'll try to give all of this area a more thorough test on Monday. Thanks, Chris |
|
|
Thanks. This will be fixed in the next nightly build. |
|
|
Yep, it works now. Thanks! One possible improvement could be with the validation range of integer values. By default, DD will prevent any value higher than int.MaxValue but it would be nice if the EntityDataAnnotationProvider could automatically reduce this maximum limit if the underlying data model specifies a type with a smaller range. For example, I have a byte property and while DD accepts values higher than 255, this just leads to an exception thrown from LightSpeed because the value exceeds the type's maximum value. I can add DD validation attributes manually in the appropriate places but it seems like something that could be automatically handled by LightSpeed. Thanks, Chris |
|
|
I'm a bit wary of this because it seems to be that it should be handled within Dynamic Data. After all, DD has access to the type information -- it knows that the property is a byte rather than an int -- we shouldn't need to provide additional metadata to tell it what the range of that type is. This isn't an issue that's specific to LightSpeed. This may seem like evasion, but we prefer not to incur the complexity of working around issues in other frameworks unless we really have to *grin*. (The feature isn't trivial because a short property might or might not have explicit validations that would interact with the type-inferred validation.) I'm open to discussion on this one, but at the moment I'd suggest that you either: (a) add explicit LightSpeed range validations to your short integer properties (so that EDAP can translate these); or (b) compose in a TypeDescriptionProvider of your own, which emits RangeAttribute on sub-32-bit integer types. Also probably worth filing a bug on Connect or getting in touch with the Dynamic Data team to ask what their plans (or recommended solutions) are for making this happen at the DD level. And as I say, if you feel strongly that this is something LightSpeed should be doing, I'm open to being persuaded! |
|
|
Thanks for the reply Ivan. I think that if it's not trivial and given your valid point about working around issues in other frameworks then I'm happy to just go with option (a). This will be fine for now but if I get time after this project is complete then I will get in touch with the DD team as you suggest. If you contact them in the mean time then please just point me at the discussion or bug listing in case there's anything I can add and so I can follow it. Thanks, Chris |
|