Overriding ModelBindingMessageProvider error messages - asp.net-core

I have a .net core 2.2 webapi. There is a POST action that accepts a model. The model has a Guid as one of the properties. When I post this model but supply a string and not a Guid, I get a ModelState.IsValid = false, which is correct. The default model binding error message is "Error converting value \"string\" to type 'System.Guid'. Path 'memberId', line 3, position 22." This is not a friendly message that I want to return, also, this message needs to get localized to user's language. All the resources that I have read said I need to set the accessor for ModelBindingMessageProvider in the AddMvC() options. i.e.
services.AddMvc(options => options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => "blah blac");
I have set ALL of the accessors on there and it still doesn't change the default message. Anyone knows how to set those default values?

The issue is that the InputFormatter is throwing exception and the exception message is used for the modelstate entry. You can disable this in services.AddMvc().AddJsonOptions(options => options.AllowInputFormatterExceptionMessages = false;). This will add an empty string for the error message, which you can detect and then just display a generic message to user. I have not found a better way of doing this but this method will suffice for now.

Related

Error when checking for custom claims property on rules auth token

I receive an error in the emulator when I try to check for a custom claim field that does not exist on the request.auth.token object when checking storage.rules. The request fails which is correct if the property is missing but I am concerned about the error.
function isPlatformVerified() {
return request.auth.token.platformVerified == 'ok';
}
and this is the error shown in the emulator:
com.google.firebase.rules.runtime.common.EvaluationException: Error: /Users/marcel/git/dev/storage.rules line [68], column [14]. Property platformVerified is undefined on object.
I wish to check if the custom claims has this property and if it has that it contains the correct value. How do I do this without getting an error (or can I ignore this??)
Many thanks
Most likely the custom claim hasn't propagated to the client and rules yet.
Custom claims are part of the token that the client sends with its requests, and that token is only auto-refreshed once per hour. So it may take up to an hour before a new claim shows up in the client, and thus in the security rules.
You can force a refresh of the ID token on the client by calling user.reload(), to ensure that the new claims will be present before the auto-refresh.

Override default JsonSerializer on serialize exception

Is it possible, to override default Net.Core JsonSerializer or catch Exception on serialize?
Actually, when i pass wrong field type to model, required in controler(for example property is type of string i will pass int) then response look like this
{
"status": 400,
"message": "Validation error",
"data": [ {
"filedName": "$.Username",
"validateErrors": ["The JSON value could not be converted to System.String. Path: $.Username | LineNumber: 0 | BytePositionInLine: 16."]
}]
}
when i print this message to user, he won't know what i'm talking about. I need to ovveride this message for "Value is incorrect. Required [type]"
I have custom Provider which implement IValidationMetadataProvider to customize response on model validation error, but those error is not catching there.
You have three options
Catch the Json exception in server middleware, interrogate it, and then convert it to something more succint for the client. Search up "app.UseMiddleware<>()".
Inspect the status code of the HttpResponse message on the client, interrogate it, and then convert it to something more succinct for the UI.
Perform rudimentary format / variable type validations on the client before sending to the controller / API.
I would recommend approach 3. The API has presented a contract to you for the payload. The least the client / UI can do is make sure it complies with the contract. Failures due to business logic / rules definitely do belong on the server.

Getting access to the message body when handling errors in NServiceBus Version 3

I'm currently handing off exceptions to a third party telemetry tracking service (Raygun). One of the details I want to include in those exception logs is the actual contents of the message, ideally serialized to JSON.
I'm handling this at the end of the MessageHandler. I'm aware that I could also use the IManageMessageFailures interface, but then I lose the benefits of the second level retries.
I'm currently doing this:
public void End(Exception e)
{
// get the current message context
var context = this.Bus.CurrentMessageContext;
// now where do I get the body of the message from?
this.ExceptionLogger(new Log(e, context.WhereAreYouMessage.SerializedAsString()));
}
This is NSB 3.3. I notice that I can cast the CurrentMessageContext to NServiceBus.Unicast.MessageContext, but the TransportMessage property which contains the message Body is private.
How can I get a copy of the message that caused the exception?
This is not supported in version 3.
You can look in your error queue which will have the exception details correlated with the message body http://docs.particular.net/nservicebus/errors/#configure-your-error-queue

How to use validation_messages and display_exceptions in Apigility?

From the Apigility documentation (Error Reporting):
The API Problem specification allows you to compose any other additional fields that you feel would help further clarify the problem and why it occurred. Apigility uses this fact to provide more information in several ways:
Validation error messages are reported via a validation_messages key.
When the display_exceptions view configuration setting is enabled, stack traces are included via trace and exception_stack properties.
I don't understand this part of the docu. What is the purpose and how to use the settings validation_messages and display_exceptions?
The display_exceptions setting is from ZF2's view manager (see docs here). Turning this on will cause Apigiltiy to include a stack trace with any error response.
In Apigility itself the validation_messages key population is handled automatically. You configure an input filter which validates the incoming data payload and if the input filter fails the error messages it returns are automatically injected into the API response under the validation_messages key. This functionality is provided by the module zf-content-validation. You can "do it yourself" by returning an ApiProblemResponse from your resource like so:
return new ApiProblemResponse(
new ApiProblem(422, 'Failed Validation', null, null, array(
'validation_messages' => [ /* array of messages */ ]
))
);

NHibernate.Validator: when saving entity, my custom messages aren't available, how can I get them?

I'm using NHibernate.Validator with the Loquacious ValidationDef configuration style.
For all my rules I use WithMessage to set a custom message when the value is invalid. The messages are codes that I use to lookup the correct message to display, depending on context and language.
I can get these messages when calling ValidatorEngine.Validate(entity), but when saving an entity with NHibernate, I get an InvalidStateException with no details on why it's invalid.
So, how can I get to my validation messages after catching an InvalidStateException thrown during an NHibernate save?
The messages are in the exception, only a method call away. You need to call GetInvalidValues() on the exception.
try
{
// Flush NHibernate to invoke event listeners
}
catch (InvalidStateException invalidStateException)
{
InvalidValue[] invalidValues = invalidStateException.GetInvalidValues();
Console.WriteLine(string.Join<InvalidValue>("\n", invalidValues));
}
The reason they did not put it directly into Message of the exception, is probably because there can be multiple validation results.