我们正在从web api迁移到asp .net mvc核心,我在web api中有一个动作选择器,其中如果存在url“$”符号中的任何软件,我们用来调用控制器中的特定方法。 我们使用ApiControllerActionSelector在web api中实现的这个功能是在web api中做同样的代码 -
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext) {
string urlDecode = HttpUtility.UrlDecode(
controllerContext.Request.RequestUri.ToString());
if (urlDecode != null && urlDecode.Contains("$")) {
if (controllerContext.Request.Method == HttpMethod.Post) {
MethodInfo method = controllerContext.ControllerDescriptor.ControllerType
.GetMethod(
"PostCustomOperation");
return
new ReflectedHttpActionDescriptor(
controllerContext.ControllerDescriptor, method);
}
if (controllerContext.Request.Method == HttpMethod.Get) {
MethodInfo method = controllerContext.ControllerDescriptor.ControllerType
.GetMethod(
"GetCustomOperation");
return
new ReflectedHttpActionDescriptor(
controllerContext.ControllerDescriptor, method);
}
}
HttpActionDescriptor result = base.SelectAction(controllerContext);
return result;
}
我无法找到在Asp .net mvc核心中执行相同操作的等效方法,我尝试实现IRouter但是我们必须指定控制器,但我不知道。 关于如何在Asp.net MVC核心中实现相同或不可能的任何建议?
答案 0 :(得分:1)
你想要的是uploadImage(fileToUpload: any) : Observable<any> {
let input = new FormData();
input.append("image", fileToUpload);
return this.http.post('http://Api.app/api/v1/upload', input)
.map(
(response: Response) => {
// I was missing this part
response.json()
}
);
}
。您可以在ConfigureServices IActionSelector
中为其注册实现。默认实现是services.AddSingleton<IActionSelector, CustomActionSelector>()
,您可以在自定义实现中委托它。
答案 1 :(得分:0)
我选择替换IActionInvokerFactory
。它更短。这是实现。然后,我创建自己的IActionInvoker包装器。
我的目标是在必要时再次调用控制器操作。
public class PolicyActionInvokerFactory : IActionInvokerFactory
{
private readonly IEFConcurrencyService efConcurrencyService;
private readonly IActionInvokerProvider[] actionInvokerProviders;
public PolicyActionInvokerFactory(
IEFConcurrencyService efConcurrencyService,
IEnumerable<IActionInvokerProvider> actionInvokerProviders
)
{
this.efConcurrencyService = efConcurrencyService;
this.actionInvokerProviders = actionInvokerProviders.OrderBy(item => item.Order).ToArray();
}
public IActionInvoker CreateInvoker(ActionContext actionContext)
{
var context = new ActionInvokerProviderContext(actionContext);
foreach (var provider in actionInvokerProviders)
{
provider.OnProvidersExecuting(context);
}
for (var i = actionInvokerProviders.Length - 1; i >= 0; i--)
{
actionInvokerProviders[i].OnProvidersExecuted(context);
}
return new RetryActionInvoker(efConcurrencyService, context.Result, actionContext);
}
class RetryActionInvoker : IActionInvoker
{
private readonly IEFConcurrencyService efConcurrencyService;
private readonly IActionInvoker inner;
private readonly ActionContext actionContext;
public RetryActionInvoker(
IEFConcurrencyService efConcurrencyService,
IActionInvoker inner,
ActionContext actionContext
)
{
this.efConcurrencyService = efConcurrencyService;
this.inner = inner;
this.actionContext = actionContext;
}
public Task InvokeAsync()
{
var methodInfo = actionContext.ActionDescriptor;
var shouldUseRetryLogic = methodInfo.EndpointMetadata.Any(m => m is RetryOnDbExceptionAttribute);
if (shouldUseRetryLogic)
{
return efConcurrencyService.RetryOnError(() => {
// You will need to rewind the body here if you are using [FromBody]
// This is a little out of scope, but you should EnableBuffering()
// Then rewind the body with something like this:
// actionContext.HttpContext.Request.Body.Seek(0, System.IO.SeekOrigin.Begin);
return inner.InvokeAsync();
});
}
return inner.InvokeAsync();
}
}
}