Suggestion for a business logic

Cenk 1,021 Reputation points
2023-06-01T08:02:40.2633333+00:00

Hi,

I am working on an ASP.NET Core web API. The user sends product code (A12345) and quantity (1) in order to get a valid response from my API. Now requirements have changed. Some product codes must be sent with quantity and price. How can I associate price with related products? How to make the price required for related product codes in the DTO?

Is there any solution you can suggest?

Thank you.

public class RequestDto
    {
        [Required(ErrorMessage = "Please add Product Code to the request.")]
        [MaxLength(15, ErrorMessage = "The product code can not be more than 15 characters")]
        public string productCode { get; set; }

        [Required(ErrorMessage = "Please add Quantity to the request.")]
        [Range(1, 100, ErrorMessage = "The quantity must be added.(quantity = 1)")]
        public int quantity { get; set; }
        [SwaggerSchema(ReadOnly = true)]
        public string? clientTrxRef { get; set; }

    }
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,596 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
341 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,436 Reputation points Microsoft Vendor
    2023-06-14T06:25:20.4166667+00:00

    Hi @Cenk

    How can I validate the price with data annotations if it is not a mandatory property? Let's say if productCode is ABC then there is no need for price. If the productCode is DEF then the price should be required in the request.

    You can create a Custom validation, like this:

        public class RequestDto 
        {
            [Required(ErrorMessage = "Please add Product Code to the request.")]
            [MaxLength(15, ErrorMessage = "The product code can not be more than 15 characters")]
            public string productCode { get; set; }
    
            [Required(ErrorMessage = "Please add Quantity to the request.")]
            [Range(1, 100, ErrorMessage = "The quantity must be added.(quantity = 1)")]
            public int quantity { get; set; } 
            public string? shopNo { get; set; } 
            public string? safeNo { get; set; } 
            public string? cashierNo { get; set; } 
            public string? clientTrxRef { get; set; }
    
            [RequiredIf("productCode")]
            public string? price { get; set; } 
        }
    

    custom validation:

        //using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
        //using System.ComponentModel.DataAnnotations;
        [AttributeUsage(AttributeTargets.Property)]
        public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
        {
            private string PropertyName { get; set; }
            public RequiredIfAttribute(string propertyName)
            {
                PropertyName = propertyName;
            }
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
                //get the userprofile instance
                object instance = validationContext.ObjectInstance;
                Type type = instance.GetType();
                //get the property value based on the property name. Here we can get the IsChangePassword value.
                var propertyValue = type.GetProperty(PropertyName).GetValue(instance)?.ToString();
    
                //check whether the IsChangePassword checkbox is checked, if yes, validate the password. if not, ignore the password validation.
                if (string.IsNullOrWhiteSpace(value?.ToString()) && propertyValue =="DEF")
                {
                    return new ValidationResult(ErrorMessage);
                }
                return ValidationResult.Success;
            }
            public void AddValidation(ClientModelValidationContext context)
            {
                MergeAttribute(context.Attributes, "data-val", "true");
                MergeAttribute(context.Attributes, "data-val-requiredif", "Since checked the ChangePasswork, please enter tne new password");
            }
            public static bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
            {
                if (attributes.ContainsKey(key))
                {
                    return false;
                }
                attributes.Add(key, value);
                return true;
            }
        }
    

    The result as below: if productCode is ABC then there is no need for price. If the productCode is DEF then the price should be required in the request.

    User's image


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Dillion

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.