2

Is it possible to have two actions with same route name and same method but different parameter? I have tried this:

[HttpPost]
[Route("gstr4")]
public HttpResponseMessage SubmitGSTR4([FromBody] RequestPayloadWithoutSign requestPayload)
{ }

[HttpPost]
[Route("gstr4")]
public HttpResponseMessage FileGSTR4([FromBody] RequestPayloadWithSign requestPayload)
{ }

I received a Status Code of 500 (InternalServerError) and here is raw response:

{"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were found that match the request: \r\nFileGSTR4 on type APIPortal.Controllers.GSTR4Controller\r\nSubmitGSTR4 on type APIPortal.Controllers.GSTR4Controller","ExceptionType":"System.InvalidOperationException","StackTrace":"   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}
6
  • 1
    Its not possible Commented Jun 1, 2020 at 7:23
  • But its possible for HttpGet ? Commented Jun 1, 2020 at 7:26
  • 1
    No, its not possible. You can have identical route with different http state, ie. (get, post). But that will not possible to have two GET with same route. Commented Jun 1, 2020 at 7:28
  • @RithikBanerjee that is also not possible Commented Jun 1, 2020 at 7:30
  • can a request map one method among two methods? Commented Jun 1, 2020 at 7:44

3 Answers 3

3

It's not possible to have many actions with the same route and the same HTTP verb.

What you could do is to have a single action which accepts a model of a base class (possibly an abstract class) and a custom resolver.

Example:

public abstract class RequestPayload 
{
}

public class RequestPayloadWithoutSign : RequestPayload
{
}

public class RequestPayloadWithSign : RequestPayload
{
   public string Sign { get; set; }
}

public class MyController
{
    [HttpPost]
    [Route("gstr4")]
    public HttpResponseMessage SubmitGSTR4([FromBody] RequestPayload payload)
    {
        switch(payload)
        {
            case RequestPayloadWithoutSign a:
                // handle RequestPayloadWithoutSign
                break;
            case RequestPayloadWithSign b:
                // handle RequestPayloadWithSign
                break;
        }
    }
}

And, if you're using JSON mediatype for transmitting payloads, a custom JSON resolver attached to your JSON deserializer. Here's an example for Newtonsoft.Json:

class HolderConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(RequestPayload);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        if (jo.ContainsKey("sign"))
        {
            return new RequestPayloadWithSign
            {
                Sign = (string) jo["sign"]
            };
        }

        return new RequestPayloadWithoutSign();
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Now add the converter to serializer settings or mark your RequestPayload class definition with [JsonConverter(typeof(RequestPayload))] attribute and it will start converting JSONs to either RequestPayloadWithSign or RequestPayloadWithoutSign types.

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

Comments

0

It's not possible for the same method type as http Get for multiple methods. You should have a different route

2 Comments

There has to be some or other way.
It's not possible wit the same verb
0

It is only possible with different HTTP verbs. Otherwise, you have to define different routes.

https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

2 Comments

if the request payload is of model A then it should hit action with parameter A and if the request payload is of model B then it should hit action with parameter B. Possible?
I don't think you can do it with custom objects. One way to trick it is, to have one method and then delegate based on the payload. Check the following link:-stackoverflow.com/questions/14353466/…

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.