ASP.NET MVC HtmlHelper gooit CustomAttributeFormatException

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Ik ben bezig met een privé applicatie, voor mijzelf waarbij ik ASP.NET MVC 2 gebruik in combinatie met het Entities Framework en .NET 3.5. Het leuke van het entities framework is dat het makkelijk en snel te gebruiken is. Dat geldt eveneens voor MVC met z'n strong typed HTML helpers.

Nu heb ik voor een registratiepagina een viewmodel gemaakt, die onder andere een User bevat. Op deze manier zou je een bijbehorende tekstbox ervoor moeten krijgen:
C#:
1
Html.TextBoxFor(model => model.User.Username)

Dat werkt dus in theorie, maar in de praktijk blijk het anders uit te pakken. Iedere HTML helper die ik op die manier gebruik gooit ergens in de method chain een CustomAttributeFormatException op.

Omdat ik de standaard designer in Visual Studio gebruik voor het genereren van de classes die bij het datamodel horen, gebruik ik de MetadataType attribuut om het validatieclass voor mijn User class kenbaar te maken:
C#:
1
2
    [MetadataType(typeof(UserValidation))]
    public partial class User { ... }


Nu wordt deze exception opgegooid:
[small]System.Reflection.CustomAttributeFormatException was unhandled by user code
  Message=De opgegeven eigenschap ErrorMessage is niet gevonden.
  Source=mscorlib
  StackTrace:
       bij System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
       bij System.Reflection.CustomAttribute.GetCustomAttributes(RuntimePropertyInfo property, RuntimeType caType)
       bij System.Reflection.RuntimePropertyInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
       bij System.Attribute.InternalGetCustomAttributes(PropertyInfo element, Type type, Boolean inherit)
       bij System.Attribute.GetCustomAttributes(MemberInfo element, Boolean inherit)
       bij System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptor.TypeDescriptorCache.GetAssociatedMetadata(Type type, String memberName)
       bij System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptor.GetPropertiesWithMetadata(PropertyDescriptorCollection originalCollection)
       bij System.Web.Mvc.TypeDescriptorHelper._AssociatedMetadataTypeTypeDescriptor.GetProperties()
       bij System.Web.Mvc.AssociatedMetadataProvider.GetMetadataForProperty(Func`1 modelAccessor, Type containerType, String propertyName)
       bij System.Web.Mvc.ModelMetadata.GetMetadataFromProvider(Func`1 modelAccessor, Type modelType, String propertyName, Type containerType)
       bij System.Web.Mvc.ModelMetadata.FromLambdaExpression[TParameter,TValue](Expression`1 expression, ViewDataDictionary`1 viewData)
       bij System.Web.Mvc.Html.ValidationExtensions.ValidationMessageFor[TModel,TProperty](HtmlHelper`1 htmlHelper, Expression`1 expression, String validationMessage, IDictionary`2 htmlAttributes)
       bij System.Web.Mvc.Html.ValidationExtensions.ValidationMessageFor[TModel,TProperty](HtmlHelper`1 htmlHelper, Expression`1 expression)
       bij ASP.views_account_register_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in m:\Developing\Visual Studio\Projects\DevDammann.nl\DevDammann.nl\Views\Account\Register.aspx:regel 23
       bij System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       bij System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
       bij System.Web.UI.Control.Render(HtmlTextWriter writer)
       bij System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
       bij ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in m:\Developing\Visual Studio\Projects\DevDammann.nl\DevDammann.nl\Views\Shared\Site.Master:regel 47
       bij System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       bij System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
       bij System.Web.UI.Control.Render(HtmlTextWriter writer)
       bij System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
       bij System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       bij System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
       bij System.Web.UI.Page.Render(HtmlTextWriter writer)
       bij System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
       bij System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
       bij System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
       bij System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
  InnerException: System.Reflection.TargetInvocationException
       Message=Het doel van een aanroep heeft een uitzondering veroorzaakt.
       Source=mscorlib
       StackTrace:
            bij System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
            bij System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
            bij System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
            bij System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
       InnerException: System.InvalidOperationException
            Message=Deze eigenschap kan niet worden ingesteld omdat het kenmerk zich in de modus voor bronfoutberichten bevindt.
            Source=System.ComponentModel.DataAnnotations
            StackTrace:
                 bij System.ComponentModel.DataAnnotations.ValidationAttribute.set_ErrorMessage(String value)
            InnerException: 
[/small]


Ik heb al bepaald
  • De htmlhelpers kan om één of andere reden niet met mijn viewmodel omgaan
    Door simpelweg de User als een lokale variabele te refereren is dit uitgesloten.
  • De attributen in de metadataclass zorgen voor problemen
    Door deze te commenten is dit uitgesloten.
  • Username is null zorgt voor problemen
    Door de username op een random string te zetten is dit uitgesloten.
Ik denk dat ik heb bepaald:
De gegenereerde entity class zorgt voor problemen
Als ik een nieuwe instantie van de UserValidation class aanmaak en als volgt injecteer in de Textbox gaat het goed:
C#:
1
2
var u = new UserValidation() {Username = String.Empty};
Html.TextBoxFor(model => u.Username)

Er is geen exception.

De gegenereerde code van het Entity Framework:
C#:
1
2
3
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
[global::System.CodeDom.Compiler.GeneratedCode("System.Data.Entity.Design.EntityClassGenerator", "4.0.0.0")]


Ik wilde eigenlijk nog gaan proberen om xVal te gebruiken, maar dat lost het probleem niet op omdat het op een heel ander niveau ligt. Dit lijkt gewoon met de HTML helper te maken te hebben.

Uiteraard heb ik ook op Google gezocht maar er is niemand die iets relevants heeft gehad blijkbaar. Ik of mijn code moet bijna wel de fout zijn. MVC2 mag dan wel jong zijn maar is uitgebreid getest, dus dit zal dan aan het licht zijn gekomen.

Is er toevallig iemand met suggesties of ervaring?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
ErrorMessage is niet gevonden...
misschien toevoegen aan je viemodel?
C#:
1
[StringLength(5, ErrorMessage = "dl3b")] 

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Bedankt voor je suggestie, maar nee. Dit werkt niet.
Dit verbaast mij ook niet want:
De htmlhelpers kan om één of andere reden niet met mijn viewmodel omgaan
Door simpelweg de User als een lokale variabele te refereren is dit uitgesloten.
En ondertussen heb ik dat ook voor de tweede keer uitgesloten aangezien ik in de loginpagina gewoon een ander ViewModel gebruik met Username en Password als strings, en zonder attributen. Dus dat is het probleem niet.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Is er toevallig nog iemand met ideeën?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Een updateje, volgens een ASP.NET teamlid komt het doordat de gegenereerde classes horen bij het Entity Framework 4 dat met .NET 4 released werd. Omdat ik mijn project niet retargeted hebt, zou dit niet mogen voorkomen. Er gaan nu een paar mensen naar kijken.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 29-05 12:10

jvaneijk

Dr.Oak

Misschien nog even een stomme vraag Maar ASP.net MVC werkt toch alleen op .net 4.0?

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Nee, ASP.NET MVC en MVC 2 werken vanaf .NET 3.5.

Wat betreft een update op mijn probleem: Ik ben teruggedraait naar het good old Linq2Sql maar het probleem blijft. Hoe kan het dat nooit iemand hier tegenaan loopt? Heeft iemand suggesties, hoe stom ze ook kunnen zijn?

Ik overweeg om terug naar MVC 1 te gaan, heeft iemand suggesties hoe ik dit het beste kan doen?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • __Stef__
  • Registratie: Mei 2010
  • Laatst online: 15-09 20:19
Een korte vraag : wil je een DataModel entity (User) gebruiken in de View ?

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Ja, maar verpakt in een ViewModel. De User is een eigen entity, niet een MembershipUser zoals van ASP.NET

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 20:40
Ik heb (bijna) zelfde probleem gehad... Hernoem de klasse eens ;)

Even niets...


Acties:
  • 0 Henk 'm!

  • __Stef__
  • Registratie: Mei 2010
  • Laatst online: 15-09 20:19
Sebazzz schreef op woensdag 05 mei 2010 @ 18:37:
Ja, maar verpakt in een ViewModel. De User is een eigen entity, niet een MembershipUser zoals van ASP.NET
Als je een User entity class 'verpakt' in een ViewModel, is het nog steeds een entity class.
Een beter pattern&practice is om ook voor deze User entity class een User ViewModel class te maken, dus helemaal los van elkaar.

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Hernoemen naar BlaatBlaat loste het probleem niet op :(
Een beter pattern&practice is om ook voor deze User entity class een User ViewModel class te maken, dus helemaal los van elkaar.
Bron? Ik zie geen reden om dat te doen. Dat is niet bepaald DRY, en waarom zou je geen model aan je view mogen geven? Het is zowieso de oorzaak van het probleem niet, in MVC1 werkte zoiets gewoon (op de strong-typed html helper na dan).

[ Voor 77% gewijzigd door Sebazzz op 05-05-2010 19:17 ]

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • biomass
  • Registratie: Augustus 2004
  • Laatst online: 18:38
FireDrunk schreef op woensdag 05 mei 2010 @ 18:45:
Ik heb (bijna) zelfde probleem gehad... Hernoem de klasse eens ;)
"De opgegeven eigenschap" "is niet gevonden" en "InnerException: System.Reflection.TargetInvocationException" wijzen inderdaad sterk naar dat de compiler er een User klasse bijhaalt die de verplichte interfaces voor het UserInterface object niet implementeert; om het vervolgens op te geven.

Ik zie dat je dat geprobeerd hebt, mis je zelf geen interface implementaties?

[ Voor 7% gewijzigd door biomass op 05-05-2010 19:27 . Reden: BlaatBlaat klasse ]


Acties:
  • 0 Henk 'm!

  • __Stef__
  • Registratie: Mei 2010
  • Laatst online: 15-09 20:19
Punt 7:

http://codeclimber.net.nz...t-mvc-best-practices.aspx

Model’s Best Practices
7 – DomainModel != ViewModel

The DomainModel represents the domain, while the ViewModel is designed around the needs of the View, and these two worlds might be (and usually are) different. Furthermore the DomainModel is data plus behaviours, is hierarchical and is made of complex types, while the ViewModel is just a DTO, flat, and made of strings. To remove the tedious and error-prone object-mapping code, you can use AutoMapper. For a nice overview of the various options I recommend you read: ASP.NET MVC View Model Patterns.

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42
Ik twijfel aan die blogpost, die man wil ook alle HTML helpers in de ban doen. Er is geen reden om geen HTML helpers te gebruiken, aangezien je van een makkelijke syntax terug gaat naar boilerplate HTML schrijven, vind ik.
Daarnaast blijft het een best practice, geen requirement. Het verklaart nog steeds niet waarom die fout uberhaupt voorkomt.
Ik zie dat je dat geprobeerd hebt, mis je zelf geen interface implementaties?
Het zou toch niet compileren anders?

edit: Het blijkt dat als ik mijn project retarget naar .NET 4 alles correct werkt! :o

[ Voor 8% gewijzigd door Sebazzz op 05-05-2010 21:02 ]

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]

Pagina: 1