1

I have strict API routing requirements. This must be a Get request and the routing cannot be changed. The user can search for people by name, but he can also search for them by part of the name:

api/People?name=Tom - "Tom" can be in any part of the name, ignore case

api/People?name:contains=Tom - "Tom" must be at the beginning of the name, ignore case

api/People?name:exact=Tom - "Tom" must be case sensitive

How it should be implemented in the controller?

There is an option with 3 parameters, can this be improved?

    public async Task<IActionResult> GetByName(
        [FromQuery(Name = "name")] string name, 
        [FromQuery(Name = "name:contains")] string beginName, 
        [FromQuery(Name = "name:exact")] string exactName)
Yiyi You
  • 16,875
  • 1
  • 10
  • 22
  • May I suggest "public HttpResponseMessage Post([FromBody]FormDataCollection formbody)". Check out this link for details https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api – Lucarob Oct 20 '20 at 14:44
  • Thank you, unfortunately this must be a get request and the solution is not suitable for me. I corrected the description – TomBrowster Oct 21 '20 at 05:14
  • I will use two parameters like `name` and `operator`. – vernou Oct 21 '20 at 08:13

1 Answers1

0

You can use custom model binding,here is a demo: NameModel:

public class NameModel {
        public string name { get; set; }
        public string beginName { get; set; }
        public string exactName { get; set; }
    }

Controller:

        [Route("/GetByName")]
        public async Task<IActionResult> GetByName([ModelBinder(typeof(NameBinder))]NameModel nameModel)
        {
            return Ok();
        }

NameBinder:

 public class NameBinder:IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var model1 = new NameModel();
            var name=bindingContext.ValueProvider.GetValue("name").FirstValue;
            var beginName = bindingContext.ValueProvider.GetValue("name:contains").FirstValue;
            var exactName = bindingContext.ValueProvider.GetValue("name:exact").FirstValue;
            if (name.ToLower().Contains("tom")) {
                model1.name = name;
            }
            if (beginName.ToLower().StartsWith("tom")) {
                model1.beginName = beginName;
            }
            if (exactName.Contains("Tom")) {
                model1.exactName = exactName;
            }
            bindingContext.Result = ModelBindingResult.Success(model1);
            return Task.CompletedTask;
        }
    }

result: enter image description here

Yiyi You
  • 16,875
  • 1
  • 10
  • 22