ASP.NET Core: model invalid due to related ICollections - asp.net-core

When submitting my post request, ModelState.IsValid is always false due to the related entities being empty.
[Key]
[Required()]
public int ID {get; set;}
[MaxLength(20)]
[Required()]
public string NAME {get; set;}
public ICollection<ActorMovieJunction> NameJobJunction {get; set;}
Both the ID and the NAME show up as valid in the state model, but NameJobJunction being "null" creates an error.
I'm also using the [BindProperty] tag

I think the problem is a new nullable feature net6. I highly recommend you to remove it or comment in project properties
<!--<Nullable>enable</Nullable>-->
Or you will have to mark all nullable properties as nullable.
public ICollection<ActorMovieJunction>? NameJobJunction {get; set;}
and IMHO never use [Bind] in the controller action parameters.

You can try to give a default value to NameJobJunction:
public ICollection<ActorMovieJunction> NameJobJunction {get; set;}=new List<ActorMovieJunction>();

Related

Trying to figure out a good way to OrderBy on IQueryable using a string of a property name C# .Net Core

I am passing in a query string that specifies a property to sort on but need to translate that to a property value in a model.
public class A
{
public int Prop1 {get; set;}
public int Prop2 {get; set;}
}
query string segment sort=Prop1
Server Side Code
query is a IQueryable
query.OrderBy(x => x.{properyName})
I have parsed the property name value from the query string but now I need to translate that to x.Prop1 in the orderby lambda not sure a great way without using reflection

Should I have both text and value in my model for a property that is selected from dropdownlist

In ASP.NET MVC application I have a model named CarSearchCriteria:
public class CarSearchCriteria{
public int CarMake {get;set;} // This is selected from a dropdownlist
public int YearOfFirstReg {get;set;}
public string ModelVariant {get;set}
}
I have two views - one for editing and the other one for viewing. In the editing view for the CarMake property I can do the following. I know I could have used DropDownListFor but didn't want to mess with SelectList for the time being:
<select name="CarMake">
<option value="1">BMW</option>
<option value="2">Mercedes</option>
<option value="3">Toyota</option>
</select>
So the model binding mechanism will easily bind the selected value to the appropriate model property. But what about the reading mode. I can't show 1s or 2s. I need to show BMW, Mercedes and so on. My question is what is the preferred way, do I have to have a property name that holds the actual textual information, something like CarMakeText?
You could have both the identifier (which you currently have) as well as the Make object itself. The latter would never need to be accessed when building the model, but can be accessed when reading the model. A lazy-loaded read-only property often works well for that. Something like this:
public int CarMakeID { get; set; }
public Make CarMake
{
get
{
if (CarMakeID == default(int))
return null;
// fetch the Make from data and return it
}
}
Naturally, this depends a lot on what a Make actually is and where you get it. If there's just some in-memory list somewhere then that should work fine. If fetching an instance of a Make is a little more of an operation (say, fetching from a database) then maybe some in-object caching would be in order in case you need to access it more than once:
public int CarMakeID { get; set; }
private Make _carMake;
public Make CarMake
{
get
{
if (CarMakeID == default(int))
return null;
if (_carMake == null)
// fetch the Make from data and save it to _carMake
return _carMake;
}
}
David's solution is just fine but for some reason I find my own solution to better fit my needs and besides that I find it more elegant. So basically what I do is I create a class that holds the textual descriptions of all the properties that keep just ID. For example, I have the following model:
public class EmployeeModel{
public int EmployeeID {get;set;}
public string FullName {get;set}
*public int DepartmentID {get;set}
*public int SpecialityID {get;set;}
public int Age {get;set;}
}
The properties marked with asterisk are the properties that keep ids of possible many predefined options and when showing we're supposed to show the actual descriptions, not the number representations. So for this purpose, we create a separate class:
public class EmployeeTextValues{
public string DepartmentName {get;set;}
public string SpecialityName {get;set;}
}
And then I just add this class as a property to my model:
public EmployeeTextValues TextValues {get;set;}
After that, it's quite easy to access it from anywhere, including Razor.
P.S. I'm sure that a lot of people will tend to do the following before initializing this property:
Employee emp=new Employee;
emp.Age=25;
emp.TextValues.DepartmentName="Engineering";// Don't do this
If you try to access or set Textvalues.Someproperty you'll get Object reference not set to an instance of an object. So do not forget to set TextValues first to some initialized object. Just a kind reminder, that's all.

How can ServiceStack.OrmLite ignore a property by attribute

public class User
{
public long Id {get;set;}
[References(typeof(City))]
public long CityId {get;set;}
[????]
public City {get;set;}
}
I'm trying to use ServiceStack.OrmLite. I'm using both ReferenceKey(CityId) and Reference (City). ReferenceKey is for Db creation, Reference is for using object in my code.
IgnoreAttribute .. Tested, it works.
Try the [IgnoreDataMember] attribute.
This attribute will tell the ServiceStack libraries to ignore this property.

Storing something other than a string in SuspensionManager.SessionState

The sample apps include a Suspension Manager class that stores session state in a Dictionary, but never attempt to store anything except a string in it.
Whenever I store anything else but a string, then trigger the serialization, I get the following error
Type 'System.RuntimeType' with data contract name 'RuntimeType:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Do I have to do something else to be able to store other types in SessionState?
You will need to do two things:
Firstly, ensure the type you are (de)serializing is decorated with the DataContract attribute from System.Runtime.Serialization and ensure it's members are decorated appropriately. For example in c#:
[DataContract]
public struct Product
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public DateTime ManufactureDate { get; set; }
[DataMember]
public decimal Cost { get; set; }
}
Secondly you will need to call SessionManager's AddKnownType<T>() (with T being the type you need) before attempting to (de)serialize it.
looking at the SessionManager code it is only string types, guess you will have to 'roll your own'
http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2/sourcecode?fileId=43552&pathId=6033729

Creating a map for relationship key besides using object property

I have a Note class which has a relationship through Client class, and therefore has a property
public virtual Client Client {get; set;}
but how can I add a map to the client_id column, for example having
public virtual int? ClientId {get; set;}
You don't.
If you need to get the value of the FK, you can just do this:
var clientId = note.Client == null? (int?)null : note.Client.Id;
Accessing the id will not cause loading of the Client proxy.
If you need to set the value (and you have an id):
note.Client = session.Load<Client>(clientId);
In the mapping class you would have:
Map(x => x.ClientId);