asp.net MVC3 DefaultModelBinder error messages keys - asp.net

There's a lot of question (and answer) here on stackoverflow and other site about translating the default error messages provided by the DefaultModelBinder, such as this one or this one.
All answers to these questions basically proprose to create a ressource (resx) file under App_GlobalResources and put a message for "PropertyValueInvalid".
That's fine, it does works, but there is other message also (ex. "The value xxx must be a number") and the big question is : where in hell can I have a list of the messages key used for model binding validation, with a description of the context they are used for so I can translate each of them ?

When DefaultModelBinder.ResourceClassKey = "ResourceFileName"; is set in Application_Start method the DefaultModelBinder class uses other resource keys than defined in the resource file used by Asp.Net MVC.
While disassembling DefaultModelBinder there is a method GetUserResourceString that reads from the custom resource file. This functions is only called twice with these messages keys:
PropertyValueRequired (A value is required.)
PropertyValueInvalid (The value '{0}' is not valid for {1}.)
These are the only messages that could be set for DefaultModelBinder in MVC3.

Related

API Platform custom IRI with value objects

I am currently trying to create a custom IRI for one of my entities in API Platform.
I know there is page in the documentation describing how to use a custom IRI (https://api-platform.com/docs/core/identifiers/), but I can't get it working.
My entity uses a value object for the id (currently used for IRI) and also for the name (should be used for IRI). But the values themself are priviate and scalar in the entity.
API Platform seems to get the information what should be used as the identifier, from my XML Doctrine mapping. I already tried to overwrite it by usung annotations, attributues and YAML definitions. Without luck.
The returned error reads:
preg_match(): Argument #2 ($subject) must be of type string
(at this point it receives the value object instead of the actual value)
best regards,
spigandromeda
I solved my problem.
To explain the solution, I have to dig a little into API Platform response generation.
API platform generates an IRI for every entity it returns (colelction and item operation)
it's using the Symfony router go generate the URI
all the necessary information can draw API Platform from different sources (YAML, XML, annotations, attributes)
the information include the identifier(s) defined for the entities resource
API Platform gets the value for the identifier via Symfony property accessor
because the property accessor is using getters before accessing private properties via reflection, it will return the VO
an ordinary VO cannot be used by the Symfony URL generator to create the URL
As I explained, I am using a VO for my Id as well. So I tried to figure out why it was working with the Id VO but not with the name VO.
Simple answer: the Id VO implemented the __toString method and the name VO didn't. So the solution was to let the name VO implement this method as well.
It was interesing to dig into the internal process of API Platform, but I also feel a little stupid :D

API-PLATFORM - model with object serialized to string at endpoint

I faced the problem with generating React components with api-platform-generate-crud.
Model has property that is object email.
I have serializer that make my email object a string.
API endpoint is serving string.
It works for GET & POST.
When I try to generate React components error message is
TypeError: Cannot read property '0' of undefined
Looking deeper into it, looks like that generator still see my email as object not a string.
Any idea how I can force API to 'see' email property as string not object ?
The data model you define is authoritative. Types in the Hydra documentation reflect the ones in PHP classes.
Here, the email property is of type object. If you set the related data as a string somewhere, you don't respect this contract anymore. The Hydra documentation is not in sync with the returned data.
You can change the type of the email property in the Hydra documentation by decorating the api_platform.hydra.normalizer.documentation service.
But I would recommend to keep the PHP classes' structure of your entities as close as possible of the structure exposed through the API.
Your classes should reflect the output of the API. You can use custom data providers to deal with more complex data structure (ex: ORM entities) before hydrating the structure to expose.

How do I specify an asp.net mvc 5 resource file in a VB Class Data Annotation?

VS 2013, MVC 5, VB, Entity Framework
This is part of my Class:
Public Class Order
....
Private mFirstName As String
<Required(ErrorMessage:="First name required - hard coded")>
Public Property FirstName() As String
Get
Return mFirstName
End Get
Set(ByVal value As String)
mFirstName = value
End Set
End Property
....
I want to setup a resource file to allow error messages to change with different countries. What would I write to have the error message pulled from a resource file named ErrorMessages.resx?
The examples for doing this are mostly in C#, and finding the VB equivalent was difficult, at least for me, and I thought other VB programmers might appreciate the proper syntax.
The C# answer is:
[Required(ErrorMessageResourceType=typeof(ErrorMessages),ErrorMessageResourceName="FirstNameRequired")]
What was difficult was to find the proper VB operator to apply for the C# "typeof" operator. In VB the line above is:
<Required(ErrorMessageResourceName:="FirstNameRequired", ErrorMessageResourceType:=GetType(Resources.ErrorMessages))>
in the lines above, the Name/Value pairs are stored in ErrorMessages.resx (see how to create below), and "FirstNameRequired" is the Name of the string that will hold the actual text to be displayed.
Just to cover the bases:
What's pretty neat is that VS2013 automatically creates the Class and type definitions for the resource file and they show up in Intellisense, as in the VB line above 'Resources.ErrorMessages'.
It's also important to note the Data Annotation operators can have only one or the other of the two error message string properties, so the property "ErrorMessage" had to be removed as seen in the code lines in this answer post.
To use a Global Resource file (local files are possible), on the project node do an Add > Add ASP.NET Folder > Add App_GlobalResources. Then inside that folder Add > New Item > Resources File. After that the Name-Value pairs can be added, and then later additional country-culture resource files can be added, and online documentation for this process is fairly plentiful. ASP.NET, and MSDN for the country-culture.
The MSDN page that lists all of the data annotations is here; But I didn't find enough code samples to readily explain how to take advantage of the properties listed.
Hope this is helpful for someone else.
Best Regards,
Alan

When calling ScriptManager.RegisterStartupScript, what is the point of the 'Type' parameter?

A minor question that I hope admits of a simple answer that I'll kick myself for not noticing.
So, when we have the following overload of RegisterStartupScript
public static void RegisterStartupScript(
Control control,
Type type,
string key,
string script,
bool addScriptTags
)
we have to provide a type as well as a control. Now, I can see what the point of specifying the control - the script gets pushed out just in case the control is part of the partial page render. But what is the point of the Type parameter? Usually one just sets it to the type of the control. And this is in fact the suggestion made by MSDN:
control
Type: System.Web.UI..::.Control
The control that is registering the client script block.
type
Type: System..::.Type
The type of the client script block. This parameter is usually specified by using the typeof operator (C#) or the GetType operator (Visual Basic) to retrieve the type of the control that is registering the script.
So why do we have to specify it? Presumably not just to spare the .Net Framework the bother of retrieving the runtime type itself.
Usually type is the type of the page or control that registers a script. This is just a way to prevent that two different controls register different scripts using the same key.
Excerpt from MSDN:
A client script is uniquely identified
by its key and its type. Scripts with
the same key and type are considered
duplicates. Only one script with a
given type and key pair can be
registered with the page. Attempting
to register a script that is already
registered does not create a duplicate
of the script.

How to Integrate Enterprise Library Validation Application Block ValidationResults between WCF and ASP.NET?

Enterprise Library Validation Application Block (VAB) integrates with ASP.NET and also with WCF.
Is there a way to integrate ValidationResults created in WCF with ASP.NET?
e.g. an ASP.NET web page invokes a WCF service. The WCF service validates the data using VAB and returns validation information via a FaultContract. The ASP.NET page can take the results and display some error messages. However, a common approach is to indicate which fields have errors (e.g. inline message or asterisk). It seems that most of these approaches will involve being able to correlate the validation result with a control or with a validator.
I don't think there is an out of the box solution but was also curious if anyone had done this and what their approach was.
Since there is no out of the box solution and there aren't any answers posted, I will share what I implemented. I'm not in love with the approach but it is working for me.
Overview
The basic approach is for the ASP.NET page to populate a mapping between properties on the DataContract objects to the ClientId of the control that is being validated. When a validation error occurs the ClientId is returned back from the service to the asp.net page as part of a FaultContract. Then the details from the FaultException are extracted; the ASP.NET page retrieves the ClientId of the control that caused the error and appropriate action can be taken (e.g. change control look and feel or set the text on a validator).
Details
All of the DataContract objects inherit from a base class that exposes a Dictionary. This dictionary is used to map object properties to ASP.NET controls. In the Dictionary, the key is the property name on the DataContract object and the value is the ClientId of the control. Before invoking a service, the client must attach the Dictionary to the DataContract object.
When a ValidationResult is created by Enterprise Library it contains a property called Target which is the object that was validated. ValidationResult also contains a property called key which is the name of the property from the target object that was validated. The ValidationResult key is also a key into the Dictionary that was set in the ASP.NET page before calling the service.
With the ValidationResult key, the ASP.NET supplied information (ClientId) can be extracted from the ValidationResult Target. The information is then added as the Tag of the ValidationResult. Unfortunately, Tag is a readonly property so it has to be set by creating a new ValidationResult and passing the tag to the constructor.
The collection of ValidationResults is then transformed to a pre-existing CustomValidationResults collection (which looks just like ValidationResult) that we needed to use. The CustomValidationResults are then added to a custom ValidationFault and a FaultException is thrown.
The ValidationFaults are then extracted from the FaultException in the ASP.NET page. The ValidationFault contains the ClientId of the control which is associated with the error so the page can choose to display the Messages as it sees fit.

Resources