2

Hello,

I have api GET-method /rating (ASP.Net WebApi 2.1), which accepts objects of type ChartPageRequest:

// comments're removed for readability
public sealed class ChartPageRequest
{
    public DateTime? From { get; set; }

    public DateTime? To { get; set; }

    public string Cursor { get; set; }

    [Range(-100, 100)]
    public int Take { get; set; } = 10;
}

/rating method has following signature:

[HttpGet]
[Route("rating")]
[ResponseType(typeof(ChartPage))]
[ValidateModelState]
public async Task<IHttpActionResult> GetTranslationRatingChartAsync([ModelBinder] ChartPageRequest model)
{
    // body here
}

And ValidateModelState attribute is just a custom attribute which returns custom response when ModelState isn't valid. It doesn't check anything by itself except HttpActionContext.ModelState.IsValid property.

This api method works fine except one case - when client explicitly passes null value to DateTime? properties of ChartPageRequest, e.g.:

/rating?from=2016-07-08 12:01:55.604&to=null

In this case ValidateModelState attribute registers invalid ModelState with following message: The value 'null' is not valid for To.

I've found this kind of problem quite popular, but haven't found any good workarounds without creating custom model binder. So here's the questions:

  1. Is there another approach without custom model binder?

  2. In case there isn't, how can I take only "accepting null" job and leave DateTime parsing to default binder in my custom binder?

  3. Do I need to accept those nulls at all? All clients are developing by my colleagues so I can force them to not send it. Is it good practice after all?

Thanks!

4
  • 3
    Do not include the value at all in the query string. If you have external clients that are not controlled by you then you should inform them or update the documentation so that they know that null values should be omitted. This goes for everything that you pass, not just this date time. If you try it with an int? or a string you will also get unexpected results (error with the int, probably a literal "null" string with the string assinment). Commented Sep 19, 2016 at 14:07
  • @Igor, I'll update my question and will ask if it's good practice. Thank you Commented Sep 19, 2016 at 14:09
  • Check this answer if you want to include it in the query string even if there is no value: . /rating?from=2016-07-08 12:01:55.604&to=%00. I recommend just omit it though if it is not necessary. As to what best practice is that might be a matter of opinion. Commented Sep 19, 2016 at 14:17
  • Oh, thanks again, mate! I always thought this problem doesn't exist for the others primitive types and I've just realized it's not true :) Ok, so this problem is about passing nulls at all. It seems I need to talk with api clients ;) Commented Sep 19, 2016 at 14:23

1 Answer 1

0

I didn't validate this method, but I guess you can try parse it yourself, though I think it's not a convenient way, first use a string to get the To:

public string To { get; set; }

And give another property DateTimeTo and parse To yourself:

public DateTime? DateTimeTo { get; set; }

public void ParseTo()
{
    if(To.ToLower() == "null")
        DateTimeTo = null;
    else
        DateTimeTo = Convert.ToDateTime(To); 
}

And DateTimeTo is the parsed result property.

I recently ran into some Asp.Net WebApi parsing body issue, the parsing doesn't work very well in some condition.

Sign up to request clarification or add additional context in comments.

Comments

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.