Home > Back-end >  Return custom formatted JSON in exception handling
Return custom formatted JSON in exception handling

Time:03-30

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:

Actual 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();
        }
    }
    ...
}
  • Related