I have the following method which I am trying to use to stop people altering the querystring
in order to view other peoples details:
public static bool IsCurrentUserAuthorisedVessel(HttpRequest request)
{
Guid currentUser = GetCurrentUserId();
PersonRepository repo = new PersonRepository();
VesselRepository vesselRepo = new VesselRepository();
Person currentPerson = repo.GetPersonByUser(currentUser);
int qs = int.Parse(request.QueryString["VesselId"]);
Vessel currentVessel = vesselRepo.GetVessel(qs);
if (!String.IsNullOrEmpty(request.QueryString["VesselId"]))
{
if (IsCurrentUserAdmin())
{
return true; //Always return true for admin
}
else
{
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
}
}
return true;
}
In the example I am currently debugging currentPerson.Vessels
yields 3 vessels in an Icollection<Vessel>
one of which has a VesselId
of 6 which also happens to be the VesselId of currentVessel
however the match is failing and the method is returning false
.
I have done some reading on similar SO questions and MSDN documentation and my understanding of what is happening here is because the Vessel which has an ID of 6 within the ICollection is a different instance of the currentVessel I am attempting to match, the reference is resulting in not equal and something to do with the equality rules are not based on ID.
My Person
model contains public virtual ICollection<Vessel> Vessels { get; set; }
public virtual ICollection<Vessel> Vessels { get; set; }
public virtual ICollection<Vessel> Vessels { get; set; }
does this mean that I must implement the IEquatable
interface on my Vessel
model and then override the Equals method.
I want my own custom rules based on id for equality in this instance. How do I override this method?
在这种情况下,覆盖Equals
在这里似乎有点过大了,为什么不这样做
currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
The solution suggested by @james is not the best practice. here why if you have a long list of Vessels that should be added to a Hashset<Vessel>
contains method will cost only O(1)
since it will be indexed on GetHashCode
while .Any
is an extension method that should iterate through all elements to find the right one and the cost will be O(n)
you could do something like this
public class Vessel : IEquatable<Vessel>
{
public int Id { get; set; }
public bool Equals(Vessel other)
{
return Id == other.Id ;
}
public override int GetHashCode()
{
return Id;
}
public override bool Equals(object obj)
{
var vessel = obj as Vessel;
return vessel != null && vessel.Id == this.Id;
}
}
Update
the reasons why I have stated it's not a best practice it's that OP stated that he has an ICollection<Vessel>
which can be converted to many Generics collections like List<T>
for example.
from MSDN
When the search methods of a number of generic collection objects are called. Some of these types and their methods include the following:
change
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
to
return currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.