damienbod / ElasticsearchCRUD

Elasticsearch .NET netstandard API
http://damienbod.com/2014/09/22/elasticsearch-crud-net-provider/
176 stars 49 forks source link

MapCollectionOrArray fails in asp.net 5 package #142

Closed kdotzenrod closed 8 years ago

kdotzenrod commented 8 years ago

Exception details below: System.MissingMethodException was unhandled by user code HResult=-2146233069 Message=No parameterless constructor defined for this object. Source=mscorlib StackTrace: at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at ElasticsearchCRUD.ElasticsearchMapping.MapIEnumerableEntitiesForMapping(ElasticsearchCrudJsonWriter elasticsearchCrudJsonWriter, EntityContextInfo parentEntityInfo, PropertyInfo prop, Boolean createPropertyMappings) at ElasticsearchCRUD.ElasticsearchMapping.MapCollectionOrArray(PropertyInfo prop, EntityContextInfo entityInfo, ElasticsearchCrudJsonWriter elasticsearchCrudJsonWriter, Boolean createPropertyMappings) at ShelterCloudDataManager.WebHost.Protocol.Models.SearchableInstrumentElasticSearchMapping.MapEntityValues(EntityContextInfo entityInfo, ElasticsearchCrudJsonWriter elasticsearchCrudJsonWriter, Boolean beginMappingTree, Boolean createPropertyMappings) in D:\git\shelterclouddatamanager\src\ShelterCloudDataManager.WebHost\Protocol\Models\SearchableInstrument.cs:line 119 at ElasticsearchCRUD.ContextAddDeleteUpdate.ElasticsearchSerializer.CreateBulkContentForParentDocument(EntityContextInfo entityInfo, ElasticsearchMapping elasticsearchMapping) at ElasticsearchCRUD.ContextAddDeleteUpdate.ElasticsearchSerializer.AddUpdateEntity(EntityContextInfo entityInfo) at ElasticsearchCRUD.ContextAddDeleteUpdate.ElasticsearchSerializer.Serialize(IEnumerable`1 entities) at ElasticsearchCRUD.ContextAddDeleteUpdate.ElasticsearchContextAddDeleteUpdate.d__10.MoveNext() InnerException:

damienbod commented 8 years ago

Hi @kdotzenrod

Does your DTO have a parameterless constructor?

Message=No parameterless constructor defined for this object.

Greetings Damien

kdotzenrod commented 8 years ago

yes, here's the DTO:

public class SearchableInstrument
{
    [ElasticsearchId]
    public Int64 Id { get; set; }

    [ElasticsearchLong]
    public Int64? VarastoId { get; set; }

    [ElasticsearchInteger]
    public int? MrktSymbolId { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string ComstockKey { get; set; }

    [ElasticsearchNested(IncludeInParent = true)]
    public List<String> Tickers { get; set; }

    [ElasticsearchInteger]
    public Int64? DowJonesId { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string Cusip { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string Sedol { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string Isin { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string SearchableCusip
    {
        get
        {
            if (String.IsNullOrEmpty(Cusip) || Cusip.Length <= 8)
                return Cusip;
            return Cusip.Substring(0, 8);
        }
    }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string DjnSymbol { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string DowJonesKey { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string Fuid { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string OfficialIdentifier { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string FactivaCode { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string QueryIsin { get; set; }

    [ElasticsearchString(Fields = typeof(FieldDataDefNotAnalyzed), Index = StringIndex.not_analyzed)]
    public string DowJonesLocalCode { get; set; }
}

I was wondering if had to do with how some of the reflection changes with DNXCORE50.

damienbod commented 8 years ago

I'll check this, the new JSON serializer has also some breaking changes.

Greetings Damien

kdotzenrod commented 8 years ago

here's the method that fails on MapCollectionOrArray in case that helps:

    public override void MapEntityValues(EntityContextInfo entityInfo, ElasticsearchCrudJsonWriter elasticsearchCrudJsonWriter, bool beginMappingTree = false, bool createPropertyMappings = true)
    {
            SearchableInstrument searchableInstrument = entityInfo.Document as SearchableInstrument;
            MapValue("id", searchableInstrument.Id, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("varastoid", searchableInstrument.VarastoId, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("mrktsymbolid", searchableInstrument.MrktSymbolId, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("comstockkey", searchableInstrument.ComstockKey, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("dowjonesid", searchableInstrument.DowJonesId, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("cusip", searchableInstrument.Cusip, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("sedol", searchableInstrument.Sedol, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("isin", searchableInstrument.Isin, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("searchablecusip", searchableInstrument.SearchableCusip, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("djnsymbol", searchableInstrument.DjnSymbol, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("dowjoneskey", searchableInstrument.DowJonesKey, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("fuid", searchableInstrument.Fuid, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("officialidentifier", searchableInstrument.OfficialIdentifier, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("factivacode", searchableInstrument.FactivaCode, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("queryisin", searchableInstrument.QueryIsin, elasticsearchCrudJsonWriter.JsonWriter);
            MapValue("dowjoneslocalcode", searchableInstrument.DowJonesLocalCode, elasticsearchCrudJsonWriter.JsonWriter);
            var typeInfo = typeof(SearchableInstrument).GetProperty("Tickers");
            MapCollectionOrArray(typeof(SearchableInstrument).GetProperty("Tickers"), entityInfo, elasticsearchCrudJsonWriter, true);

    }

}
damienbod commented 8 years ago

Hi @kdotzenrod

This is a bug. Thanks for finding. Serialization of a list of strings does not work. I'll fix this in the next package.

As a workaround until its fixed, create a wrapper class

public class Wrapper
{
        public string Tick { get; set; }
}

And then use this

[ElasticsearchNested(IncludeInParent = true)]
public List<Wrapper> Tickers { get; set; }

Test code

IElasticsearchMappingResolver elasticsearchMappingResolver = new ElasticsearchMappingResolver();

using ( var elasticsearchContext = new ElasticsearchContext( "http://localhost.fiddler:9200/", elasticsearchMappingResolver))
{
   // Add some tracing for the console
   elasticsearchContext.TraceProvider = new ConsoleTraceProvider();

   elasticsearchContext.IndexCreate<SearchableInstrument>();
}

Hope this helps

Greetings Damien

kdotzenrod commented 8 years ago

thanks, will give that a try