5
votes

Why do I get the error in the screenshot below when attempting to call a Web API method that takes a enum as an input parameter? How do I resolve this?

It appears like the messageDestinationType is always null no matter what I do...

I would prefer to keep the input type as an enum. I am newish to using web apis and can't understand how this is so difficult when a WCF handles this scenario perfectly

[JsonConverter(typeof(StringEnumConverter))]    
public enum MessageDestinationType
{
    None = 0,
    [EnumMember(Value = "SMS")]
    SMS = 1,
    [EnumMember(Value = "Email")]
    Email = 2,
    PushNotification = 3,
    UXP = 4,
    IntermediaryApp = 5,
    YouthApp = 6
}



    [HttpPost, Route("ReadClientMessagesC")]
    public IHttpActionResult ReadClientMessagesC([FromBody]MessageDestinationType messageDestinationType)
    {
        var request = new ClientInboxRequest
        {
            Gcn = Gcn,
            ClientIpAddress = ClientIpAddress,
            CallingApplication = CallingApplication.Name,
            CallingApplicationVersion = CallingApplication.Version,
            CookieString = CookieString,
            HasPbUk = HasPbUk,
            HasIamIms = HasIamIms,
            HasPbZa = HasPbZa,
            HasSps = HasSps,
            HasWiUk = HasWiUk,
            HasWiZa = HasWiZa,
            LinkedGcns = LinkedGcns,
            RequestId = RequestId.ToString(),
            SsoProfiles = SsoProfiles.Select(x => x.Name).ToList()
        };

        MessageDestinationType messageDestination = (MessageDestinationType)messageDestinationType;

        return Ok(ClientMessageCenterHelper.ReadClientMessagesA(Gcn, messageDestination, request));
    }

enter image description here

Error message: { "Message": "The request is invalid.", "MessageDetail": "The parameters dictionary contains a null entry for parameter 'messageDestinationType' of non-nullable type 'API.Domain.ClientMessageCenter.MessageDestinationType' for method 'System.Web.Http.IHttpActionResult ReadClientMessagesC(API.Domain.ClientMessageCenter.MessageDestinationType)' in 'ID.ClientMessageCenter.Controllers.ClientMessageCenterController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter." }

3
Could you copy and paste the error in to the question as not everyone will be able to see the attached image and it will be easier to read.phuzi
Have you tried to send the json like: { "messageDestinationType": 2 }?Tiago Ávila
@TiagoÁvila, yes unfortunately it gives me the same error messageBossRoss

3 Answers

1
votes

You can send a string (string name of an enum) to the Web API Controller (even if it has a numeric value like the one in OP's example). ASP.NET framework already has provisions for this conversion to happen automatically - you just need to enable it.

In your Startup.cs ConfigureServices method, add your converter to the JsonSerializerOptions.Converters property.

services.AddControllers()
    .AddJsonOptions(opts =>
    {
        opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        opts.JsonSerializerOptions.IgnoreNullValues = true;
    });

I would also suggest setting IgnoreNullValues as well to a setting of your preference to make it very explicit.

Credit: I solved my problem from this post (by regisdiogo) and shamelessly copied it here :-)

0
votes

You should choose either a string or an integer in place of the enum for this.

Then parse this to your enum if you still need to use it.

Personally I would prefer an integer if I was consuming your RESTful API as you are effectively exposing a Type here. You could make these types available via a Get / GetAll method which keeps your API maintainable.

-1
votes

You have a few different options to solve this:

  • If you can change the data that is being sent to ReadClientMessagesC, pass the data as an int (the Enum value) rather than the Enum description.
  • If you can't change the incoming data, change the parameter type to string and use Enum.Parse in the method body or;
  • Keep the method as written and use a custom model binder to convert the string to the MessageDestinationType.