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
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.
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: