FromRoute and FromQuery in the same model has different results between asp net core 2.2 and 3.0 - model-binding

I don't know if it's any different default configuration, but by creating an asp.net core 2.2 project and another asp.net core 3.0 project, I'm getting different results in model binding.
public class Dto
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public string Prop4 { get; set; }
}
[HttpGet("test/{prop1:alpha}/{prop2:alpha}")]
public ActionResult<Result> Test(Dto dto)
{
}
The above code works perfectly in asp.net core 2.2 when the url is called:
https://localhost:xxxx/test/aaa/bbb/?prop3=ccc&prop4=ddd
However, in asp.net core 3 the object is null.
if i use [FromRoute] it just gets the values of prop1 and prop2.
If I use [FromQuery] it just gets the values of prop3 and prop4.
How do I configure asp.net core 3 so that it get the values of the route and querystring like asp.net core 2.2 ?
Note that in asp.net core 2.2 I have not informed either [FromRoute] or [FromQuery] that seem to me mandatory now.

OK, I found that the problem refers to using the ApiExplorer attribute.
Without it, it works exactly as I would like.

In time, it is possible to have the same results using ApiController attribute, however, by setting the SuppressInferBindingSourcesForParameters property to true.
Problem solved.

Related

After upgrade to EF Core 2.2 => 3.1, Guid ID no longer generated by DbSet.Add()

I'm upgrading from EF Core 2.2 to EF Core 3.1. I have an entity Patient with a GUID Id:
class Patient {
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
A DbSet is defined for this type:
public DbSet<Patient> Patients { get; set; }
In EF 2.2, when I added a new Patient, the Id would be automatically generated when the object was added to the DbSet:
// newPatient.Id -> 00000000-0000-0000-0000-000000000000
ctx.Patients.Add(newPatient);
// newPatient.Id -> C1D5ACB8-A4C9-4680-AF2F-BF5E5B0AC1B6 <=== GUID generated
Now, in EF 3.1, the Id is not being automatically generated upon Add:
// newPatient.Id -> 00000000-0000-0000-0000-000000000000
ctx.Patients.Add(newPatient);
// newPatient.Id -> 00000000-0000-0000-0000-000000000000 <=== still an empty GUID
This obviously breaks my code.
In EF Core 3.0 there is a breaking change "String and byte array keys are not client-generated by default". However, this breaking change indicates string and byte array keys, not GUID keys. Also, I have tried the recommended mitigations with FluentAPI and Data Annotations and it does not resolve my issue (still no GUID generated).
I am using the dotConnect for Oracle database provider v9.11. I did not find any breaking changes there that would affect this.
Of course I can explicitly assign a GUID Id in my code, but I'd like to make this work as it did before in EF Core 2.2.
Any suggestions why this is not working? Thanks.

How to define the order of property deserialization when using ASP.NET Web API 2.2 OData V4

I would like to define the order of property deserialization when using ASP.NET Web API 2.2 OData V4. Perhaps there is already an attribute which can be used to define this. For the purpose of this e-mail I name it DeserializationOrderAttribute. I imagine I should be able to define a class like this:
public class Employee
{
[DeserializationOrder(0)]
public Guid EmployeeID { get; set; }
[DeserializationOrder(1)]
public string FirstName { get; set; }
[DeserializationOrder(1)]
public string LastName { get; set; }
}
In this situation, the EmployeeID property should be deserialized before FirstName and LastName. FirstName and LastName can be deserialized in any mutual order.
Is there an attribute for achieving this or is there another standard way of achieving definition of the order of property deserialization?
Best regards,
Henrik Dahl
You can add a DataMember attribute to your properties and then specify the Order property.
Note that properties not decorated with this attribute will always appear first as detailed here.

Overly complicated many-to-many relationship with ASP.NET MVC

While researching whether or not ASP.NET MVC is suited for my next website, I've come across an annoying issue.
I have followed ASP.NET MVC since version 2, and it's gotten better. For instance, it's now fairly easy to get going with migrations in the entity framework with code first, which used to be a hassle.
This means that I now can get running with a database migrations and code first within half an hour (as I usually don't remember the steps involved, I have to follow a guide I wrote).
Now, fairly early on I always get a many-to-many relationship between entities (e.g. tags and posts) in my database, and what I've found is that getting this relationship exposed via MVC framework is surprisingly complicated! Example from asp.net Example from mikesdotnetting
It involves special methods to retrieve the relationship's data that is not an inherent part of the framework.
Is there really no better/easier way of treating the many-to-many relationship?
You should add a virtual key word to the Many port
public class Post
{
[Key]
public int ID { get; set; }
public string Title { get; set; }
public virtual ICollection<Tag> Tags {get;set;}
}
public class Tag
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts {get;set;}
}

With Entity Framework 4.1 Codefirst, how do you create unmapped fields in the poco classes?

I have a set of classes as my domain objects.
I have a set of configuration files to map these objects (EntityTypeConfiguration<>).
When I add a property to any of the domain objects without mapping to a column, the dbcontext attempts to query for the column, ignoring the fact that it is not mapped.
I must be missing a setting either in the configuration code or the dbcontext code. I do not want to add an attribute to the poco class (decorating the pocos tie them to a specific persistence implementation, which I wish to avoid).
On the call against the IQueryable to populate a ticket object, the call fails with the message:
Invalid column name 'NotInDatabase'.
public class Ticket
{
public Ticket()
{
}
public virtual int Id
{
get;
set;
}
public virtual string Title
{
get;
set;
}
public virtual string Description
{
get;
set;
}
public string NotInDatabase
{
get;
set;
}
}
internal class TicketConfiguration : EntityTypeConfiguration<Ticket>
{
public TicketConfiguration()
{
ToTable("ticket_table_name");
HasKey(o => o.Id)
.Property(o => o.Id)
.HasColumnName("ticketId")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired();
Property(o => o.Title).HasColumnName("TicketTitle");
Property(o => o.Description).HasColumnName("TicketDescription");
}
}
Note:
Please do not suggest using "Database First" or "Model First" for my situation. I want to map poco objects to the database using the features of code first, even though I have an existing db structure. I am comparing this to nhibernate and really want to stick to a similar structure (since Microsoft "adopted" fluent nhibernate's approach, it's pretty easy to compare apples to apples).
Thanks!
.Ignore should do the trick or by attribute it's called [NotMapped]

ASP.NET MVC / DDD architecture help

I am creating a Web application using ASP.NET MVC, and I'm trying to use domain-driven design. I have an architecture question.
I have a WebControl table to store keys and values for lists so they can be editable. I've incorporated this into my business model, but it is resulting in a lot of redundant code and I'm not sure it belongs there. For example, in my Request class I have a property called NeedType. Because this comes from a list, I created a NeedType class to provide the values for the radio buttons. I'm showing just one example here, but the form is going to have probably a dozen or so lists that need to come from the database.
[edit, to clarify question] What's a better way to do this? Are these list objects really part of my domain or do they exist only for the UI? If not part of the domain, then they don't belong in my Core project, so where do they go?
public class Request : DomainObject
{
public virtual int RequestId { get; set; }
public virtual DateTime SubmissionDate { get; set; }
public virtual string NeedType { get; set; }
public virtual string NeedDescription { get; set; }
// etc.
}
public class NeedType : DomainObject
{
public virtual int NeedTypeId { get; set; }
public virtual string NeedTypeCode { get; set; }
public virtual string NeedTypeName { get; set; }
public virtual int DisplayOrder { get; set; }
public virtual bool Active { get; set; }
}
public class RequestController : Controller
{
private readonly IRequestRepository repository;
public RequestController()
{
repository = new RequestRepository(new HybridSessionBuilder());
}
public RequestController(IRequestRepository repository)
{
this.repository = repository;
}
public ViewResult Index(RequestForm form)
{
ViewData.Add("NeedTypes", GetNeedTypes());
if (form == null)
{
form = new RequestForm();
form.BindTo(repository.GetById(125));
}
}
private NeedType[] GetNeedTypes()
{
INeedTypeRepository repo = new NeedTypeRepository(new HybridSessionBuilder());
return repo.GetAll();
}
}
Create a seperate viewmodel with the data you need in your view. The Model in the M of MVC is not the same as the domainmodel. MVC viewmodels are dumb DTO's without behaviour, properties only. A domain model has as much behaviour as possible. A domain model with get;set; properties only is considered an anti-pattern called "anemic domain model". There are 2 places where most people put the viewmodels: in the web layer, close to the views and controllers, or in a application service layer.
Edit:
When you only need to display a list of all needtypes in the database and one request in your view, I would indeed create one viewmodel with the request and the list of needtypes as properties. I don't think a call to multiple repositories in a controller is a smell, unless you have a larger application and you might want a seperate application service layer that returns the whole viewmodel with one method call.
I think it might also be a good idea to follow the advise of Todd Smith about value object.
When the needtypes can be added or edited by users at runtime, needtype should be an entity. When the needtypes are hardcoded and only changed with new releases of the project, needtype should be a value object and the list of needtypes could be populated by something like NeedType.GetAll() and stored in the database by adding a column to the request table instead of a seperate needtype table.
If it comes from a list, then I'm betting this is a foreign key. Don't think about your UI at all when designing your domain model. This is simply a case where NeedType is a foreign key. Replace the string NeedType with a reference to an actual NeedType object. In your database, this would be a reference to an id.
When you're building your list of NeedType choices, you simply need to pull every NeedType. Perhaps keeping it cached would be a good idea if it doesn't change much.
Your NeedType looks like a value object to me. If it's read-only data then it should be treated as a value object in a DDD architecture and are part of your domain.
A lot of people run into the "omg so much redundancy" issue when dealing with DDD since you're no longer using the old Database -> DataTable -> UI approach.

Resources