We've been using log4net in a .net console app. It used to log everything to console and SQL from the first entry. All of a sudden, the logger doesn't write to our SQL until much later, and it's weird, considering:
Logger.Info("my message won't log")
Logger.Info("my message will log")
it won't log the first but logs the second. Appears to happen every time at the same lines of code, still verifying that. I debugged, stopped at the first logger, used immediate window and log a message and that worked. Can't seem to see why.
But all the meanwhile everything is being logged to the console fine!
Thoughts on what could have happened or why?
Code for custom appender
namespace Dsmt.Logging
{
public class HistoryPatternLayout : PatternLayout
{
public HistoryPatternLayout()
{
AddConverter(new ConverterInfo
{
Name = "migrationHistory",
Type = typeof(MigrationHistoryConverter)
});
}
}
public class MigrationHistoryConverter : PatternConverter
{
protected override void Convert(TextWriter writer, object state)
{
if (state == null)
{
writer.Write(SystemInfo.NullText);
return;
}
var loggingEvent = state as LoggingEvent;
var historyInfo = loggingEvent!= null ? loggingEvent.MessageObject as HistoryLoggerInfo : null;
if (historyInfo == null)
{
writer.Write(SystemInfo.NullText);
return;
}
switch (this.Option.ToLower())
{
case "migrationhistoryid" :
writer.Write(historyInfo.MigrationHistoryId);
break;
case "itemid" :
writer.Write(historyInfo.ItemID);
break;
case "success" :
writer.Write(historyInfo.Success);
break;
case "message" :
writer.Write(historyInfo.Message);
break;
case "itemdatetime" :
writer.Write(historyInfo.ItemDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
break;
case "newlocation":
writer.Write(historyInfo.NewLocation);
break;
default :
writer.Write(SystemInfo.NullText);
break;
}
}
}
public class HistoryLoggerInfo
{
public string MigrationHistoryId { get; set; }
public string ItemID { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public DateTime ItemDateTime { get; set; }
public string NewLocation { get;set; }
public override string ToString()
{
var serializeObject = JsonConvert.SerializeObject(this);
//var serializeObject = JsonConvert.SerializeObject(this, new Log4NetDateTimeConverter());
return serializeObject;
}
public class Log4NetDateTimeConverter : DateTimeConverterBase
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return DateTime.Now.AddYears(-13);
}
}
}
}
Related
Newbie to Orchard CMS
After upgrading an existing Orchard site running version 1.7 to version 1.10.2, some (not all) of my content part drivers are no longer updating the part properties with the new values entered into the form on add or edit.
When I go into add or edit an item, the only property that is saved is an MediaPickerField that is a field of the part.
I have compared the non-working code with working content part drivers in the solution and I can't see anything that is different from them that would cause the issue.
TryUpdateModel is returning true, but none of the values on the form flow through. On Add, there will be a record in the DB with all empty fields except the Id. The driver returns the edit view with a message that the part was added successfully, but all the fields are cleared out except the Image field.
Here is the code for one of the parts having the issue.
public class FeaturedPromoPartRecord : ContentPartRecord {
[StringLength(100)]
public virtual string Name { get; set; }
[StringLengthMax]
public virtual string LinkUrl { get; set; }
public virtual FeaturedPromoGroupPartRecord FeaturedPromoGroupPartRecord { get; set; }
public virtual int SlideOrder { get; set; }
public virtual DateTime? StartDate { get; set; }
public virtual DateTime? EndDate { get; set; }
}
public class FeaturedPromoPart : ContentPart<FeaturedPromoPartRecord> {
public string Name
{
get { return Record.Name; }
set { Record.Name = value; }
}
public string LinkUrl {
get { return Record.LinkUrl; }
set { Record.LinkUrl = value; }
}
public FeaturedPromoGroupPartRecord FeaturedPromoGroupPartRecord
{
get { return Record.FeaturedPromoGroupPartRecord; }
set { Record.FeaturedPromoGroupPartRecord = value; }
}
public int SlideOrder {
get { return Record.SlideOrder; }
set { Record.SlideOrder = value; }
}
public DateTime? StartDate
{
get { return Record.StartDate; }
set { Record.StartDate = value; }
}
public DateTime? EndDate
{
get { return Record.EndDate; }
set { Record.EndDate = value; }
}
}
public class FeaturedPromoPartDriver : ContentPartDriver<FeaturedPromoPart> {
private readonly IFeaturedPromoService _featuredPromoService;
public FeaturedPromoPartDriver(IFeaturedPromoService featuredPromoService) {
_featuredPromoService = featuredPromoService;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected override DriverResult Display(FeaturedPromoPart part, string displayType, dynamic shapeHelper) {
var group = _featuredPromoService.GetFeaturedPromoGroup(part.FeaturedPromoGroupPartRecord.Id);
return ContentShape("Parts_FeaturedPromo_SummaryAdmin",
() => shapeHelper.Parts_FeaturedPromo_SummaryAdmin(ContentPart: part, ContentItem: part.ContentItem, Group: group));
}
protected override DriverResult Editor(FeaturedPromoPart part, dynamic shapeHelper) {
var groups = _featuredPromoService.GetFeaturedPromoGroups();
var viewModel = new FeaturedPromoEditViewModel
{
Groups = groups,
Name = part.Name,
FeaturedPromoGroupPartRecordId = (part.FeaturedPromoGroupPartRecord == null) ? 0 : part.FeaturedPromoGroupPartRecord.Id,
LinkUrl = part.LinkUrl,
SlideOrder = part.SlideOrder,
StartDate = part.StartDate,
EndDate = part.EndDate
};
return ContentShape("Parts_FeaturedPromo_Edit",
() => shapeHelper.EditorTemplate(TemplateName: "Parts.FeaturedPromo.Edit", Model: viewModel));
}
protected override DriverResult Editor(FeaturedPromoPart part, IUpdateModel updater, dynamic shapeHelper) {
var result = updater.TryUpdateModel(part, Prefix, null, null);
var group = _featuredPromoService.GetFeaturedPromoGroup(part.FeaturedPromoGroupPartRecord.Id);
if(group != null)
part.FeaturedPromoGroupPartRecord = group._record.Value;
if (part.StartDate.HasValue && part.EndDate.HasValue && part.StartDate > part.EndDate)
updater.AddModelError("", T("The End Date cannot be after the Start Date."));
return Editor(part, shapeHelper);
}
}
Some images of what I'm seeing.
Edit
Add New
If anyone has encountered this issue, or has some insight on how to fix I would greatly appreciate your help!
Thank you
I am new at automapper and it is a very good stuff easy to use, but now I have a problem with it. Trying to convert my derived class to base and it gives me
AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.
Mapping types: ClientEventDb -> EventId
Database.ClientEventDb -> EventId
Destination path: ClientEvent
Source value:
Event:Login
Automapper wants to convert ClientEventDb to EventId? I don't understand why. EventId is an enum...
Please help me I have run out of ideas.
Here is the code which I run:
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.Take(1000).ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>();
Console.WriteLine("hello");
return edbl.Select(edb => Mapper.Map<ClientEvent>(edb)).ToArray();
Here are my classes
[Table("events", Schema = "public")]
public class ClientEventDb : ClientEvent
{
public ClientEventDb(string userName, EventId happening, object userObject = null)
: base(userName, happening, userObject)
{
}
public ClientEventDb()
{
}
}
[ProtoContract]
[Table("events", Schema = "public")]
public class ClientEvent : ClientEventBase
{
[ProtoMember(1)]
[Column("username")]
public string UserName { get; private set; }
[ProtoMember(2)]
[Column("time")]
public DateTime DateTime { get; private set; }
[ProtoMember(3)]
[Key]
[Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; private set; }
[ProtoMember(4)]
[Column("data")]
public byte[] UserObject { get; set; }
public ClientEvent(string userName,EventId happening, object userObject=null) : base(happening)
{
UserName = userName;
DateTime = DateTime.Now;
//UserObject = null;
if (userObject!=null) throw new NotImplementedException();
}
public ClientEvent()
{
}
protected ClientEvent Clone()
{
return (ClientEvent)MemberwiseClone();
}
}
[ProtoContract]
[ProtoInclude(10, typeof(ClientEvent))]
public class ClientEventBase
{
[Column("eventid")]
[ProtoMember(1)]
public int EventIdValue { get; set; } //must be public because of entity framework
[NotMapped]
public EventId EventId
{
get { return (EventId) EventIdValue; }
set { EventIdValue = (int) value; }
}
public ClientEventBase(EventId eventId)
{
EventId = eventId;
}
public ClientEventBase()
{
}
public override string ToString()
{
return String.Format("Event:{0}",EventId);
}
}
public enum EventId
{
Login = 1,
Logout,
ExitApplication,
}
UPDATE
bugfix: ClientEvent [Key] attribute moved to id property
Solution was this (thx to stuartd):
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>().ConstructUsing((ClientEventDb src) => new ClientEvent());
return edbl.Select(Mapper.Map<ClientEvent>).ToArray();
AutoMapper is confused as its made to map between similar properties in different classes, you are using it incorrectly - you just need to go from the derived class to the base which does not require AutoMapper. You could use this to do what you need....
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.Take(1000).ToArray();
}
return edbl.Cast<ClientEvent>().ToList();
I'd be looking at why you even feel you need a derived ClientEventDb though - understand we dont have the whole picture here but it seems to do nothing in addition to what the base class already does.
The issue is that ClientEvent has two constructors but you have not told AutoMapper which to use.
If you want it to use your constructor with parameters, change your mapping code to this and it will work:
Mapper.CreateMap<ClientEventDb, ClientEvent>()
.ConstructUsing(src => new ClientEvent(src.UserName, src.EventId));
Or to make AutoMapper use the default constructor:
Mapper.CreateMap<ClientEventDb, ClientEvent>()
.ConstructUsing((ClientEventDb src) => new ClientEvent());
Seeing a strange problem, getting empty metata pages for xml,json and jvs.
Using the following command line app. How does one debug these issues?
namespace ConsoleApplication2
{
public struct NativeUser
{
public int login;
public string group;
public string name;
}
[DataContract]
public class User
{
private NativeUser _native;
public User() { }
public User(NativeUser native)
{
_native = native;
}
public static implicit operator NativeUser(User user)
{
return user._native;
}
public static implicit operator User(NativeUser native)
{
return new User(native);
}
// ReSharper disable InconsistentNaming
[DataMember]
public int login
{
get { return _native.login; }
set { _native.login = value; }
}
[DataMember]
public string group
{
get { return _native.group; }
set { _native.group = value; }
}
[DataMember]
public string name
{
get { return _native.name; }
set { _native.name = value; }
}
}
[Description("GET account, all or by list of groups or by list of logins")]
[Route("/accounts/{groups}", "GET")]
[Route("/accounts/{logins}", "GET")]
[Route("/accounts/", "GET")]
public class Accounts : IReturn<User[]>
{
public string[] groups { set; get; }
public int[] logins { set; get; }
public Accounts() { }
public Accounts(params int[] logins)
{
this.logins = logins;
}
public Accounts(params string[] groups)
{
this.groups = groups;
}
}
public class Host : AppHostHttpListenerBase
{
public Host() : base("Test",
typeof(Accounts).Assembly)
{
}
public override void Configure(Funq.Container container)
{
}
}
public class Servce : IService
{
public object Get(Accounts request)
{
return new List<User>(){new User(new NativeUser())};
}
}
class Program
{
static void Main(string[] args)
{
var host = new Host();
host.Init();
host.Start("http://+:12345/");
global::System.Console.ReadLine();
}
}
}
Nm, found the bug :
public class Accounts : IReturn<User[]>
needs to be
public class Accounts : IReturn<List<User>>
Another very note worthy thing: All DTO's and objects being passed back and fourth in the DTO's require an empty constructor in order for the metata data to be properly generated.
Not sure if this is by design or a bug
i am new in orchard module development.i create a module.when i try to save data.
i use this code fore save data
public ActionResult Create(FormCollection input)
{
var product = contentManager.New<ProductPart>("Product");
product.EmployeeName = input["EmployeeName"];
product.EmployeeFathersName = input["EmployeeFathersName"];
product.DOB = Convert.ToDateTime(input["DOB"]);
product.Email = input["Email"];
product.Address = input["Address"];
product.JoiningDate = Convert.ToDateTime(input["JoiningDate"]);
if (!ModelState.IsValid)
{
return View(product);
}
contentManager.Create(product);
return RedirectToAction("Index");
}
this class i use in Model
public class ProductRecord:ContentPartRecord
{
public virtual string EmployeeName { get; set; }
public virtual string EmployeeFathersName { get; set; }
public virtual DateTime DOB { get; set; }
public virtual string Email { get; set; }
public virtual string Address { get; set; }
public virtual DateTime JoiningDate { get; set; }
}
public class ProductPart : ContentPart<ProductRecord>
{
/*
public int Id
{
get { return Record.Id; }
set{Record.Id = value;}
}
*/
[Required]
public string EmployeeName
{
get { return Record.EmployeeName; }
set { Record.EmployeeName = value; }
}
[Required]
public string EmployeeFathersName
{
get { return Record.EmployeeFathersName; }
set { Record.EmployeeFathersName = value; }
}
[Required]
public DateTime DOB
{
get { return Record.DOB; }
set { Record.DOB = value; }
}
[Required]
public string Email
{
get { return Record.Email; }
set { Record.Email = value; }
}
[Required]
public string Address
{
get { return Record.Address; }
set { Record.Address = value; }
}
[Required]
public DateTime JoiningDate
{
get { return Record.JoiningDate;}
set { Record.JoiningDate = value; }
}
}
i use content type "Product" but when it goes orchard ContentCreateExtension in belows method
public static T New<T>(this IContentManager manager, string contentType) where T : class, IContent {
var contentItem = manager.New(contentType);
if (contentItem == null)
return null;
var part = contentItem.Get<T>();
if (part == null)
throw new InvalidCastException();
return part;
}
here i face var part is null that means it content part is null.
please help me....
Have you setup your migrations class?
i.e.
public class Migrations : DataMigrationImpl {
public int Create() {
SchemaBuilder.CreateTable("ProductRecord",
table => table
.ContentPartRecord()
.COLUMNS NEED TO BE SPECIFIED
);
ContentDefinitionManager.AlterTypeDefinition("Forum",
cfg => cfg
.WithPart("ProductPart")
.WithPart("CommonPart")
);
Also have you setup your repository?
i.e.
public class ProductPartHandler : ContentHandler {
public ProductPartHandler(IRepository<ProductPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
In addition to the Nicholas answer, I want to mention, that missing driver for the ProductPart can cause such error. Make sure, that you have at least empty driver defined.
public class ProductPartDriver : ContentPartDriver<ProductPart> {}
Just went through a similar situation, be sure that the handler class is declared as public.
is there any problem with this kinda registration via structure map??
static public class ContainerBootstrapper
{
static public void BootstrapDefaultContainer(bool test = false)
{
StructureMap.ObjectFactory.Initialize(x =>
{
x.Scan(p =>
{
p.AssemblyContainingType<IPropertyType>();
p.AddAllTypesOf<IPropertyType>();
// p.AddAllTypesOf<IPropertyType>().NameBy(c => c.Name);
});
});
}
public interface IPropertyType : IIdentityObject, IPriority
{
string PropertyName { get; set; }
ObjectType ObjectType { get; }
string DisplayName { get; set; }
IEntityType EntityType { get; set; }
IList<IPropertyRuleObject> RuleObjects { get; set; }
void AddRuleObject(IPropertyRuleObject ruleObject);
}
public abstract class PropertyTypeBase : PersistentObject, IPropertyType
{
public PropertyTypeBase()
{
}
public PropertyTypeBase(string propertyName, string displayName)
{
PropertyName = propertyName;
DisplayName = displayName;
}
....
}
public class StringType : PropertyTypeBase
{
private ObjectType _objectType;
public StringType()
{
_objectType = new ObjectType(typeof(string));
}
public StringType(string propertyName, string displayName)
: base()
{
PropertyName = propertyName;
DisplayName = displayName;
}
public override ObjectType ObjectType
{
get { return _objectType; }
}
}
when ContainerBootstrapper.BootstrapDefaultContainer(); execute I see this line of error:
StructureMap Exception Code: 200
Could not find an Instance named "StringType" for PluginType Azarakhsh.Domain.Core.AdaptiveObjectModel.Interface.IPropertyType
the calling code:
public IPropertyType GetPropertyType(IIdentityObject identityObject, string name)
{
string[] Properties = name.Split('.');
object Result = identityObject;
foreach (var Property in Properties)
Result = Result.GetType().GetProperty(Property).PropertyType.Name;
IPropertyType propertyType = StructureMap.ObjectFactory.GetNamedInstance<IPropertyType> (Result + "Type");
if (propertyType==null)
throw new Exception("Property type not found");
return propertyType;
}
what is the problem?
You are trying to get a named instance, but from what I can see of the code you have provided, you dont name your instances. The line of code that name your instances is commented out.
But even if you would just use the ObjectFactory.GetInstance<IPropertyType>(); here, you would have got an error because structuremap dont know what constructor to use. There are several solutions to theis problem.
Change your design so you only have one constructor
Mark your default constructor with the [DefaultConstructor] attribute, then it will work.
You can register it with objectFactory manually with something like this:
x.For().Use().Ctor("propertyName").Is("someValue").Ctor("displayName").Is("someValue");
You can write a custom registrationconvention as described here