Note field required even though it has no required attribute - c#

I have the following class:
public class UpdateActionRequest
{
[Required]
public int ActionId { get; set; }
[Required]
public int LeadId { get; set; }
[Required]
public int AssignedToUserId { get; set; }
public string Note { get; set; }
public DateTime? PlannedDate { get; set; }
}
Which I use in an api call:
[HttpPatch("update", Name = nameof(UpdateAction))]
public async Task<LeadAction> UpdateAction(UpdateActionRequest request)
{
return await _actionsHandler.Value.UpdateAction(request);
}
But when I send the following JSON:
{
"ActionId":7,
"LeadId":40,
"AssignedToUserId": 8306,
"PlannedDate":"2022-11-14T11:23:45.343Z"
}
I'm getting a bad request saying the note field is required - how do I make it so that I don't need to send the note property?

you can use
public string? Note { get; set; };
or
public string Note { get; set; } = string.Empty;

Related

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();
}
}

PUT Request Does not Convert Snake Case to Pascal Case

I am trying to send a PUT request, but for some reason my API refuses to convert snake case properties
The request looks like this:
Where mercuryParserResponse looks like this in C#:
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public class MercuryParserResponseDto
{
public string Author { get; set; }
public string Content { get; set; }
public DateTimeOffset DatePublished { get; set; }
public string Direction { get; set; }
public string Domain { get; set; }
public string Excerpt { get; set; }
public string LeadImageUrl { get; set; }
public string Url { get; set; }
[JsonProperty("word_count")]
public int WordCount { get; set; }
public string NextPageUrl { get; set; } //
public int RenderedPages { get; set; } //
public string Title { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
}
And my API endpoint
[HttpPut]
public async Task<IActionResult> Put(
[FromBody]ImportArticleDto article,
CancellationToken cancellationToken = default)
{
return null;
}
But article.MercuryParserResponse.WordCount is always 0 (Note that single-word properties such as author are coming through correctly)
Why? Why are my Json attributes not working here?
From this answer, using JsonPropertyName works:
[JsonPropertyName("word_count")]
However I don't really want to have to add this to every single property
If anyone can advise how to apply this casing to the entire class I will accept your answer

Not getting object data from Json deserialization

I am getting Json data from a web server, but when I try to deserialize it to objects, I am not getting any data. The Json string looks like this:
{"success":true,"data":[{"Id":6,"CustomerGuid":"70b390d8-82d5-4bba-aa68-fc8268a1b1ff","UserName":"victoria_victoria#nopCommerce.com","Email":"victoria_victoria#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472393)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472393)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":5,"CustomerGuid":"eb9e6f24-f362-4c10-942a-366e2919dc11","UserName":"brenda_lindgren#nopCommerce.com","Email":"brenda_lindgren#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472363)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472363)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":4,"CustomerGuid":"9f46dbae-6942-410c-90b8-9b38a0890064","UserName":"james_pan#nopCommerce.com","Email":"james_pan#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472317)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472317)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":3,"CustomerGuid":"6277386b-13ee-427b-9cfe-4ebfa487c340","UserName":"arthur_holmes#nopCommerce.com","Email":"arthur_holmes#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472253)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472253)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":2,"CustomerGuid":"241f45f1-b38c-4e22-8c5a-743fa3276620","UserName":"steve_gates#nopCommerce.com","Email":"steve_gates#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472207)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472207)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":1,"CustomerGuid":"a940dc03-5f52-47d2-9391-8597b3b31cf2","UserName":"tony#lakesideos.com","Email":"tony#lakesideos.com","CustomerRoles":[{"Id":1,"Name":"Administrators","SystemName":"Administrators"},{"Id":2,"Name":"Forum Moderators","SystemName":"ForumModerators"},{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":true,"Active":true,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":"71.185.255.7","CreatedOnUtc":"\/Date(1472933470783)\/","LastLoginDateUtc":"\/Date(1477522483903)\/","LastActivityDateUtc":"\/Date(1477523996553)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[{"Id":1,"StoreId":1,"ShoppingCartTypeId":1,"CustomerId":1,"ProductId":18,"AttributesXml":null,"CustomerEnteredPrice":0.0000,"Quantity":1,"CreatedOnUtc":"\/Date(1473801903447)\/","UpdatedOnUtc":"\/Date(1473803336207)\/","IsFreeShipping":false,"IsShipEnabled":true,"AdditionalShippingCharge":0.0000,"IsTaxExempt":false}]}]}
I created these classes from the recommendation given in this link:
recommendation
I used this to create the classes: json2csharp
Response class:
class Response
{
bool success;
IList<Customer> data;
}
Customer class:
class Customer
{
public int Id { get; set; }
public string CustomerGuid { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public List<CustomerRole> CustomerRoles { get; set; }
public object AdminComment { get; set; }
public bool IsTaxExempt { get; set; }
public int AffiliateId { get; set; }
public int VendorId { get; set; }
public bool HasShoppingCartItems { get; set; }
public bool Active { get; set; }
public bool Deleted { get; set; }
public bool IsSystemAccount { get; set; }
public object SystemName { get; set; }
public string LastIpAddress { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime? LastLoginDateUtc { get; set; }
public DateTime LastActivityDateUtc { get; set; }
public List<object> ExternalAuthenticationRecords { get; set; }
public List<object> ShoppingCartItems { get; set; }
}
CustomerRole class:
class CustomerRole
{
public int Id { get; set; }
public string Name { get; set; }
public string SystemName { get; set; }
}
ExternalAuthenticationRecord class:
class ExternalAuthenticationRecord
{
public int Id { get; set; }
public int CustomerId { get; set; }
public string Email { get; set; }
public object ExternalIdentifier { get; set; }
public object ExternalDisplayIdentifier { get; set; }
public object OAuthToken { get; set; }
public object OAuthAccessToken { get; set; }
public string ProviderSystemName { get; set; }
}
ShoppingCartItem class:
class ShoppingCartItem
{
public int Id { get; set; }
public int StoreId { get; set; }
public int ShoppingCartTypeId { get; set; }
public int CustomerId { get; set; }
public int ProductId { get; set; }
public object AttributesXml { get; set; }
public double CustomerEnteredPrice { get; set; }
public int Quantity { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime UpdatedOnUtc { get; set; }
public bool IsFreeShipping { get; set; }
public bool IsShipEnabled { get; set; }
public double AdditionalShippingCharge { get; set; }
public bool IsTaxExempt { get; set; }
}
I am using this statement to deserialzie the Json string: Response res = (Response)JsonConvert.DeserializeObject(customerJson, (typeof(Response)));
When I stop it in the debugger, it shows "res" as data: null and success: false.
I am not getting any errors. It is just not giving me the data from the Json string.
Any help that anybody can provide to figure out why I'm not getting the data I want in "res", would be gratefully appreciated.
Thanks,
Tony
The problem is related to the accessibility level in your Response class. By default the fields, property and method are private so JsonConvert is not able to fill the properties.
Change the class as follow:
class Response
{
public bool success {get; set;}
public IList<Customer> data {get; set;}
}
And it wil works.
Another improvement is related to the JsonConvert use. To avoid the explicit cast use this type conversion: JsonConvert.DeserializeObject<T>(string) where T will be Response

Windows 8 C#/XAML SuspensionManager failed

I'm writing simple imageviewer for one imageboard. I'm using these 2 classes for navigation(navigation parameter for Frame.Navigate() method) in my app:
public class KonaParameter
{
public int page { get; set; }
public string tags { get; set; }
public KonaParameter()
{
page = 1;
}
}
public class Post
{
public int id { get; set; }
public string tags { get; set; }
public int created_at { get; set; }
public int creator_id { get; set; }
public string author { get; set; }
public int change { get; set; }
public string source { get; set; }
public int score { get; set; }
public string md5 { get; set; }
public int file_size { get; set; }
public string file_url { get; set; }
public bool is_shown_in_index { get; set; }
public string preview_url { get; set; }
public int preview_width { get; set; }
public int preview_height { get; set; }
public int actual_preview_width { get; set; }
public int actual_preview_height { get; set; }
public string sample_url { get; set; }
public int sample_width { get; set; }
public int sample_height { get; set; }
public int sample_file_size { get; set; }
public string jpeg_url { get; set; }
public int jpeg_width { get; set; }
public int jpeg_height { get; set; }
public int jpeg_file_size { get; set; }
public string rating { get; set; }
public bool has_children { get; set; }
public object parent_id { get; set; }
public string status { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool is_held { get; set; }
public string frames_pending_string { get; set; }
public List<object> frames_pending { get; set; }
public string frames_string { get; set; }
public List<object> frames { get; set; }
public object flag_detail { get; set; }
}
The problem I faced is that suspending doesn't work. SuspensionManager throws "SuspensionManager failed" exception after await SuspensionManager.SaveAsync(); call(I googled that it's because of using complex types).
I tried to use string as a navigation parameter. It works, but I need more than 1 string for my parameter(List<string> doesn't work, I tried to use it).
How to suspend my app correctly?
The problem is that SuspensionManager uses Frame.GetNavigationState() to get the history of the Frame. It then tries to serialise the navigation history to a string, unfortunately it has no way to know how to serialise custom complex types as parameters like Post or KonaParameter and fails with an exception.
If you want to use SuspensionManager then you'll need to restrict yourself to simple types like int or string as parameters.
If you do need complex types then it's best to store them in some background service / repository with an identifier. You can then pass the identifier as the parameter.
The recommended approach is to serialize your "state" object, so it can be saved/restored as a string. You can use Json.NET to do this:
//save state
Post post = //...;
string state = JsonConvert.Serialize(post)
//restore state
Post post = JsonConvert.Deserialize<Post>(state);
If you want to use two objects (a Post and a KonaParameter), I'd consider creating an "aggregate" class that encapsulates both, and serializing/deserializing that instead:
public class State
{
public Post post {get; set;}
public KonaParameter param {get; set;}
}

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