How to include Query String in the route resolution in order to allow multiple Actions with the same Method, Route and Query String?

后端 未结 2 1138
醉酒成梦
醉酒成梦 2021-01-24 13:03

I am converting an ASP.NET MVC (.NET Framework) application to ASP.NET Core MVC. This is strictly a conversion, I cannot make any breaking changes hence I cannot change any Rout

相关标签:
2条回答
  • 2021-01-24 13:19

    Why not use a single endpoint instead? You don't need to pass Guid's, since it's a GET operation, you can pass strings and cast them later. That way you can send one parameter or the other.

    [HttpPut]
    [Route("status")]
    public async Task<IActionResult> UpdateStatus([FromBody] POST_Status statusModel, [FromQuery] string orderGUID = null, [FromQuery] string id = null)
    {
        if (!string.IsNullOrEmpty(orderGUID))
        {
            // UpdateStatusByOrderGuid implementation here
            // Guid guid = Guid.Parse(orderGUID);
    
        }
        else if (!string.IsNullOrEmpty(id))
        {
            // UpdateStatusById implementation here
            // Guid guid = Guid.Parse(id);
        }
        else
        {
            throw new ArgumentException("No valid GUID.");
        }
    }
    

    This endpoint should be compatible with both scenarios you specified.

    0 讨论(0)
  • 2021-01-24 13:32

    You needs to custom ActionMethodSelectorAttribute:

    1.QueryStringConstraintAttribute:

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class QueryStringConstraintAttribute : ActionMethodSelectorAttribute
    {
        public string ValueName { get; private set; }
        public bool ValuePresent { get; private set; }
        public QueryStringConstraintAttribute(string valueName, bool valuePresent)
        {
            this.ValueName = valueName;
            this.ValuePresent = valuePresent;
        }
        public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
        {
            var value = routeContext.HttpContext.Request.Query[this.ValueName];
            if (this.ValuePresent)
            {
                return !StringValues.IsNullOrEmpty(value);
            }
            return StringValues.IsNullOrEmpty(value);
        }
    }
    

    2.Controller:

    [HttpPut]
    [Route("status")]
    [QueryStringConstraint("orderGUID",true)]
    [QueryStringConstraint("id", false)]
    public void UpdateStatusByOrderGuid([FromQuery] Guid orderGUID,[FromBody]POST_Status model)
    {
    
    }
    
    [HttpPut]
    [Route("status")]
    [QueryStringConstraint("id", true)]
    [QueryStringConstraint("orderGUID", false)]
    public void UpdateStatusById([FromQuery] Guid id, [FromBody]POST_Status model)
    {
    
    }
    

    3.Startup.cs:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    

    Result:

    0 讨论(0)
提交回复
热议问题