使用Web.Api异步记录asp.net mvc的错误

时间:2014-11-21 16:49:21

标签: asp.net asynchronous asp.net-web-api asp.net-web-api2

我有一个旧的日志记录DLL,可以将错误记录到数据库中。我们不想在我们的环境中的每个应用程序中使用DLL,而是要进行Web调用以记录错误。

我已经构建了一个web.api应用程序,可以将错误记录到数据库中。使用POSTMAN进行测试时,它的效果与宣传的一样。

我在一个演示MVC应用程序中添加了一个类并连接了我的一个构造函数来执行一个日志命令,但是这个调用不仅没有进入我的web.api,而且即使是fiddler也没有显示调用制成。

任何有关实际运行的输入都将非常感激。

这是我的代码:

在Web.API中调用的记录实用程序

public class Utilities
{
    public void LogException(string exceptionMessage, string stackTrace, string appCode, string runMode, int entityId, int itmsUserID, string updateBy, string path, string method)
    {
        ErrorLog.Entry _error = new ErrorLog.Entry();
        _error.ErrorMessage = exceptionMessage;
        _error.StackTrace = stackTrace;
        _error.AppCode = appCode;
        _error.Path = path;
        _error.Method = method;
        _error.UpdateBy = updateBy;
        _error.RunMode = runMode;
        _error.EntityID = entityId;
        //_error.Server = server;   server will have to be changed to accept a setter
        _error.ITMSUserID = CommonFunctions.Get_ITMSUserID(updateBy);
        _error.Save();
    }
}

Web.API

    // POST: api/ErrorLog
    public void Post([FromBody]ErrorLogEntryDTO item)
    {
        var utils = new Utilities();

        utils.LogException(item.ErrorMessage, item.StackTrace, item.AppCode, item.RunMode, item.EntityID, item.ITMSUserID, item.UpdateBy, item.Path, item.Method);
    }

MVC控制器代码

    // GET: BillingRules/Create
    public virtual ActionResult CauseHandledError()
    {
        try
        {

            throw new Exception("Handled exception test");
        }
        catch (Exception ex)
        {
            var utils = new Utilities();
            utils.LogException(ex, "system", MVC.BillingRules.Name, MVC.BillingRules.ActionNames.CauseHandledError);
        }
        return RedirectToAction(MVC.BillingRules.ActionNames.Index, MVC.BillingRules.Name);
    }

MVC应用程序中的实用程序代码

    public void LogException(Exception exception, string updateBy, string path, string method)
    {
        try
        {
            var itmsUserID = CommonFunctions.Get_ITMSUserID(updateBy);

            var errorDTO = new ErrorLogEntryDTO();
            errorDTO.ITMSUserID = itmsUserID;
            errorDTO.AppCode = _appCode.Value;
            errorDTO.ErrorMessage = exception.Message;
            errorDTO.StackTrace = exception.StackTrace;
            errorDTO.Path = path;
            errorDTO.Method = method;
            errorDTO.UpdateBy = updateBy;

            var client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:52316");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            var result = client.PostAsJsonAsync("api/ErrorLog", errorDTO).Result; //ContinueWith(readTask => client.Dispose()); // 
        }
        catch (Exception ex)
        {
            var myError = ex;
            throw;
        }
    }

2 个答案:

答案 0 :(得分:0)

我非常确定在此实例中调用.Result不会立即调用PostAsJsonAsync方法。因为您没有对结果做任何事情,所以它实际上从未执行过。由于您并不关心响应,因此您应该能够使用:

client.PostAsJsonAsync("api/ErrorLog", errorDTO).Wait();

答案 1 :(得分:0)

我认为.Result会调用PostAsJsonAsync来电。您正在等待respsonse,因此必须在此行之后完成调用。无论您是否使用结果。

您可以删除[FromBody]属性,因为默认情况下会从正文中读取复杂类型。

我无法重现您的问题。我创建了一个新的Web API项目和一个新的控制台项目。在Web API中,我已将valuescontroller的帖子更改为您的。 在控制台项目中,我从MVC应用程序中获取了LogException()方法。 它打我的web api应用程序。 是在同一主机还是在不同的主机中?

编辑: 要使您的日志记录异步,您可以使用Task.Run()进行“即发即弃”,但这取决于您拥有的应用程序。在ASP.Net中Task.Run()是根据Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation的反模式。