-1

I'm trying to create custom exceptions for a Web-API program, if the name, code or whatever is null, it should send me a custom message saying x input is empty or null error, I'm not sure how to finish it so I'd appreciate some help.

public Product CreateProduct(Product p)
{    
    if (p.Name.Trim() == "")
    {
        throw new InvalidProductDataException("El producto no tiene nombre");
    }
    return p;                     
}

enter image description here

ggeorge
  • 1,496
  • 2
  • 13
  • 19
  • If you want to check a string for null or an empty value, you can use the method string.IsNullOrWhiteSpace to simplify the check. See more at: https://learn.microsoft.com/en-us/dotnet/api/system.string.isnullorwhitespace?view=net-5.0 – Zokka May 12 '21 at 20:39
  • 1
    That would normally result in a 400 Bad Request and a message stating what was wrong with the data so that the consumer can try to fix it. – Crowcoder May 12 '21 at 20:43
  • but if I don't want to use the string.IsNull exception and want to create mine called InvalidProductDataException, how can I do it? – Paola Vilaseca May 12 '21 at 20:54
  • 1
    `String.IsNullOrWhitespace` (and `String.IsNullOrEmpty`) aren't Exceptions, they're just static functions that return true or false. Zokka is just suggesting that using `.Trim()` and checking for equality with `""` is not the most elegant way to perform this check. – Paul Wheeler May 12 '21 at 21:22
  • Does this answer your question? [How to write User Defined exceptions in C#?](https://stackoverflow.com/questions/3852751/how-to-write-user-defined-exceptions-in-c) – Paul Wheeler May 12 '21 at 23:39
  • @PaolaVilaseca Based on various comments it is very unclear what you are actually trying to accomplish. What do you mean by "the name, code or whatever"? What do you mean by "it should send me a custom message"? What behavior are you currently seeing, and are you seeing it on the API Web Server, or on a client that is calling this API via HTTP? How does that behavior differ from your desired behavior? – Paul Wheeler May 12 '21 at 23:46
  • One thing I should point out is that `p.Name.Trim()` will throw a `NullReferenceException` if either `p` or `p.Name` is null. So if you want to handle those cases you should check for them explicitly. However **that is one reason everybody keeps telling you to use `String.IsNullOrWhitespace` because that will fix this issue**. – Paul Wheeler May 12 '21 at 23:48

3 Answers3

2

I'm assuming CreateProduct is an action method on a Controller class, and what you are actually trying to do is return errors to a client that is calling your API. Therefor, the easiest way to return errors to an HTTP client is by using the IActionResult return type instead of returning your actual type. This will give you control over the HTTP status code.

class ProductController : Controller {

  public IActionResult CreateProduct(Product p)
  {
    if (String.IsNullOrWhitespace(p.Name))
    {
      return BadRequest("El producto no tiene nombre");
    }

    // Perform create?
    return Ok(p);   
  }
}

For more information on controller action return types see: https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-5.0

Any kind of exception thrown from a controller action is going to result in an opaque HTTP 500 response sent to the API client, which probably isn't what you want for this kind of error.

An alternative is to introduce Middleware that will capture certain types of exception and convert them to HTTP responses.

Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41
  • I'm trying not to use String.IsNullOrWhitespace(p.Name) but create an exception with InvalidProductDataException – Paola Vilaseca May 12 '21 at 23:06
  • I'll be honest @PaolaVilaseca, I don't think you actually understand what you are trying to do. However, if you really want to define and throw a custom exception type, I've posted an alternative answer on how to do that. However I've also flagged this question as a duplicate of https://stackoverflow.com/questions/3852751/how-to-write-user-defined-exceptions-in-c – Paul Wheeler May 12 '21 at 23:41
1

Let's define a custom exception named LoginException that will be used to throw an error exception in login processes.

public class LoginException : System.Exception
    {
       //todo
    }

Now let's make the necessary constructor definitions for use in the application.

public class LoginException : System.Exception
 {
     public LoginException()
         : base()
     { }
 
     public LoginException(String message)
         : base(message)
 
     { }
 
     public LoginException(String message, Exception innerException)
         : base(message, innerException)
     { }
 
     protected LoginException(SerializationInfo info, StreamingContext context)
         : base(info, context)
     { }
 }

As seen above, we have defined the constructors of LoginException and made the constructor redirects for the System.Exception class, so we made the LoginException class ready for use.

void Login(string userName, string password)
       {
           try
           {
               if (userName != "canert" && password != "qwerty123")
                   throw new LoginException("Invalid login operation");
           }
           catch (LoginException loginException)
           {
               Response.Write(loginException.Message);
           }
       }
H.S
  • 190
  • 13
0

If you want to throw a custom type of exception called InvalidProductDataException then you need to declare a class with that name and it needs to be a subclass of System.Exception:

public class InvalidProductDataException : System.Exception {
    public InvalidProductDataException(String message) : base(message) {
    }

    // This constructor overload is necessary to allow for your Exception to be deserialized. This is a best practice when implementing custom Exception types.
    protected InvalidProductDataException(SerializationInfo info, StreamingContext context) :
      base(info, context) {

      // If you exception contained custom properties, you would want to deserialize them here
    }
}

For more information on creating custom Exception classes see: https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions

Note: It is not necessary to create a custom Exception class just to be able to specify the message that you want. For example you could simply throw new Exception("your message"). However it does make sense to create a custom Exception class if you want to be able to catch that specific exception elsewhere in your code.

Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41