I am using elastic 7.17.3 and NEST 7.17.3
I have a elastic response which I am trying to put in a list. I have below method. The method is generic and is called from different model classes.
public class Account
{
[JsonProperty(AnalyticsFields.AccessRegions)]
public string[] AccessRegions { get; set; }
[JsonProperty(AnalyticsFields.AccessUsers)]
public string[] AccessUsers { get; set; }
[JsonProperty(AnalyticsFields.AccountId)]
public string AccountId { get; set; }
[JsonProperty(AnalyticsFields.AccountIdAndName)]
public string AccountIdAndName { get; set; }
[JsonProperty(AnalyticsFields.AdvisorId)]
public string AdvisorId { get; set; }
[JsonProperty(AnalyticsFields.AdvisorIdAndName)]
public string AdvisorIdAndName { get; set; }
}
This is how the method converting the elastic response looks like
private void AddSearchResponseHits<T>(ISearchResponse<T> searchResponse, List<T> results) where T : class
{
results.AddRange(searchResponse.Hits.Select(h => h.Source).ToArray());
}
The problem is the field value becomes null even thought the searchresponse have the complete response from elastic. Please help me out. The field values should load in respective properties in the model class.
Related
I am creating POC using Asp.Net Web API. For mapping one object type to another i am using AutoMapper(v5.1.1). Here are the types which is being used for mapping:
//Entity
public class Goal : IVersionedEntity
{
public virtual int GoalId { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual DateTime StartDate { get; set; }
public virtual DateTime EndDate { get; set; }
public virtual string Reward { get; set; }
public virtual DateTime? DisabledDate { get; set; }
public virtual byte[] Version { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Schedule> Schedules { get; set; }
}
//Model
public class Goal
{
private List<Link> _links;
public int GoalId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
//public Status Status { get; set; }
public string Reward { get; set; }
public DateTime? DisabledDate { get; set; }
public User User { get; set; }
public ICollection<Schedule> Schedules { get; set; }
public List<Link> Links
{
get { return _links ?? (_links = new List<Link>()); }
set { _links = value; }
}
public void AddLink(Link link)
{
_links.Add(link);
}
}
I am mapping Goal Entity to Goal model type object as following:
public async System.Threading.Tasks.Task Configure()
{
Mapper.Initialize(cfg => cfg.CreateMap<Data.Entities.Goal, Models.Goal>()
.ForMember(m => m.Links, i => i.Ignore()));
}
and here is the 'AutoMapperConfigurator' class in 'App_Start':
public void Configure(IEnumerable<IAutoMapperTypeConfigurator> autoMapperTypeConfigurations)
{
autoMapperTypeConfigurations.ToList().ForEach(m => m.Configure());
Mapper.AssertConfigurationIsValid();
}
But it is throwing following exception:
The following property on TestApp.Web.Api.Models.Goal cannot be
mapped: Add a custom mapping expression, ignore, add a custom
resolver, or modify the destination type TestApp.Web.Api.Models.Goal.
Context: Mapping from type TestApp.Data.Entities.Goal to
TestApp.Web.Api.Models.Goal Exception of type
'AutoMapper.AutoMapperConfigurationException' was thrown.
See it's not showing which property is not getting mapped.
Any help for this isssue.
After spending hours on this, my final findings are follows:
You must have all your entity models and service models mapping correct to make it work. Even if one fails, the mentioned exception will be thrown. And if your complex type mappings are not correct you will get the above error.
In my case, I was missing how to configure the Complex Type with AutoMapper.
To configure Complex Type, either add .ForMember(m => m.Property, i => i.Ignore()) to ignore the complex type mapping if not needed or .ForMember(m => m.Property, i => i.MapFrom(j => Mapper.Map<Entity,ServiceModel>(j.Property))) for nested mapping (refer: http://www.softwarerockstar.com/2011/05/complex-object-mapping-using-automapper/) or use CustomMapping if there is come specific requirement during the mapping
I have a route on my WebAPI project that accepts an object as input ExportPostData. ExportPostData has a property called "contract" of type Contract which was successfully being populated when I called the route. I added the [OnDeserialized] tag to the Contract class and now it always fails deserialization. There are no errors thrown, just Contract is null. I have no idea how to debug this since my OnDeserialized method never even gets hit.
ExportPostData
public class ExportPostData
{
public Contract contract { get; set; }
public bool includeSubItems { get; set; }
public string user { get; set; }
public string[] projects { get; set; }
}
Contract
public class ZEstimateContract
{
public string _id { get; set; }
public string contractName { get; set; }
public string contractNumber { get; set; }
public string updatedBy { get; set; }
public DateTime updated_at { get; set; }
[OnDeserialized()]
internal void Deserialized()
{
// THIS NEVER GETS HIT
Console.WriteLine("I'm deserialized");
}
}
Change
[OnDeserialized()]
internal void Deserialized()
{
// THIS NEVER GETS HIT
Console.WriteLine("I'm deserialized");
}
to this:
[OnDeserialized]
internal void Deserialized(StreamingContext context)
{
// THIS GETS HIT NOW
Console.WriteLine("I'm deserialized");
}
Without the parameter, the method's signature doesn't match what OnDeserialized is looking for. See this article for details: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx
I am attempting to add a row to a Class in my Parse database using the API
I have managed to get the row added but I noticed that both the 'ACL & user__user' fields are blank.
My Request class looks like this:
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public int Amount { get; set; }
public int CreditBalance { get; set; }
}
And my function looks like this:
public static AccountDataResponse AddTransaction(AccountDataRequest details)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.parse.com/1/classes/AccountData");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("X-Parse-Application-Id", "xxxxx");
httpWebRequest.Headers.Add("X-Parse-REST-API-Key", "xxxxx");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(details);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return JsonConvert.DeserializeObject<AccountDataResponse>(result);
}
}
}
The 'user__user' links to the 'objectID(String)' in mu Users class.
I have tried adding it to my class as a string but it throws and error.
Can anyone tell me how to get the ACL and 'user__user' populated please?
Thanks
UPDATE:
I have learnt that the Pointer is a structure so have amended my classes as follows:
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public double Amount { get; set; }
public int CreditBalance { get; set; }
public Pointer Pointer { get; set; }
}
public class Pointer
{
public string __type { get; set; }
public string className { get; set; }
public string objectId { get; set; }
}
So, when I now call the API with the following:
POST https://api.parse.com/1/classes/AccountData HTTP/1.1
Content-Type: application/json
X-Parse-Application-Id: xxxxx
X-Parse-REST-API-Key: xxxxx
Host: api.parse.com
Content-Length: 163
Expect: 100-continue
Connection: Keep-Alive
{"OrderNo":"9","SiteName":"Trev","CreditDebit":"Debit","Amount":1.0,"CreditBalance":999,"Pointer":{"__type":"Pointer","className":"AccountData","objectId":"fvJ8jPjyjx"}}
This call produces no errors and returns a createddate and an objectid but the user(Pointer <__User> is still null.
I also tried changing the className to "__User" to which the API responds:
{"code":111,"error":"invalid type for key Pointer, expected *AccountData, but got *_User"}
This is what the empty column looks like in my AccountData class
And I am trying to tie it to the objectId in my User table:
Can anyone see what is wrong please?
If the column in Parse is defined as a Pointer to _User, then you need to pass the appropriate structure to Parse and not just the objectId. Take a look at the Data Types section of the Parse REST SDK. It has a paragraph and sample for passing a Pointer structure through the API.
Similarly, for ACLs you need to specify that structure as well. Details for it are in the security docs for the SDK.
In both cases, if you want to use an object->JSON converter, you'll need to build an object that appropriately represents that structure. That'll be a bit easier for Pointers than ACLs as the former has predefined keys whereas the latter uses dynamic key names (e.g. objectIds and role names).
Updated to include class definition
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public double Amount { get; set; }
public int CreditBalance { get; set; }
public Pointer user { get; set; }
}
I am trying to find one or more documents in RavenDB based on the values of a child collection.
I have the following classes
public class GoldenDocument
{
public GoldenDocument()
{
LinkedDocuments = new List<LinkedDocument>();
MergeMatchFields = new List<MergeMatchField>();
}
public string Id { get; set; }
public Guid SourceRowId { get; set; }
public List<MergeMatchField> MergeMatchFields { get; set; }
public List<LinkedDocument> LinkedDocuments { get; set; }
}
And the class that is in the collection MergeMatchFields
public class MergeMatchField
{
public string Id { get; set; }
public Guid OriginId { get; set; }
public string Name { get; set; }
public MatchType MatchType { get; set; }
public double MatchPerc { get; set; }
public string Value { get; set; }
}
In a List<MergeFields> mergeFields collection I have values that is not stored in RavenDB yet. Values are compared to values in a RavenDB document for find if it is a possible match by executing the following query:
using (var session = documentStore.OpenSession())
{
var docs = from gd in session.Query<GoldenDocument>()
from mf in gd.MergeMatchFields
from tf in mergeFields
where mf.Name == tf.Name
&& JaroWinklerCalculator.jaroWinkler(mf.Value, tf.Value) > .90d
&& !string.IsNullOrEmpty(mf.Value)
select gd;
}
I understand that ravenDB does not support SelectMany() so how would I go about getting the results from the Document store?
Create an index for this that would output the values you want to query on.
Note that you can't just execute arbitrary code the way you do here: JaroWinklerCalculator.jaroWinkler(mf.Value, tf.Value) > .90d
But you can use fuzzy queries, and they will do the same.
document Structure:
class UserAccountInfo
{
public String Id { get; set; }
public AccountType AccountType { get; set; }Servicetax
public String MainAccountMobileNo { get; set; }
public UserStatus Status { get; set; }
public String EmailId { get; set; }
public String DisplayName { get; set; }
**public Object User { get; set; }**
}
object stores instance of any type that is mentioned in Account type. the type that is stored in the object can be found using Accountype for ex; if Accountype is customer then instance stored in the object will be AccountinfoCustomer and so on. So using that I've tried to query but getting the following exception from raven.
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
{"Url: \"/indexes/dynamic/UserAccountInfos?query=AccountType%253ADistributor%2520AND%2520User).Customerstatus%253APending&start=0&pageSize=128&aggregation=None\"\r\n\r\nSystem.ArgumentException: The field ')_Customerstatus' is not indexed, cannot query on fields that are not indexed\r\n at Raven.Database.Indexing.Index.IndexQueryOperation.AssertQueryDoesNotContainFieldsThatAreNotIndexes()
This should work. Tested in current stable RavenDB 2.0.2230.
Tests here: https://gist.github.com/4692351
Are you on an older version?