是否可以将代码提取到委托中?
Is it possible to extract code into delegate?
更新:
我遇到的问题是模型验证,但我发现当模型传递给 Action 时 FluentValidation 已经解决了这个问题,所以我的问题并不完全正确并且可能具有误导性。我会关闭它(如果找到如何操作)。
我有以下代码:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
try
{
**await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction("Index");**
}
catch (ValidationException vldEx)
{
foreach (var vldError in vldEx.Errors)
{
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
try里面的文字随着controller的不同动作不同而不同,其他都是一样的。是否可以将公共代码提取到基class中的函数中?
我尝试使用 Func,但无法找到正确的方法。
我正在寻找这样的东西:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
FunctionWithCommonCode(x =>
{
await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction("Index");
});
}
不需要委托或任何复杂的东西,只需创建一个您从每个操作调用的基本方法并传入您需要的字符串,例如:
private async Task<IActionResult> CreateBase(CreateAccountViewModel model, string action)
{
try
{
await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction(action);
}
catch (ValidationException vldEx)
{
foreach (var vldError in vldEx.Errors)
{
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
操作方法如下所示:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
return await CreateBase(model, "Index");
}
我无法编译它 - 有太多对您未提供的代码的依赖。如果您可以提供最小的、完整的和可验证的示例 (https://whosebug.com/help/minimal-reproducible-example),并有足够的存根 类 来编译您的示例代码(不依赖于您不提供的代码),那么我会更新我的回答。
但是,如果我理解你的问题,你需要做的是创建一个方法来完成除了你的 **star-ed**
代码之外的所有事情,并将带星号的代码作为参数传递给适当的委托类型。抱歉,但是因为我无法编译,所以我不确定我是否在正确的位置进行了异步和等待。但是,这应该会给您一个良好的开端。
因此,您从提供所有样板的辅助函数开始:
private async Task<IActionResult> WebWorker<TModel> (TModel model, Func<TModel, Task<IActionResult>> workToDo) {
try {
return await workToDo(TModel model);
} catch (ValidationException vldEx) {
foreach (var vldError in vldEx.Errors) {
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
该函数采用您的模式和适当 Func<>
类型的委托。
然后你可以这样称呼它:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model) {
return await WebWorker<CreateAccountViewModel>(model,
m => {
Mediator.Send(_mapper.Map<CreateAccountCommand>(m));
return RedirectToAction("Index");
});
}
请注意,WebWorker
函数的第二个参数是一个 Lambda,其签名与声明为该函数第二个参数的 Func 的签名匹配。
更新: 我遇到的问题是模型验证,但我发现当模型传递给 Action 时 FluentValidation 已经解决了这个问题,所以我的问题并不完全正确并且可能具有误导性。我会关闭它(如果找到如何操作)。
我有以下代码:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
try
{
**await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction("Index");**
}
catch (ValidationException vldEx)
{
foreach (var vldError in vldEx.Errors)
{
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
try里面的文字随着controller的不同动作不同而不同,其他都是一样的。是否可以将公共代码提取到基class中的函数中? 我尝试使用 Func,但无法找到正确的方法。 我正在寻找这样的东西:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
FunctionWithCommonCode(x =>
{
await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction("Index");
});
}
不需要委托或任何复杂的东西,只需创建一个您从每个操作调用的基本方法并传入您需要的字符串,例如:
private async Task<IActionResult> CreateBase(CreateAccountViewModel model, string action)
{
try
{
await Mediator.Send(_mapper.Map<CreateAccountCommand>(model));
return RedirectToAction(action);
}
catch (ValidationException vldEx)
{
foreach (var vldError in vldEx.Errors)
{
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
操作方法如下所示:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model)
{
return await CreateBase(model, "Index");
}
我无法编译它 - 有太多对您未提供的代码的依赖。如果您可以提供最小的、完整的和可验证的示例 (https://whosebug.com/help/minimal-reproducible-example),并有足够的存根 类 来编译您的示例代码(不依赖于您不提供的代码),那么我会更新我的回答。
但是,如果我理解你的问题,你需要做的是创建一个方法来完成除了你的 **star-ed**
代码之外的所有事情,并将带星号的代码作为参数传递给适当的委托类型。抱歉,但是因为我无法编译,所以我不确定我是否在正确的位置进行了异步和等待。但是,这应该会给您一个良好的开端。
因此,您从提供所有样板的辅助函数开始:
private async Task<IActionResult> WebWorker<TModel> (TModel model, Func<TModel, Task<IActionResult>> workToDo) {
try {
return await workToDo(TModel model);
} catch (ValidationException vldEx) {
foreach (var vldError in vldEx.Errors) {
ModelState.AddModelError(vldError.PropertyName, vldError.ErrorMessage);
}
return View(model);
}
}
该函数采用您的模式和适当 Func<>
类型的委托。
然后你可以这样称呼它:
[HttpPost]
public async Task<IActionResult> Create(CreateAccountViewModel model) {
return await WebWorker<CreateAccountViewModel>(model,
m => {
Mediator.Send(_mapper.Map<CreateAccountCommand>(m));
return RedirectToAction("Index");
});
}
请注意,WebWorker
函数的第二个参数是一个 Lambda,其签名与声明为该函数第二个参数的 Func 的签名匹配。