Asp.net 5 个网站 api 自定义 ActionResult
Asp.net 5 web api Custom ActionResult
这是我对自定义 ActionResult 的实现
public class ResultData<T>
{
public string Code { get; set; }
public string Massage { get; set; }
public T Result { get; set; }
}
public class BaseApiResult<T> : JsonResult
{
public BaseApiResult() : base(null)
{
ContentType = "application/json";
}
public IActionResult Success(T result)
{
Value = new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
};
StatusCode = 200;
return this;
}
public IActionResult Fail(T result, string code, string massage)
{
Value = new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
};
StatusCode = 400;
return this;
}
public IActionResult ServerError(T result)
{
Value = new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
};
StatusCode = 500;
return this;
}
}
现在我们这样称呼它
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
var res = _entityFrameworkCoreService.GetAllProducts();
if (res.Count <= 0)
{
return new BaseApiResult<string>().Fail(null, "4002", "NoRecord found");
}
return new BaseApiResult<IList<DtoProSubCat>>().Sucsees(res); ;
}
catch (Exception ex)
{
return new BaseApiResult<string>().ServerError(ex.Message);
}
}
现在我要问的是:-
1- 这是 ActionResult 的错误实现吗?
2- 此实现是否存在性能问题?
3- 是否有任何增强功能可以添加到此实现中?
3- 实现自定义 ActionResult 的最佳实践是什么?
上面的方法还是可以的,但是个人觉得不太好。
首先,您真正需要的是 return 包裹在 ResultData 中的结果。
这被认为是一种数据模型,而不是一种行为。要知道,IActionResult不仅仅是return数据,在AspMVC运行模型中,它也是HTTP服务器的输出处理程序。
我提出以下几种方案,相信会更适合。
方法一:为ControllerBase创建一个基础class。
例如:
public class ControllerBase : Microsoft.AspNetCore.Mvc.Controller
{
protected IActionResult MyResult <T> (int statusCode, ResultData<T> result)
{
var jsonResult = Json(result);
jsonResult.StatusCode = statusCode;
return jsonResult;
}
protected IActionResult Success <T> (T result)
{
return MyResult(200, new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
});
}
protected IActionResult Fail <T> (T result, string code, string massage)
{
return MyResult(400, new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
});
}
protected IActionResult ServerError<T>(T result)
{
return MyResult(500, new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
});
}
}
/** implement */
public class HomeController : ControllerBase
{
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //
if (res.Count <= 0)
{
return Fail<string>(null, "4002", "NoRecord found");
}
return Success<IList<DtoProSubCat>>(res); ;
}
catch (Exception ex)
{
return ServerError(ex.Message);
}
}
}
有点类似的方法是为 Controller 创建一个扩展函数,或者您将创建一个包含处理数据的函数的静态 class。
方法二:为每个响应行为创建一个特定的class。
例如:
public class SuccessResult <T> : JsonResult
{
public SuccessResult (T result)
: base(new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
})
{
StatusCode = 200;
}
}
public class FailResult<T> : JsonResult
{
public FailResult(T result, string code, string massage)
: base(new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
})
{
StatusCode = 400;
}
}
public class ServerErrorResult<T> : JsonResult
{
public ServerErrorResult(T result)
: base(new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
})
{
StatusCode = 500;
}
}
/** implement */
public class HomeController : Controller
{
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //
if (res.Count <= 0)
{
return new FailResult<string>(null, "4002", "NoRecord found");
}
return new SuccessResult<IList<DtoProSubCat>>(res); ;
}
catch (Exception ex)
{
return new ServerErrorResult<string>(ex.Message);
}
}
}
你上面的实现方式使得几行命令毫无意义,当然在应用程序的运行ning期间没有太大问题,但在长时间的运行中会影响扩展或维护过程。以上两种方式帮你保护函数的运行模型,最小化源代码,最小化无意义的命令行。
这个 V2 怎么样,因为 @Henry Trần 给出了提示
public class BaseApiResultV2
{
private IActionResult SetResult<T>(int statusCode, ResultData<T> result)
{
JsonResult jsonResult = new(result)
{
StatusCode = statusCode,
ContentType = "application/json"
};
return jsonResult;
}
public IActionResult Success<T>(T result)
{
return SetResult(StatusCodes.Status200OK,
new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
});
}
public IActionResult Fail<T>(T result, string code, string massage)
{
return SetResult(StatusCodes.Status400BadRequest,
new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
});
}
public IActionResult ServerError<T>(T result)
{
return SetResult(StatusCodes.Status500InternalServerError,
new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
});
}
private struct ResultData<T>
{
public string Code { get; set; }
public string Massage { get; set; }
public T Result { get; set; }
}
}
这是我对自定义 ActionResult 的实现
public class ResultData<T>
{
public string Code { get; set; }
public string Massage { get; set; }
public T Result { get; set; }
}
public class BaseApiResult<T> : JsonResult
{
public BaseApiResult() : base(null)
{
ContentType = "application/json";
}
public IActionResult Success(T result)
{
Value = new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
};
StatusCode = 200;
return this;
}
public IActionResult Fail(T result, string code, string massage)
{
Value = new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
};
StatusCode = 400;
return this;
}
public IActionResult ServerError(T result)
{
Value = new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
};
StatusCode = 500;
return this;
}
}
现在我们这样称呼它
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
var res = _entityFrameworkCoreService.GetAllProducts();
if (res.Count <= 0)
{
return new BaseApiResult<string>().Fail(null, "4002", "NoRecord found");
}
return new BaseApiResult<IList<DtoProSubCat>>().Sucsees(res); ;
}
catch (Exception ex)
{
return new BaseApiResult<string>().ServerError(ex.Message);
}
}
现在我要问的是:-
1- 这是 ActionResult 的错误实现吗?
2- 此实现是否存在性能问题?
3- 是否有任何增强功能可以添加到此实现中?
3- 实现自定义 ActionResult 的最佳实践是什么?
上面的方法还是可以的,但是个人觉得不太好。 首先,您真正需要的是 return 包裹在 ResultData 中的结果。 这被认为是一种数据模型,而不是一种行为。要知道,IActionResult不仅仅是return数据,在AspMVC运行模型中,它也是HTTP服务器的输出处理程序。
我提出以下几种方案,相信会更适合。
方法一:为ControllerBase创建一个基础class。 例如:
public class ControllerBase : Microsoft.AspNetCore.Mvc.Controller
{
protected IActionResult MyResult <T> (int statusCode, ResultData<T> result)
{
var jsonResult = Json(result);
jsonResult.StatusCode = statusCode;
return jsonResult;
}
protected IActionResult Success <T> (T result)
{
return MyResult(200, new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
});
}
protected IActionResult Fail <T> (T result, string code, string massage)
{
return MyResult(400, new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
});
}
protected IActionResult ServerError<T>(T result)
{
return MyResult(500, new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
});
}
}
/** implement */
public class HomeController : ControllerBase
{
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //
if (res.Count <= 0)
{
return Fail<string>(null, "4002", "NoRecord found");
}
return Success<IList<DtoProSubCat>>(res); ;
}
catch (Exception ex)
{
return ServerError(ex.Message);
}
}
}
有点类似的方法是为 Controller 创建一个扩展函数,或者您将创建一个包含处理数据的函数的静态 class。
方法二:为每个响应行为创建一个特定的class。 例如:
public class SuccessResult <T> : JsonResult
{
public SuccessResult (T result)
: base(new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
})
{
StatusCode = 200;
}
}
public class FailResult<T> : JsonResult
{
public FailResult(T result, string code, string massage)
: base(new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
})
{
StatusCode = 400;
}
}
public class ServerErrorResult<T> : JsonResult
{
public ServerErrorResult(T result)
: base(new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
})
{
StatusCode = 500;
}
}
/** implement */
public class HomeController : Controller
{
[HttpGet("GetProducts")]
public IActionResult GetProducts()
{
try
{
IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //
if (res.Count <= 0)
{
return new FailResult<string>(null, "4002", "NoRecord found");
}
return new SuccessResult<IList<DtoProSubCat>>(res); ;
}
catch (Exception ex)
{
return new ServerErrorResult<string>(ex.Message);
}
}
}
你上面的实现方式使得几行命令毫无意义,当然在应用程序的运行ning期间没有太大问题,但在长时间的运行中会影响扩展或维护过程。以上两种方式帮你保护函数的运行模型,最小化源代码,最小化无意义的命令行。
这个 V2 怎么样,因为 @Henry Trần 给出了提示
public class BaseApiResultV2
{
private IActionResult SetResult<T>(int statusCode, ResultData<T> result)
{
JsonResult jsonResult = new(result)
{
StatusCode = statusCode,
ContentType = "application/json"
};
return jsonResult;
}
public IActionResult Success<T>(T result)
{
return SetResult(StatusCodes.Status200OK,
new ResultData<T>
{
Code = "2000",
Massage = "Sucsess",
Result = result
});
}
public IActionResult Fail<T>(T result, string code, string massage)
{
return SetResult(StatusCodes.Status400BadRequest,
new ResultData<T>
{
Code = code,
Massage = massage,
Result = result
});
}
public IActionResult ServerError<T>(T result)
{
return SetResult(StatusCodes.Status500InternalServerError,
new ResultData<T>
{
Code = "5000",
Massage = "Internal Server Error",
Result = result
});
}
private struct ResultData<T>
{
public string Code { get; set; }
public string Massage { get; set; }
public T Result { get; set; }
}
}