Fluent Validation : String Contain Another String - c#

i'm trying to see if AzureAdRegister.Scopes Contains The AzureAd.ClientId by something like the spaghetti code below.
and it's crashing once the validation of the model launched, i think this validation rule is not correct, but i was able to make that check without fluent validation for now;
is it because of ToSting() or what? thanks in advance :)
//for more clarity
public class AzureAd
{
public string Instance { get; set; }
public string Domain { get; set; }
public Guid TenantId { get; set; }
public Guid ClientId { get; set; }
public string CallbackPath { get; set; }
public List<string> Scopes { get; set; }
public List<string> DefaultScopes { get; set; }
public string ClientSecret { get; set; }
public List<string> ClientCertificates { get; set; }
}
public class AzureAdRegister
{
public string AuthorizationUrl { get; set; }
public string TokenUrl { get; set; }
public string Scopes { get; set; }
public Guid ClientId { get; set; }
}
public class AzureConfiguration
{
public AzureAd AzureAd { get; set; }
public AzureAdRegister AzureAdRegister { get; set;}
}
// there is the issue
public class AzureConfigurationValidator : AbstractValidator<AzureConfiguration>
{
public AzureConfigurationValidator()
{
RuleFor(azure => azure.AzureAdRegister.Scopes)
.Must((azure,scope) => scope.Contains(azure.AzureAd.ClientId.ToString()))
.WithMessage("the scope of registeration app must contains the client id of the main app");
}
}

Related

Auto mapper makes error when mapping class with another class properties

I have following two class structures, its CASADetialsResponse as follows,
public class CASADetialsResponse
{
public string status { get; set; }
public string message { get; set; }
public List<object> validation { get; set; }
public Data data { get; set; }
}
public class LinkedCard
{
public string cardNumber { get; set; }
}
public class JointParty
{
public string jointName { get; set; }
}
public class Account
{
public string accountNumber { get; set; }
public string accountNickName { get; set; }
public List<LinkedCard> linkedCards { get; set; }
public List<JointParty> jointParty { get; set; }
public List<object> productValidation { get; set; }
}
public class Transaction
{
public string accountNumber { get; set; }
public string valueDate { get; set; }
public string transactionDetails { get; set; }
public string postDate { get; set; }
}
public class Data
{
public Account account { get; set; }
public List<Transaction> transactions { get; set; }
}
And the CASADetails class structure as follows,
public class CASADetails
{
public string status { get; set; }
public string message { get; set; }
public List<object> validation { get; set; }
public Data data { get; set; }
}
public class LinkedCard
{
public string cardNumber { get; set; }
}
public class JointParty
{
public string jointName { get; set; }
}
public class Account
{
public string accountNumber { get; set; }
public string accountNickName { get; set; }
public List<LinkedCard> linkedCards { get; set; }
public List<JointParty> jointParty { get; set; }
public List<object> productValidation { get; set; }
}
public class Transaction
{
public string accountNumber { get; set; }
public string valueDate { get; set; }
public string transactionDetails { get; set; }
public string postDate { get; set; }
}
public class Data
{
public Account account { get; set; }
public List<Transaction> transactions { get; set; }
}
When I use _mapper.Map<CASADetialsResponse>(casaResponse); I'm getting this error:
Error mapping types:
Mapping types:
CASADetails -> CASADetialsResponse
AccountManagement.Domain.CASADetails -> AccountManagement.Application.Dtos.CASADetails.CASADetialsResponse
Type Map configuration:
CASADetails -> CASADetialsResponse
AccountManagement.Domain.CASADetails -> AccountManagement.Application.Dtos.CASADetails.CASADetialsResponse
Destination Member:
data
This is how I map the two classes,
public class CASADetailsProfile : Profile
{
public CASADetailsProfile()
{
// Source -> Target
CreateMap<CASADetialsRequest, CASADetails>();
CreateMap<CASADetails, CASADetialsResponse>();
}
}
I just commented the public Data data { get; set; } from the both classes, and without any error its worked. I think problem is with that line. may I know the reason? please help me
The namespace for Data class is different, even though their content is the same.
Delete these
and refer to source Data class namespace or
If you don't want to delete them, add the following configuration
public class CASADetailsProfile: Profile
{
public CASADetailsProfile()
{
// Source -> Target
CreateMap<CASADetialsRequest, CASADetails>();
CreateMap<CASADetails, CASADetialsResponse>();
CreateMap<Sources.Data, Destinations.Data>();
CreateMap<Sources.Account, Destinations.Account>();
CreateMap<Sources.Transaction, Destinations.Transaction>();
CreateMap<Sources.LinkedCard, Destinations.LinkedCard>();
CreateMap<Sources.JointParty, Destinations.JointParty>();
}
}
Change Sources namespace and Destinations namespace to the namespace that you have

Validation of Class with FluentValidation returning object is required for non-static field

I am trying to add FluentValidator to my .net core 3.1 Worker Service. I created a class that will hold my CSV parsed files.
public partial class Subjects
{
public Guid SubjectId { get; set; }
public string Code { get; set; }
public Guid OrganizationId { get; set; }
public string PreferredName { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
public string Gender { get; set; }
public string LastNameInitial { get; set; }
public string CodeDisplay { get; set; }
public Guid? RaceId { get; set; }
public Guid? MaritalStatusId { get; set; }
public Guid? StatusId { get; set; }
public string Rank { get; set; }
public string Email { get; set; }
public string MobilePhone { get; set; }
public bool MobilePhoneDoNotLeaveMsg { get; set; }
public bool MobilePhoneDoNotText { get; set; }
public string WorkPhone { get; set; }
public bool WorkPhoneDoNotLeaveMsg { get; set; }
}
Then according to the documentation, I create the Validation class implementing the AbstractValidator interface:
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
RuleFor(subject => Subjects.FirstName).NotEmpty();
}
}
According to the documentation, I need to add the rules in the constructor. However, when I pass in the lambda for the rule I got this error:
"An object reference is required for non-static field, method, or
property"
So I modified the constructor like this:
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
Subjects subject = new Subjects();
RuleFor(x=>subject.FirstName).NotEmpty();
}
}
Which got of the error, but when I try to call the validation I get an error when I instantiate the object for testing:
Subjects subject = new Subjects();
subject.FirstName = "John";
SubjectsValidation validator = SubjectsValidation();
This returns a failed message because I had to create a new subject in the Subject Validation so it return a failure. So following the instructions on the website, I just can't get this working. How do I fix this?
The RuleFor method is expecting a delegate. So your first attempt will work if you use the parameter of the delegate within the body (subject instead of Subjects):
class SubjectsValidation : AbstractValidator<Subjects>
{
public SubjectsValidation()
{
RuleFor(subject => subject.FirstName).NotEmpty();
}
}

Noob C# Class Declaration Issue

So I created a class using json2csharp
public class ResponseType
{
public class Query
{
public string q { get; set; }
public object sku { get; set; }
public int limit { get; set; }
public object reference { get; set; }
public object mpn_or_sku { get; set; }
public string mpn { get; set; }
public object brand { get; set; }
public string __class__ { get; set; }
public int start { get; set; }
public object seller { get; set; }
}
public class Request
{
public bool exact_only { get; set; }
public string __class__ { get; set; }
public List<Query> queries { get; set; }
}
public class Seller
{
public string display_flag { get; set; }
public bool has_ecommerce { get; set; }
public string name { get; set; }
public string __class__ { get; set; }
public string homepage_url { get; set; }
public string id { get; set; }
public string uid { get; set; }
}
public class Prices
{
public List<List<object>> USD { get; set; }
public List<List<object>> JPY { get; set; }
public List<List<object>> CNY { get; set; }
}
public class Offer
{
public string sku { get; set; }
public string packaging { get; set; }
public string on_order_eta { get; set; }
public string last_updated { get; set; }
public int? order_multiple { get; set; }
public int in_stock_quantity { get; set; }
public string eligible_region { get; set; }
public int? moq { get; set; }
public int? on_order_quantity { get; set; }
public object octopart_rfq_url { get; set; }
public string __class__ { get; set; }
public Seller seller { get; set; }
public string product_url { get; set; }
public object factory_order_multiple { get; set; }
public string _naive_id { get; set; }
public int? factory_lead_days { get; set; }
public Prices prices { get; set; }
public bool is_authorized { get; set; }
public bool is_realtime { get; set; }
}
public class Brand
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Manufacturer
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Item
{
public List<Offer> offers { get; set; }
public string uid { get; set; }
public string mpn { get; set; }
public List<object> redirected_uids { get; set; }
public Brand brand { get; set; }
public string octopart_url { get; set; }
public string __class__ { get; set; }
public Manufacturer manufacturer { get; set; }
}
public class Result
{
public List<Item> items { get; set; }
public int hits { get; set; }
public string __class__ { get; set; }
public object reference { get; set; }
public object error { get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}
}
The problem is at design-time, when I declare a variable with the type of my class:
ResponseType Response = new ResponseType();
Intellisense does not allow me to access the subclasses RootObject.results list. It only shows Equals, GetHashCode, GetType and ToString. I am assuming I did something wrong in my class declaration.
Thank you in advance!
Edit -- I am fairly new to C Sharp. I am trying to parse a response from a REST API. I took the JSON provided by the Rest API and converted it using json2csharp into a class. My intent was to do something like this
Within a function return:
public ResponseType ExecuteSearch(String PartNumber)
{
~ ALL CODE FOR GENERATING req
// Perform the search and obtain results
var data = client.Execute(req).Content;
JSON = data;
return JsonConvert.DeserializeObject<ResponseType>(data);
}
Then being able to access the response as an object outside of the function
Edit 2:
I figured out what I did. Instead of nesting everything within the ResponseType I should have simply renamed RootObject to ResponseType.
Intellisense does not allow me to access the subclasses RootObject.results list
it is because the property results is not static and you try to acces it this way. A static property is accessed via ClassName.PropertyName. For more information on static variables check the link.
It only shows Equals, GetHashCode, GetType and ToString
This is the basic set of methods that every object in C# inherits from the class object. This is why you can see it.
Intellisense will allow you to do this:
ResponseType.RootObject ro = new ResponseType.RootObject();
ro.results.First();
because you will need an Instance of that class to acces the property results.
I am assuming I did something wrong in my class declaration.
It depends. Basically if the compiler does not complain then you declared your classes as supposed to be. But the declaration of the properties commands you to access them in a specific way. So if you still want to access results with RootObject.results you need to make it static:
public class RootObject
{
public static List<Result> results { get; set; }
}
But note that this list will exist only once! and is not individual to each instance of RootObject! Since you have embedded classes you need to call it like this:
ResponseType.RootObject.results.WhatEver();
EDIT
I guess you would like to get the Object of type RootObject inside the Object of type ResponseType. If I am right then it is not necessary to declare the classes inside ResponseType but you have to declare variables of each type inside it like:
public class ResponseType
{
public RootObject MyRootObject{ get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}
Now you will be able to access the results variable inside the ResponseType object:
ResponseType rt = new ResponseType();
rt.MyRootObject.results.WhatEver();
For more information on how to deserialize JSON to classes please read the Deserialize JSON to C# Classes post
1) Object with ResponseType class isn't contain any fields(event static one).
2) You declare ResponseType object, but results is field of RootObject object.
So if you want to work with results you should do something like this:
ResponseType.RootObject rootObject = new ResponseType.RootObject();
rootObject.results.DoWork();
Below is what I think you are trying to do. I would only use it in this form if this is some kind of Data Transfer Object (DTO) because otherwise it is pretty bad practice for a class that would be used in code (mostly because of the public getters and setters on all of the fields and the field names matching the class name), but it does show your main mistake and that is that classes need to be defined outside of your main class and if you need that type of class in your top level class you need to define a public field to access it.
public class ResponseType
{
public Query Query { get; set; }
public Request Request { get; set; }
public Seller Seller { get; set; }
public Prices Prices { get; set; }
public Offer Offer { get; set; }
public Brand Brand { get; set; }
public Manufacturer Manufacturer { get; set; }
public Item Item { get; set; }
public Result Result { get; set; }
public RootObject RootObject { get; set; }
}
public class Query
{
public string q { get; set; }
public object sku { get; set; }
public int limit { get; set; }
public object reference { get; set; }
public object mpn_or_sku { get; set; }
public string mpn { get; set; }
public object brand { get; set; }
public string __class__ { get; set; }
public int start { get; set; }
public object seller { get; set; }
}
public class Request
{
public bool exact_only { get; set; }
public string __class__ { get; set; }
public List<Query> queries { get; set; }
}
public class Seller
{
public string display_flag { get; set; }
public bool has_ecommerce { get; set; }
public string name { get; set; }
public string __class__ { get; set; }
public string homepage_url { get; set; }
public string id { get; set; }
public string uid { get; set; }
}
public class Prices
{
public List<List<object>> USD { get; set; }
public List<List<object>> JPY { get; set; }
public List<List<object>> CNY { get; set; }
}
public class Offer
{
public string sku { get; set; }
public string packaging { get; set; }
public string on_order_eta { get; set; }
public string last_updated { get; set; }
public int? order_multiple { get; set; }
public int in_stock_quantity { get; set; }
public string eligible_region { get; set; }
public int? moq { get; set; }
public int? on_order_quantity { get; set; }
public object octopart_rfq_url { get; set; }
public string __class__ { get; set; }
public Seller seller { get; set; }
public string product_url { get; set; }
public object factory_order_multiple { get; set; }
public string _naive_id { get; set; }
public int? factory_lead_days { get; set; }
public Prices prices { get; set; }
public bool is_authorized { get; set; }
public bool is_realtime { get; set; }
}
public class Brand
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Manufacturer
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Item
{
public List<Offer> offers { get; set; }
public string uid { get; set; }
public string mpn { get; set; }
public List<object> redirected_uids { get; set; }
public Brand brand { get; set; }
public string octopart_url { get; set; }
public string __class__ { get; set; }
public Manufacturer manufacturer { get; set; }
}
public class Result
{
public List<Item> items { get; set; }
public int hits { get; set; }
public string __class__ { get; set; }
public object reference { get; set; }
public object error { get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}

How to ignore an inner nested object when using AutoMapper

Hello I have the classes:
Class User
public class User
{
public Int64 Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public Profile Profile { get; set; } //EF one to one
}
Class Profile
public class Profile
{
public Int64 Id { get; set; }
public string Skype { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
public virtual User User { get; set; } //This is because EF Mappings
}
Class User DTO
public class UserDTO
{
public string Name { get; set; }
public string Email { get; set; }
public Profile Profile { get; set; }
}
I did the configurations to Map User to UserDTO
Mapper.CreateMap<User, UserDTO>();
I need to have the Profile.User because of the Entity Framework One to One Relationship but I don't want the Profile.User to be shown in the Mapping.
How can I ignore the Profile.User?
You could use a UserProfileDTO class that omits User
public class UserProfileDTO
{
public string Skype { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public ICollection<AddressDTO> Addresses { get; set; }
}
public class UserDTO
{
public string Name { get; set; }
public string Email { get; set; }
public UserProfileDTO Profile { get; set; }
}
Mapper.CreateMap<User, UserDTO>();
Mapper.CreateMap<Profile, UserProfileDTO>();

Im trying to get the last record submitted in the db using the repository pattern and MVC

Im trying to get the last record submitted in the db using the repository pattern and MVC. I am attaching the interface and class.And the controller where you can put the code. Please let me know if you need more details. Thanks.
public interface IRequestRepository
{
tblRequest GetCaseId(int caseId);
}
public class RequestRepository: IRequestRepository
{
helpdeskEntities context = null;
public RequestRepository()
{
context = new helpdeskEntities();
}
public string GetCaseId(Ticket ticket)
{
string caseId = string.Empty;
tblRequest tr = context.tblRequests.Where(u => u.CaseID == ticket.CaseID && u.UEmailAddress == ticket.UEmailAddress).SingleOrDefault();
if (tr != null)
{
caseId = tr.CaseID;
}
return caseId;
}
}
public class Ticket
{
public int CaseID { get; set; }
public string Title { get; set; }
[Required]
public string UFirstName { get; set; }
[Required]
public string ULastName { get; set; }
//public string UDisplayName { get; set; }
[Required]
public string UDep_Location { get; set; }
[Required]
public string UEmailAddress { get; set; }
//public string UComputerName { get; set; }
//public string UIPAddress { get; set; }
[Required]
public string UPhoneNumber { get; set; }
[Required]
public string Priority { get; set; }
[Required]
public string ProbCat { get; set; }
//public string IniDateTime { get; set; }
//public string UpdateProbDetails { get; set; }
//public string UpdatedBy { get; set; }
public string InitiatedBy_tech { get; set; }
public string AssignedBy { get; set; }
public string TechAssigned { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string ProbDetails { get; set; }
}
Controller
public ActionResult CreateTicket(tblRequest td)
{
}
First, you need to upgrade your IRequestRepository and add that method:
(I am assuming you're using EntityFramework for that)
public IRequestRepository
{
Request Latest(Ticket ticket);
}
Next, you need to implement that method in your RequestRepository:
public class RequestRepository : IRequestRepository
{
/* other code here */
public Request Latest(Ticket ticket)
{
// I'm also assuming you're using an auto incremented CaseId
return this.context.tblRequests.OrderByDescending(p => p.CaseId).FirstOrDefault(p => p.UEmailAddress == ticket.UEmailAddress);
}
}
And another thing:
Your IRequestRepository.GetCaseId implementation returns a string while it should return a tblRequest (one would also expect it to return an int Id...)
Anyway, I hope this helps!

Categories