I just started to migrate my project to .NET Core 6, using ASP.NET Boilerplate with Kendo controls.
The application will do some operations (insert/update) and throw some custom error messages to the client if any database operation failed.
The application sends the raw error message instead of the custom formatted JSON. Am I missing something to configure?
Is there any way to get the custom error message which I have returned from the controller?
Controller:
[ValidateAntiForgeryToken()]
[DontWrapResult]
[DisableValidation]
[HttpPost]
public ActionResult CreateOrUpdate([DataSourceRequest] DataSourceRequest request,
[Bind(Prefix = "models")] IEnumerable<InstallationTeamMemberDto> teamMembers,
long id, string teamName, string description, string category, bool isActive,
long? teamLeadId, string contactNumber, string remarks)
{
List<InstallationTeamMemberDto> teamMembersList = teamMembers.ToList();
try
{
if (ValidateMe(teamMembersList, id, teamName, description, category, isActive, teamLeadId, contactNumber, remarks) && ModelState.IsValid)
{
id = _installationTeamAppService.CreateOrUpdateAsync(teamMembersList, id, teamName, description,
category, isActive, teamLeadId, contactNumber, remarks);
}
}
catch (Exception ex)
{
ModelState.AddModelError("", "Unable to Save the data! Internal error occured." ex.Message.ToString());
var res1 = teamMembers.ToDataSourceResult(request, ModelState);
return Json(new
{
Data = res1.Data,
Errors = res1.Errors,
Id = id,
IsSuccess = 0
}, JsonSetting.DefaultJsonSerializerSetting);
}
var res = teamMembers.ToDataSourceResult(request, ModelState);
// Returning the Id to save the Technical Details information
return Json(new
{
Data = res.Data,
Errors = res.Errors,
Id = id,
IsSuccess = 1
}, JsonSetting.DefaultJsonSerializerSetting);
}
Result:
CodePudding user response:
ASP.NET Boilerplate's Conventional Unit of Work is scoped around your Controller action.
You need to place the try/catch around the Unit of Work scope:
[UnitOfWork(IsDisabled = true)] // Add this
public ActionResult CreateOrUpdate(...)
{
List<InstallationTeamMemberDto> teamMembersList = teamMembers.ToList();
try
{
using (var uow = _unitOfWorkManager.Begin()) // Add this
{ //
if (ValidateMe(...)
{
id = _installationTeamAppService.CreateOrUpdate(...);
}
uow.Complete(); // Add this
} //
}
...
}
Instead of beginning a unit of work explicitly in your controller, you could add a [UnitOfWork]
attribute on your application service method:
[UnitOfWork] // Add this
public void CreateOrUpdate(...)
You can require a new unit of work, but you will have the unnecessary ambient unit of work:
// [UnitOfWork(IsDisabled = true)] // -
public ActionResult CreateOrUpdate(...)
{
List<InstallationTeamMemberDto> teamMembersList = teamMembers.ToList();
try
{
// using (var uow = _unitOfWorkManager.Begin()) // -
using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew)) //
{
if (ValidateMe(...)
{
id = _installationTeamAppService.CreateOrUpdate(...);
}
uow.Complete();
}
}
...
}