I have some custom exceptions that inherit from Exception that have custom properties
e.g.
[Serializable]
public class MyException : Exception
{
public MyException(string message, string myProperty)
{
MyProperty = myProperty
}
public string MyProperty {get; set;}
}
I'd like to automatically add each custom property to my log4net logs. Is there any built in way to do this or do I need to create some kind of custom appender?
You can add custom fields to log4net using GlobalContext.Properties, like so:
GlobalContext.Properties["MyProperty"] = customException.MyProperty;
Then, in your appender configuration, you can access this custom field with %property{MyProperty}.
You could override the .ToString() method in your custom exception and append the output to the base .ToString() method.
Related
I am creating a webapp in asp.net MVC5 which will only allow people with a certain domain to sign up.
From what I understand the easiest way is to use a regular expression. Is there any way to use Data Annotations to change the model, or do I have to play around with the view to achieve this?
Probably a bit too late now but I would suggest as follows:
I've have an app in which I need to modify some of ApplicationUser properties, I am trying something which haven't tested on real life yet, but my Unit Tests are passing so far, it could be useful for you.
Override Email property in ApplicationUser, and add a custom validation annotation:
[ValidateEmailDomain(ErrorMessage = "Not a valid email domain.")]
public override string Email { get; set; }
ValidateEmailDomain code:
using System.ComponentModel.DataAnnotations;
using System.Web;
namespace WATHEVER
{
public class ValidateEmailDomain: RequiredAttribute
{
public override bool IsValid(object value)
{
//code
}
}
}
Note that as ValidateEmailDomain inherits from RequiredAttribute it will become obviously obligatory, if you don't want it that way, you could validate it also when it's null.
Sorry for my English :/
with MVC 5 you're using ASPNET Identiy, and the basic properties are encapsulate inside IdentityUser, so for your case, you cannot have access direct to the field email, but yuo can use EF Fluent API to add some rules, the but part is that regularexpression attribute is not part of the EF Fluent API.
If you need to see how can you use EF Fluent API with ASPNET Identity:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{ }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//Define rules
modelBuilder.Entity<IdentityUser>()
.Property(u => u.Email).IsRequired();
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Regards,
I am using Xamarin.iOS. I have created UIView with a few UITextFields. I am looking for best way to initialize text value in these textfields from code.
I can pass text data in the constructor of UIViewContoller, but I don't have access to textFields inside it (they are null). I can change text value of textFields in viewDidLoad method.
I don't want to create additional fields in controller class to store data passed by constructor and use them in viewDidLoad. Do you know better solution ?
I don't want to create additional fields in controller class to store
data passed by constructor and use them in viewDidLoad.
But that's how it's meant to be done.
Alternatively, you can create less fields/properties in your viewcontroller if you use a MVVM pattern:
public class UserViewModel {
public string Name { get; set;}
public string Title { get; set;}
}
public class UserViewController : UIViewController
{
UserViewModel viewModel;
public UserViewController (UserViewModel viewModel) : base (...)
{
this.viewModel = viewModel;
}
public override void ViewDidLoad ()
{
userName.Text = viewModel.Name;
userTitle.Text = viewModel.Title;
}
}
That's the kind of pattern which gives you a lot of code reuse accross platforms (android, WP, ...) and clearly separate concerns. It's a (very) little bit of extra code, but it's worth every byte.
I am trying to set a public property in the service constructor, it is giving null reference exception in the Any() method. If I changed it to readonly field, it is working fine. But I would like to set this property by instantiating the service, could anyone provide insights how this can be achieved.
public class CustomerService : Service
{
private readonly IDbConnection _dbConnection;
public ServiceCommand SelectCommand {get;set;}
public CustomerService(IDBConnection dbConnection)
{
SelectCommand = new ServiceCommand();
_dbConnection = dbConnection;
}
public Customer Any()
{
//selectcommand is null here
}
}
I've partially answered this in this earlier question.
All public properties get injected by the IOC
The reason why SelectCommand property is null is because it's a public property. All of your Services public properties are attempted to be resolved by your Registered dependencies and because you don't have any registered dependencies of type ServiceCommand it is overrided with null. If this was defined in your constructor instead it would've thrown a run-time exception, because it's just a property it's set to null.
If you change the visibility of SelectCommand to be non-public, e.g. protected, private, internal or static it wont be attempted to be injected by the IOC.
We have been using ServiceStack for REST based services for a while now and so far it has been amazing.
All of our services have been written as:
public class MyRestService : RestService<RestServiceDto>
{
public override object OnGet(RestServiceDto request)
{
}
}
For each DTO we have Response equivalent object:
public class RestServiceDto
{
public ResponseStatus ResponseStatus {get;set;}
}
which handles all the exceptions should they get thrown.
What I noticed is if an exception is thrown in the OnGet() or OnPost() methods, then the http status description contains the name of the exception class where as if I threw a:
new HttpError(HttpStatus.NotFound, "Some Message");
then the http status description contains the text "Some Message".
Since some of the rest services are throwing exceptions and others are throwing new HttpError(), I was wondering if there was a way without changing all my REST services to catch any exceptions and throw a new HttpError()?
So for example, if the OnGet() method throws an exception, then catch it and throw a new HttpError()?
Using Old API - inherit a custom base class
As you're using the old API to handle exceptions generically you should provide a Custom Base class and override the HandleException method, e.g:
public class MyRestServiceBase<TRequest> : RestService<TRequest>
{
public override object HandleException(TRequest request, Exception ex)
{
...
return new HttpError(..);
}
}
Then to take advantage of the custom Error handling have all your services inherit your class instead, e.g:
public class MyRestService : MyRestServiceBase<RestServiceDto>
{
public override object OnGet(RestServiceDto request)
{
}
}
Using New API - use a ServiceRunner
Otherwise if you're using ServiceStack's improved New API then you don't need to have all services inherit a base class, instead you can just tell ServiceStack to use a custom runner in your AppHost by overriding CreateServiceRunner:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
return new MyServiceRunner<TRequest>(this, actionContext);
}
Where MyServiceRunner is just a just custom class implementing the custom hooks you're interested in, e.g:
public class MyServiceRunner<T> : ServiceRunner<T> {
public override object HandleException(IRequestContext requestContext,
TRequest request, Exception ex) {
// Called whenever an exception is thrown in your Services Action
}
}
I'm trying to filter my appender based on the type of exception being logged. Is this possible in log4net?
log4net does not support this directly. You can however quite easily implement your own filter by deriving either from the IFilter interface or the FilterSkeleton class (both in log4net.Filter namespace).
Something like this should do the trick:
public class ExceptionTypeFilter : FilterSkeleton
{
override public FilterDecision Decide(LoggingEvent loggingEvent)
{
var ex = loggingEvent.ExceptionObject as YourExceptionType;
return (ex != null) ? FilterDecision.Accept : FilterDecision.Deny;
}
}
This filter you can then use like a regular filter. For further reference you may look at the source code of the standard log4net filters.