Using this example for my MVC project, I want to log my exception on a file, even without attaching a debugger, when I run my project after publishing it on IIS, not in output window when the project is in debug.
My code is the same as the one presented in the link.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
namespace ServerSide
{
public class MyLoggerService : DevExpress.XtraReports.Web.ClientControls.LoggerService
{
public override void Info(string message)
{
System.Diagnostics.Debug.WriteLine("[{0}]: Info: '{1}'.", DateTime.Now, message);
}
public override void Error(Exception exception, string message)
{
System.Diagnostics.Debug.WriteLine("[{0}]: Exception occured. Message: '{1}'. Exception Details:\r\n{2}",
DateTime.Now, message, exception);
}
}
}
How could I change this code in order to make it log exceptions to a file?
In case anyone needs it, the solution is to add in Error method this code:
string filePath = #"C:\ReportDesigner\server\publish\Exceptions.txt";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("-----------------------------------------------------------------------------");
writer.WriteLine("Date : " + DateTime.Now.ToString());
writer.WriteLine();
while (exception != null)
{
writer.WriteLine(exception.GetType().FullName);
writer.WriteLine("Message : " + exception.Message);
writer.WriteLine("StackTrace : " + exception.StackTrace);
exception = exception.InnerException;
}
}
Related
I am running dotnet core 2.* and as the title mentions I have trouble getting my try catch to work when calling from API. And before anyone comments I am also running middle-ware to catch any exceptions. It too doesn't perform as expected
Addinional Information:
The Two Classes are in different namespaces/projects
Queries.Authentication is static.
They are both in the same solution
Controller:
[AllowAnonymous]
[HttpPost]
public string Login([FromBody] AuthRequest req)
{
// See if the user exists
if (Authenticate(req.username, req.password))
{
try {
// Should Fail Below
UserDetails ud = Queries.Authentication.GetUser(req.username);
} catch (RetrievalException e){ }
catch (Exception e){ } // Exception Still Comes Through
}
}
Queries.Authentication.GetUser Code:
public static class Authentication {
public static UserDetails GetUser (string username)
{
// Some Code
if (details.success)
{
// Some Code
}
else
{
throw new RetrievalException(details.errorMessage); // This is not caught propperly
}
}
}
Retrieval Exception:
public class RetrievalException : Exception
{
public RetrievalException()
{
}
public RetrievalException(String message)
: base(message)
{
}
public RetrievalException(String message, Exception inner)
: base(message, inner)
{
}
}
EDIT: Adding Middleware Code Here as per request:
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
String message = String.Empty;
var exceptionType = context.Exception.GetType();
if (exceptionType == typeof(UnauthorizedAccessException))
{
message = "Unauthorized Access";
status = HttpStatusCode.Unauthorized;
}
else if (exceptionType == typeof(NullReferenceException))
{
message = "Null Reference Exception";
status = HttpStatusCode.InternalServerError;
}
else if (exceptionType == typeof(NotImplementedException))
{
message = "A server error occurred.";
status = HttpStatusCode.NotImplemented;
}
else if (exceptionType == typeof(RSClientCore.RetrievalException))
{
message = " The User could not be found.";
status = HttpStatusCode.NotFound;
}
else
{
message = context.Exception.Message;
status = HttpStatusCode.NotFound;
}
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
var err = "{\"message\":\"" + message + "\",\"code\" :\""+ (int)status + "\"}";
response.WriteAsync(err);
}
}
App Config:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} else
{
app.UseExceptionHandler();
}
...
}
Service Config:
public void ConfigureServices(IServiceCollection services)
{
// Add Model View Controller Support
services.AddMvc( config =>
config.Filters.Add(typeof (CustomExceptionFilter))
);
UPDATE: After playing around with it I noticed that even though my program throws the exception, if I press continue the API controller then handles it as if the exception was never thrown (as in it catches it and does what I want). So I turned off the break on Exception setting, this fixed it in debugger mode. However this the break doesn't seem to be an issue when I build/publish the program. This makes me think it is definitely a issue with visual studio itself rather than the code.
When you set ExceptionHandled to true that means you have handled the exception and there is kind of no error anymore. So try to set it to false.
context.ExceptionHandled = false;
I agree it looks a bit confusing, but should do the trick you need.
Relevant notes:
For those who deal with different MVC and API controller make sure you implemented appropriate IExceptionFilter as there are two of them - System.Web.Mvc.IExceptionFilter (for MVC) and System.Web.Http.Filters.IExceptionFilter (for API).
There is a nice article about Error Handling and ExceptionFilter Dependency Injection for ASP.NET Core APIs you could use as a guide for implementing exception filters.
Also have a look at documentation: Filters in ASP.NET Core (note selector above the left page menu to select ASP.NET Core 1.0, ASP.NET Core 1.1,ASP.NET Core 2.0, or ASP.NET Core 2.1 RC1). It has many important notes and explanations why it works as it does.
Im tyring to send an email with my program to an gmx email. Every time I try to send the mail I get the same error message in my console.
What can be the solution for that?
The error message:
System.Net.Mail.SmtpException: SMTP server requiers secure connection or the client wasnt authenticated. server response was: authentication required.
in - System.Net.Mail.SendMailAsyncResult.End(IAsyncResult result)
in - System.Net.Mail.SmtpClient.SendMailCallback(IAsyncResult result)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.ComponentModel;
namespace SMTP_Client
{
class Program
{
static bool mailSent = false;
private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
if (e.Cancelled)
{
Console.WriteLine("[{0}] Send canceled.", token);
}
if (e.Error != null)
{
Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
}
else
{
Console.WriteLine("Message sent.");
}
mailSent = true;
}
public static void Main(string[] args)
{
SmtpClient client = new SmtpClient("smtp.gmx.com",25);
MailAddress from = new MailAddress("example#project.com", "me " + (char)0xD8 + " you", System.Text.Encoding.UTF8);
MailAddress to = new MailAddress("example#gmx.com");
MailMessage message = new MailMessage(from, to);
message.Body = "The project has succeeded ";
message.Subject = "made it!";
client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
string userState = "test message2\n";
client.SendAsync(message, userState);
Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.");
string answer = Console.ReadLine();
if (answer.StartsWith("c") && mailSent == false)
{
client.SendAsyncCancel();
}
message.Dispose();
Console.WriteLine("proccess ended.");
}
}
}
I am trying to export to file the json output of a url. But starting with parsing the json output, I got an error of Bad request. I can't understand why, because when i manually input the url on web, it has a valid result.
using System;
using System.IO;
using System.Web;
using System.Net;
namespace web
{
class Program
{
static void Main(string[] args)
{
var json = new WebClient().DownloadString("http://steamcommunity.com/market/pricehistory/?country=DE¤cy=3&appid=570&market_hash_name=Helm%20of%20the%20Guardian%20Construct");
Console.WriteLine(json);
Console.ReadLine();
}
}
}
I am getting file not found error though I have the needed file inside the project directory.There are no compilation errors.
Here is my startup.cs class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
namespace OdeToFood
{
public class Startup
{
public Startup()
{
var builder = new ConfigurationBuilder()
.AddJsonFile("config.json");
Configuration = builder.Build();
}
public IConfiguration Configuration { get; set; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
var message = Configuration["greeting"];
await context.Response.WriteAsync(message);
});
}
}
}
And this is the error message I get when I build it.
System.IO.FileNotFoundException: The configuration file 'config.json' was not found and is not optional.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at OdeToFood.Startup..ctor()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider services, Type startupType, String environmentName)
at Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.<>c__DisplayClass1_0.b__1(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.ScopedCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
Screenshot showing the file present
How should I rectify this?
Thanks
I think you forget to use Server.MapPath function.
You can edit your Constructor with following code :
public Startup()
{
var builder = new ConfigurationBuilder()
.AddJsonFile(HttpContext.Current.Server.MapPath("~/config.json"));
Configuration = builder.Build();
}
Hope it helps you :)
Basically I've written a C# script for a Script task in SSIS that looks in a User::Directory for 1 csv, if & only if there is one file, it stores that in the instance variable which then maps to the package variables of SSIS.
When I exicute, it gives me the red filled in box of the Script task. I think it's related to how I'm looking at the directory, but I'm not sure.
Please help!
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
namespace ST_e8b4bbbddb4b4806b79f30644240db19.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
private String fileName = "";
private String RootDirictory;
private String FilePath;
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
public ScriptMain()
{
RootDirictory = Dts.Variables["RootDir"].Value.ToString();
FilePath = RootDirictory + "\\" + "SourceData" + "\\";
}
public void setFileName()
{
DirectoryInfo YDGetDir = new DirectoryInfo(FilePath);
FileInfo[] numberOfFiles = YDGetDir.GetFiles(".csv");
if (numberOfFiles.Length < 2)
{
fileName = numberOfFiles[0].ToString();
}
int fileNameLen = fileName.Length;
String temp = fileName.Substring(0, fileNameLen - 5);
fileName = temp;
}
public void mapStateToPackage()
{
if((fileName!=null)||(fileName!=""))
{
Dts.Variables["ExDFileName"].Value = fileName;
}
}
public void Main()
{
setFileName();
mapStateToPackage();
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
This could simply be done using Foreach loop container as explained in this Stack Overflow question, which was asked by you. :-)
Anyway, to answer your question with respect to Script Task code that you have provided. Below mentioned reasons could be cause of the issues:
You are looking for .csv. This won't return any results because you are looking for a file with no name but extension .csv. The criteria should be *.csv
If you are looking for exactly one file, then the condition if (numberOfFiles.Length < 2) should be changed to if (numberOfFiles.Length == 1)
The section of code after the if section which extracts the file name should be within the above mentioned if condition and not out side of it. This has to be done to prevent applying substring functionality on an empty string.
Modified code can be found under the Script Task Code section.
Sorry, I took the liberty to simplify the code a little. I am not suggesting this is the best way to do this functionality but this is merely an answer to the question.
Hope that helps.
Script Task Code:
C# code that can be used only in SSIS 2008 and above.
/*
Microsoft SQL Server Integration Services Script Task
Write scripts using Microsoft Visual C# 2008.
The ScriptMain is the entry point class of the script.
*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
namespace ST_3effcc4e812041c7a0fea69251bedc25.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
Variables varCollection = null;
String fileName = string.Empty;
String fileNameNoExtension = string.Empty;
String rootDirectory = string.Empty;
String filePath = string.Empty;
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
Dts.VariableDispenser.LockForRead("User::RootDir");
Dts.VariableDispenser.LockForWrite("User::ExDFileName");
Dts.VariableDispenser.GetVariables(ref varCollection);
rootDirectory = varCollection["User::RootDir"].Value.ToString();
filePath = rootDirectory + #"\SourceData\";
DirectoryInfo YDGetDir = new DirectoryInfo(filePath);
FileInfo[] numberOfFiles = YDGetDir.GetFiles("*.csv");
if (numberOfFiles.Length == 1)
{
fileName = numberOfFiles[0].ToString();
fileNameNoExtension = fileName.Substring(0, fileName.LastIndexOf("."));
}
if (!String.IsNullOrEmpty(fileNameNoExtension))
{
varCollection["User::ExDFileName"].Value = fileNameNoExtension;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}