.Net 6 is requiring all non-nullable fields when I try to deserialize JSON - serialization

I'm converting an app from .Net standard to .Net 6, but my controllers are throwing errors if I don't pass in all non-nullable fields. e.g.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string CustomerType { get; set; }
}
When I try to pass that object to an action without one of the fields, it throws an error like "The FirstName field is required." How can I get around that? I'm using NewtonSoft via the startup file like this:
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.UseMemberCasing();
});
builder.Services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
options.UseMemberCasing();
});

the easiest way is to open a project configuratuon file (just click on project name in a VS solution explorer) and remove option nullable
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable> <!-- change from enable or remove -->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
or if you want to dissable nullabel check only in the controllers actions, you can try another option
builder.Services.AddControllers(
options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);

Related

Simply Change culture for [Required] data annotation validation message in .net Core 6.0

What I'm trying to do seems really simple but I'm struggling with it since this morning...
I just want to force French language for html.ValidationMessageFor(x=>x.Name)
Here my name property :
[Required]
public string Name { get; set; }
Right now, if I try to validate a form without filling the property I've got the "The Name field is required."
Where does this message "The {0} is required." come from ?
How can I change the language of it without having to override all my [Required] properties in all my ViewModels with something like :
[Required(ErrorMessageResourceName ="Required",ErrorMessageResourceType =typeof(FrenchDataAnnotation))]
Thanks a lot.
You can create a custom validation attribute that implements the default Required attribute and use it for validation:
public sealed class ExRequiredAttribute : RequiredAttribute
{
public ExRequiredAttribute() : base()
{
this.ErrorMessage = "my custom error message...!"
}
}
Then use it like:
[ExRequired]
public string Name { get; set; }
Another solution is to use third party localization nuget like XLocalizer which overrides all default data annotations, ModelBinding and IdentityErrors.

Automapper unmaped property found

Hi guys I have found a very strange thing and I want to ask you about that.
I am using AutoMaper in my .dotnet core Web Api project. And during mapping i get the AutoMapperConfigurationException.
Here is a reference I am currently using:
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="5.0.1" />
I have a Blog entity class :
public class BlogEntity
{
public string Title { get; set; }
public int BlogEntityId { get; set; }
public List<Post> Posts { get; set; }
}
And my DTO class which I am using to create a new blank blog entity:
public class BlogCreateDto
{
public string Title { get; set; }
}
Here is my mapper profile:
public class BlogMappingProfile : Profile
{
public BlogMappingProfile()
{
CreateMap<BlogCreateDto,BlogEntity>();
}
}
Here is a line that i used in Startup.cs to set up automapper
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAutoMapper();
....
Here is a message that i get in exception:
Unmapped members were found. Review the types and members below.\nAdd
a custom mapping expression, ignore, add a custom resolver, or modify
the source/destination type\nFor no matching constructor, add a no-arg
ctor, add optional arguments, or map all of the constructor
parameters\n==========================================================\r\nAutoMapper created this type map for you, but your types cannot be mapped using
the current configuration.
I tried a lot of things, Ignore of members, constructors, inheritance etc and none of them didn't work. I resolved it by adding configuration in Startup.cs and adding my automapper profile by hand like this:
services.AddAutoMapper(cfg => cfg.AddProfile(new BlogMappingProfile()));
It is working but still i have a confusion about that i miss something and didn't do it in properly way. What I am doing wrong ? Or maybe I miss something in configuration?
You have to provide the assemblies or the assembly, where your profiles are located. The extension is using assembly-scanning to find given types to register. If your profiles are in the same project as your startup class, you can do the following
services.AddAutoMapper(typeof(Startup).Assembly);
You will also need that to automatically register all other AutoMapper types like IValueResolver<,,> and ITypeConverter<,> for instance.
You can find the registration process of that extension here.
In my case, I've forgotten to add the Profile file into the AutoMapperConfig class
something like this
public static void Configure(MapperConfigurationExpression config)
{
config.AddProfile<SettingsProfile>();
}

How to bind nullable decimal values

I'm having problems with ASP.NET Core MVC and decimal? value.
I have the following view model:
public class BlobViewModel
{
public int Id { get; set; }
public int? IntegerValue { get; set; }
public string StringValue { get; set; }
[DataType(DataType.Date)]
public DateTime? DateValue { get; set; }
public decimal? DecimalValue { get; set; }
}
And the following input element in my view
<input asp-for="DecimalValue" class="form-control" />
When I enter a decimal value, e.g. "68.5" or "68,5" and tab out of the input element, I get the following error:
The value '68.5' is not valid for DecimalValue.
I have tried with the [DataType(DataType.Currency)] attribute above the property, but I can't seem to get the binding to work. The other properties binds as expected.
Does anyone have an idea for how I accomplish this?
The error you get occurs if you local Windows settings isn't set to US localization and you are using the default asp.net template jquery validation to validate decimal values. The errors should occur irrespective if your decimals are nullable or not
In ASP.NET Core I don't think you can force the localization to US in the web.config as you get in this answer in the same way you can for ASP.NET MVC5 and earlier, so you will have to add javascript to override the jquery.validate.js as mentioned as an answer to the same question.
create a js file called validationlocalization and put it in your wwwroot\js folder with the following contents
$.validator.methods.range = function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
In the cshtml pages that require decimal validation add a reference to the javascript file to your scripts section. Make sure it is added after an reference to the existing _ValidationScriptsPartial.
#section Scripts {
...
<script src="~/js/validationlocalization.js"></script>
More detail on this workaround

mvc4 url validation

I'm writing this question here after trying to find an answer for two days.
basically here's what's going on.
I have a property in the viewmodel as follows
[Required(ErrorMessage = "Required Field")]
[Url(ErrorMessage="Please enter a valid url")]
[DisplayName("Website")]
public string web { get; set; }
in the view, I have this
#Html.EditorFor(model => model.web, new { AutoCompleteType = "Disabled", autocomplete = "off" })
now the problem lies in how the input text for this field is validated in the client side. the field must have the protocol prefix at all times, otherwise it becomes invalid.
what is the best way I can fix this issue?
Many Thanks
You can do this using the DataAnnotationsExtensions library. They have an UrlAttribute that you can configure to only validate when a protocol is specified. This attribute also supplies client-side validation. You can see an example of this behavior here: http://dataannotationsextensions.org/Url/Create
You can use this attribute as follows:
using System.ComponentModel.DataAnnotations;
namespace DataAnnotationsExtensions.Core
{
public class UrlEntity
{
[Url]
[Required]
public string Url { get; set; }
[Url(UrlOptions.OptionalProtocol)]
[Required]
public string UrlWithoutProtocolRequired { get; set; }
[Url(UrlOptions.DisallowProtocol)]
[Required]
public string UrlDisallowProtocol { get; set; }
}
}
For your purposes, the first option suffices.
The package of this library (with ASP.NET MVC support included) can be found on NuGet:
Install-Package DataAnnotationsExtensions.MVC3
Note: this also works fine with ASP.NET MVC 4
Not sure if I fully understand the question. Are you trying to validate for correctly formed URLs? If so you could implement a RegularExpression DataAnnotation as follows:
[RegularExpression(#"^http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$", ErrorMessage = "My Error Message")]

I've added a connection string, but when I add data to my site it isn't appearing in my database; where is it saving to?

Title says most of it.
I've added this to my Web.Debug.config file:
<connectionStrings>
<add name="Sharpix"
connectionString="Server=localhost; Database=sharpix; Uid=root; Pwd=;"
providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
I'm using the MySQL driver, which I found here. Presumably if I installed it incorrectly, or there was an error with it, I would get an exception, but as far as I can tell, it isn't being used, and there is no attempt at using it.
However, I can add data to my site just fine:
So where's it storing my data, and how do I get it to use my MySQL database?
If relevant, my model looks like this:
public class ImageModel
{
public int Id { get; set; }
public string FileName { get; set; }
}
}
And my context looks like this:
public class SharpixContext : DbContext
{
public DbSet<ImageModel> ImageModels { get; set; }
}
I'm pretty much a beginner when it comes to the ASP.NET MVC, but I'm very familiar with the concept of MVC in general, and the Django framework.
You need to give the connection string name in the constructor. Otherwise EF will try to create a database named namespace.SharpixContext in your local server.
public class SharpixContext : DbContext
{
public SharpixContext()
: base("Sharpix")
{}
public DbSet<ImageModel> ImageModels { get; set; }
}