0

I have the following enum:

public enum EventType
        {
            LoginSuccessfully = 1,
            LoginFailure = 2,
            UserCreated = 3,
            UnableToCreateUser = 4,
            PasswordReseted = 5,
            UnableToResetPassword = 6,
            UserDeleted = 7,
            UnableToDeleteUser = 8
        }

And I have this method:

public IActionResult GetFilteredLogs([FromBody] SearchFilterContract contract)
{
    //filter logs from database
}

Here is the contract received as parameter from my method:

 public class SearchFilterContract
    {
        public EventType? EventTypes { get; set; }
        public string Username { get; set; }
        public DateTime? fromDate { get; set; }
        public DateTime? toDate { get; set; }
        public int pageSize { get; set; }
        public int pageNumber {get; set;}

    }

If all the values from the contract are Null it gets All the values from database.

On my method I compare the variables of the contract

public SearchStatementSource(int? EventId,string username,DateTime? fromDate,DateTime? toDate,int pageSize, int PageNumber)

{
            StringBuilder sb = new StringBuilder();
 sb.AppendLine("SELECT * FROM [dbo].[eventslog] ");

            if(username != null)
            {
                sb.AppendLine("WHERE Username = @Username ");
            }
            else 
            {
                sb.AppendLine("WHERE Username IS NOT NULL ");
            }

            if(fromDate.HasValue)
            {
                sb.AppendLine("AND CreatedTime >= @fromDate ");
            }
            if(toDate.HasValue)
            {
                sb.AppendLine("AND CreatedTime <= @toDate ");
            }
            if(EventId.HasValue)
            {
                sb.AppendLine("AND EventId = @EventId ");
            }
            sb.AppendLine("AND Id >=" + startingIndex);
            sb.AppendLine("AND Id <=" + finalIndex);

            _command = sb.ToString();
Parameters.Add(new SqlParameter("@null","null"));
            AddNullable("@Username", username);
            AddNullable("@EventId", EventId);
            AddNullable("@fromDate", fromDate);
            AddNullable("@toDate",toDate);

The Int? EventId is the number received from the enum

Here's my controller method:

[HttpPost]
        [Route("[action]")]
        [AllowAnonymous]
        public IActionResult GetFilteredLogs([FromBody] SearchFilterContract contract)
        {
            try
            {
                List<EventsLog> eventsLog = _logsBl.SearchLogs(contract.EventTypes,contract.Username,contract.fromDate,contract.toDate,contract.pageNumber,contract.pageSize);
                return Ok(eventsLog);
            }
            catch(Exception ex)
            {
                return BadRequest(ex);
            }
        }

And here's my DataRepository method

public List<EventsLog> SearchLogs(EventType? EventId, string username, DateTime? fromDate, DateTime? toDate,int pageSize, int pageNumber)
        {
            List<EventsLog> logs = new List<EventsLog>();
            DataTable dt = Select(new SearchStatementSource((int)EventId,username,fromDate,toDate,pageSize,pageNumber));
            foreach(DataRow dr in dt.Rows)
            {
                logs.Add(Map(dr));
            }
            return logs;
        }

The exception is throwed when it calls on the Repository method the SearchStatementSource method

My problem here is that when I put EventTypes as Null it returns the following error:

"Nullable object must have a value"

Any ideas on how to fix this?

4
  • Possible duplicate of nullable object must have a value Commented Apr 17, 2018 at 17:08
  • I don't think it's the same scenario Commented Apr 17, 2018 at 17:13
  • The error that are you saying is an Exception that is being throwed right? Commented Apr 17, 2018 at 17:14
  • Yes correct: System.InvalidOperationException Commented Apr 17, 2018 at 17:20

1 Answer 1

1

You will have to check all the places that you use EventTypes.Value

That's because you're accessing the Value property of an null object

See here on an Fiddle

You check it first like this:

if(obj.EventTypes.HasValue)
   //Do your logic

Or if you are using C# 6 you can use this

obj.EventTypes ?? DefaultValue

Update:

Your problem is here:

DataTable dt = Select(new SearchStatementSource((int)EventId, username, [...]

You are casting EventId into int when it can be null

Change it to (int?)EventId

DataTable dt = Select(new SearchStatementSource((int?)EventId, username, [...]
Sign up to request clarification or add additional context in comments.

5 Comments

I have this logic inside my method:if(obj.EventTypes.HasValue) //Do your logic the problem is that the exception is thrown before the method
Post your logic in the question ;)
I put the logic of the data access method
Yes, but post relevant logic from where the Exception is being throwed
Thanks soo much for your help!!! It worked well! I put one positive vote on that but I don't have enough reputation. Have a nice day!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.