Update base properties - ASP.NET MVC- c# - c#

I have the following code in a model
base.Name = instance.Name;
base.SSN = instance.SSN;
base.DateModified = DateTime.Now
base.ClienType = instance.ClientType;
If I add more properties to my base then i have to update my model to update the properties. Is there an easier way to update the base.properties instead of listing each of them and then updating the same?
Yes i know i am being lazy

I'm not quite sure why you are doing this, but you might want to take a look at AutoMapper - if your properties are the same on both side you can get it to automatically map one to the other without doing any real setup.

You could use Automapper to automatically map where there is a naming convention.
Also beware that things the following would not map as one has one less t
base.ClienType = instance.ClientType;

Related

Apply SuppressImplicitRequiredAttributeForNonNullableReferenceTypes only to particular paths

Can you apply the SuppressImplicitRequiredAttributeForNonNullableReferenceTypes option to only a particular path pattern, e.g., .../v3/...?
We've gone through the trouble of enabling nullable contexts throughout our code, and ensuring all our parameters have the correct nullability. Now we want to utilize that for API validation. But since we don't want break any of our exising API behavior, we only want to apply the implicit Required attribute behvaior on paths for particular API versions. I.e., v2 would NOT have the validation, but v3+ would.
Is there any way to do this?
I can show you the way, but you have to walk through it and complete the implementation!
Ok, to see how SuppressImplicitRequiredAttributeForNonNullableReferenceTypes works, let's check the source code first!
Here's when the parameter is being used in DataAnnotationsMetadataProvider class.
https://github.com/dotnet/aspnetcore/blob/3ea008c80d5cc63de7f90ddfd6823b7b006251ff/src/Mvc/Mvc.DataAnnotations/src/DataAnnotationsMetadataProvider.cs#L343
Now let's see where DataAnnotationsMetadataProvider is used! It is added as a ModelMetadataDetailsProviders to MvcOptions.ModelMetadataDetailsProviders.
https://github.com/dotnet/aspnetcore/blob/3ea008c80d5cc63de7f90ddfd6823b7b006251ff/src/Mvc/Mvc.DataAnnotations/src/DependencyInjection/MvcDataAnnotationsMvcOptionsSetup.cs#L54
So you would need to create your own CustomValidationMetadataProvider and add it to MvcOptions.
builder.Services.AddControllers(op =>
{
op.ModelMetadataDetailsProviders.Add(new CustomValidationMetadataProvider());
});
public class CustomValidationMetadataProvider : IValidationMetadataProvider
{
public void CreateValidationMetadata(ValidationMetadataProviderContext context)
{
// context.ValidationMetadata.IsRequired = ???
}
}
Here you can have your own logic to set context.ValidationMetadata.IsRequired. Unfortunately I'm not sure if you can access the request path here, but you do have access to attributes on the model. So theoretically you could add an attribute to the models on your v3.
There are a few things that I could suggest here:
If you on C# 8 you can try nullable properties/fields for places where you want to allow nullable values. (recommended simplest one)
You can use custom Parameter Binding (non-trivial approach). You can find more details here https://www.strathweb.com/2013/04/asp-net-web-api-parameter-binding-part-1-understanding-binding-from-uri/
You can disable standard model validation and provide your own (where you should be able to specify path) and again non-trivial approach.

Model conversion coverage

We recently introduced a completely new data model which is different from our current model from the logical structure point of view. We also changed the language of the model from German to English, because we want to open the models structure as XML to our customer.
In order to be able to convert the model we implemented a explicit conversion which basically matches all properties from the different classes of the new model into our old model.
Like this:
private OldModel Convert(NewModel src)
{
var dst = new OldModel();
dst.Prop1 = src.SomeOtherProp
dst.Prop2 = Convert(src.ComplexProp);
//....
return dst;
}
Now we want to make sure, all of the properties of the new model are written into the old model for coverage and testing purposes. We also want to make sure we didn't forget any property and also guarantee that for future model extensions, we don't forget a property.
My idea would be to parse the codefile, extract all properties which are read from the new model, run over the new model with reflection compare them with the actual properties within it.
This solution feels not like a good one :-) Any suggestions?
I appreciate any help!
I suggest to use mapping libs like AutoMapper. They allow to configure mapping, converters and operate with public properties and specific methods.
We finally decided to parse the codefile with regular expressions like this:
#"private static [a-zA-Z0-9.]+[ ]+Convert[(][^)]*[)]\s*[{](?<body>[^{}]*(((?<Open>[{])[^{}]*)+((?<Close-Open>[}])[^{}]*)+)*(?(Open)(?!)))[}]";
It will match methods like this private static Namespace.ClassName Convert(Namespace.ClassName input) and will extract the methods body.
Since the converter methods follow a simple structural pattern, it was easy to extract the information I needed.

Is it possible to automatically create automapper mappings?

Maybe this is a stupid question, but it's really not obvious for me :(
var address = new Address { Id = 1, Name = "John Doe" };
// Configure AutoMapper
Mapper.CreateMap<Address, AddressViewModel>();
// Perform mapping
var viewModel = Mapper.Map<Address, AddressViewModel>(address);
Imho Mapper.CreateMap<Address, AddressViewModel>(); is not needed, because AutoMapper gets this information afterwards where the mapping is performed.
So why do I have to write those configurations?
Having a quick browse through the source, it appears that it stores it's mappings in the engine so that any calls that follow load the mapping data from the engine.
This is probably due to the fact that reflection can be expensive and there's no way for the AutoMapper to know how few - or many - times someone will use just Mapper.Map. Definition: caching :)
Additionally this pattern is very useful for validating that your configuration is correct (see https://github.com/AutoMapper/AutoMapper/wiki/Configuration-validation). Some mappings require fairly specific configuration, and this catches any errors early.
If nothing else, Automapper doesn't necessarily get all of this information when the mapping is performed, because you may have specified any number of .ForMember / .AfterMap (etc) chainings in your CreateMap expression. You don't want to have to repeat all of that in every mapping invocation.

View model properties has changing validation rules at run time

I'm new to C# MVC and I'm trying to add some dynamic validation checks to my view models that are used in a form. For example, I have a string property called FirstName. I can add the attribute StringLength(10) and Required() to it.
My problem is, depending on some other field, the FirstName StringLength could vary from 10 to 20, etc. I still want to use the MVC validations but be able to modify it. I know that attributes are bound to the class so maybe I'm using the wrong thing.
I want the abilities for attribute validation but have it modifiable at run time. Is this possible?
The values in an attribute have to be literals. You can still use attribute based validation, but you will need to use the CustomValidation tag and point it at a method to use. If it depends on multiple fields in the object, you will want to put this on the class rather than the property.
It seems you can add validation attributes at runtime by implementing DataAnnotationsModelValidatorProvider:
Dynamic Attributes # forums.asp.net

How can I convert a list of domain objects to viewmodels on the Controller in ASP.NET MVC

I'd like to know the best way of converting a list of domain object I retrieve into custom ViewModels in the controller
e.g.
IList<Balls> _balls = _ballsService.GetBalls(searchCriteria);
into
IList<BallViewModels> _balls = _ballsService.GetBalls(searchCriteria);
it doesn't have to be exactly as I've outlined above i.e. it doesn't have to be an IList and if not accessing the service directly and instead go thru some other layer that converts the objects to viewmodels then that is ok too.
thanks
For simple objects you could just use Linq:
IList<BallViewModel> _balls = _ballsService.GetBalls(searchCriteria)
.Select(b => new BallsViewModel
{
ID = b.ID,
Name = b.Name,
// etc
})
.ToList();
That can get pretty repetitive though, so you may want to give your BallViewModel class a constructor that accepts a Ball and does the work for you.
Another approach is to use a library like AutoMapper to copy the properties (even the nested ones) from your domain object to your view model.
Probably a bit of Linq, something along the lines of
var ballQuery = from ball in _ballsService.GetBalls(searchCriteria)
select new BallViewModels
{
Diameter = ball.Diameter,
color = ball.Color,
...
}
IList<BallViewModels> _balls = ballQuery.ToList();
Either that or the question is more complicated than I think...
I use AutoMapper to do this all the time. It's really flexible and has worked for me without any troubles so far.
First you set up a map like during your app's initialization:
Mapper.CreateMapping<Balls, BallViewModel>();
And whenever you need to map the objects, you would do this:
Mapper.Map<IList<Balls>, IList<BallViewModel>>(_ballsService.GetBalls());
Like I said, it's very flexible and you can modify how the mapping happens for each property using a fluent API.

Categories

Resources