Get Map(Types:String,Types:String) in .Net application - axapta

In AX 2009 I have class with method returning Map.
In ะก# I have null:
using (Axapta Ax = new Axapta())
{
Ax.Logon(null, null, null, null);
AxaptaObject ax = Ax.CreateAxaptaObject("SomeClass");
object obj = ax.Call("getMapData",1);
Dictionary<String, String> dict = obj as Dictionary<String, String>;
In this code dict is null. Why?
Is it possible to get complex data type from AX on .Net side?

Sorry, but a Map in X++ is not the same thing as a Dictionary in C#.
You can use a map though:
AxaptaObject map = ax.Call("getMapData",1);
Then call the map with:
String val = map.call("lookup", "key");

full code to do it (get Dictionary):
Dictionary<String,String> dict = new Dictionary<String,String>();
String key, value;
using (Axapta Ax = new Axapta())
{
Ax.Logon(null, null, null, null);
AxaptaObject someClass= Ax.CreateAxaptaObject("SomeClass");
AxaptaObject map = someClass.Call("getMapData",1) as AxaptaObject;
AxaptaObject mapIterator = Ax.CreateAxaptaObject("MapIterator", map);
while ((bool)mapIterator.Call("more"))
{
key = mapIterator.Call("key").ToString();
value = mapIterator.Call("value").ToString();
dict.Add(key,value);
mapIterator.Call("next");
}
}
return dict;

Related

I have Pull the value of ImagelocationID from dropdown through database using foreign key and While creating I got this error

This is my Controller
public async Task <IActionResult> SliderImage(ImageUploadViewModel imageUpload)
{
string stringFilename = UploadFile(imageUpload);
var branch = _context.BranchPages.Single(b => b.BranchId == imageUpload.ImageContentPageId);
var Sliderimage = new ImageContentModel
{
ImageOrderNo = imageUpload.ImageOrderNo,
ImageName = imageUpload.ImageName,
ImageLocation = imageUpload.ImageLocation,
RelatedLinks = imageUpload.RelatedLinks,
Image = stringFilename,
ImageContentPageId = Convert.ToInt32(branch),
};
_context.ImageContents.Add(Sliderimage);
await _context.SaveChangesAsync();
return View();
}
Error i have got
InvalidCastException: Unable to cast object of type 'H20_CafeAndPub.Models.BranchPageModel' to type 'System.IConvertible'.
System.Convert.ToInt32(object value)
H20_CafeAndPub.Controllers.HomePageController.SliderImage(ImageUploadViewModel imageUpload) in HomePageController.cs + var Sliderimage = new ImageContentModel
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()
You need to change the few code like this
Change 1 :
var branch = _context.BranchPages.Where(b => b.BranchId == imageUpload.ImageContentPageId).FirstOrDefault();
Change 2 :
ImageContentPageId = Convert.ToInt32(branch.Id)

.net Querying a Global Secondary Index in DynamoDB via DynamoDBContext

I have a dynamoDB table with a schema as follows:
var request = new CreateTableRequest
{
TableName = tableName,
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement("CompanyId", KeyType.HASH),
new KeySchemaElement("Timestamp", KeyType.RANGE)
},
AttributeDefinitions = new List<AttributeDefinition>
{
new AttributeDefinition("CompanyId", ScalarAttributeType.S),
new AttributeDefinition("Timestamp", ScalarAttributeType.N),
new AttributeDefinition("UserId", ScalarAttributeType.S)
},
GlobalSecondaryIndexes = new List<GlobalSecondaryIndex>
{
new GlobalSecondaryIndex
{
IndexName = "UserIndex",
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement("UserId", KeyType.HASH),
new KeySchemaElement("Timestamp", KeyType.RANGE)
},
Projection = new Projection {ProjectionType = "ALL"},
ProvisionedThroughput = new ProvisionedThroughput(5, 6)
}
},
ProvisionedThroughput = new ProvisionedThroughput(5, 6)
};
I can query the primary key successfully as follows:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
var sortKeyValues = new List<object>{minTimestamp};
result = await context.QueryAsync<AuditLogEntry>(companyId, QueryOperator.GreaterThanOrEqual, sortKeyValues,
new DynamoDBOperationConfig {OverrideTableName = TableName}).GetRemainingAsync();
}
And I can query the global secondary index without any constraint on the range key as follows:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
result = await context.QueryAsync<AuditLogEntry>(userId, new DynamoDBOperationConfig {OverrideTableName = TableName, IndexName = indexName})
.GetRemainingAsync();
}
But when I try to query the index with a range key constraint:
var client = new AmazonDynamoDBClient();
using (var context = new DynamoDBContext(client))
{
var sortKeyValues = new List<object> {minTimestamp};
result = await context.QueryAsync<AuditLogEntry>(userId, QueryOperator.GreaterThan, sortKeyValues, new DynamoDBOperationConfig {OverrideTableName = TableName, IndexName = indexName}).GetRemainingAsync();
}
I get the following error:
Exception thrown: 'System.InvalidOperationException' in AWSSDK.DynamoDBv2.dll
Additional information: Local Secondary Index range key conditions are used but no index could be inferred from model. Specified index name = UserIndex
Googling this error hasn't thrown any light on the issue. The reference to Local Secondary Index has me confused because I'm using a Global index, but I just can't see what's wrong with my code.
I've been able to get the query working by querying directly on the AmazonDynamoDBClient rather than using DynamoDBContext, but I'd really like to understand what I'm doing wrong and be able to use DynamoDBContext.
Any ideas would be appreciated.
In your model definition for AuditLogEntry you need to decorate properties that are part of the global secondary index with attributes - [DynamoDBGlobalSecondaryIndexRangeKey] and or [DynamoDBGlobalSecondaryIndexHashKey]. Example below.
public class AuditLogEntry {
// other properties ...
[DynamoDBProperty("UserId")]
[DynamoDBGlobalSecondaryIndexHashKey("UserIndex")]
public string UserId { get; set; }
}

Retrieving CRM 4 entities with custom fields in custom workflow activity C#

I'm trying to retrieve all phone calls related to opportunity, which statecode isn't equal 1. Tried QueryByAttribute, QueryExpression and RetrieveMultipleRequest, but still has no solution.
Here some code i wrote.
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext context = contextService.Context;
ICrmService crmService = context.CreateCrmService(true);
if (crmService != null)
{
QueryByAttribute query = new Microsoft.Crm.Sdk.Query.QueryByAttribute();
query.ColumnSet = new Microsoft.Crm.Sdk.Query.AllColumns();
query.EntityName = EntityName.phonecall.ToString();
query.Attributes = new string[] { "regardingobjectid" };
query.Values = new string[] { context.PrimaryEntityId.ToString() };
RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
retrieve.Query = query;
retrieve.ReturnDynamicEntities = true;
RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)crmService.Execute(retrieve);
}
return ActivityExecutionStatus.Closed;
}
And almost same for QueryExpression
QueryExpression phCallsQuery = new QueryExpression();
ColumnSet cols = new ColumnSet(new string[] { "activityid", "regardingobjectid" });
phCallsQuery.EntityName = EntityName.phonecall.ToString();
phCallsQuery.ColumnSet = cols;
phCallsQuery.Criteria = new FilterExpression();
phCallsQuery.Criteria.FilterOperator = LogicalOperator.And;
phCallsQuery.Criteria.AddCondition("statuscode", ConditionOperator.NotEqual, "1");
phCallsQuery.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, context.PrimaryEntityId.ToString();
I always get something like Soap exception or "Server was unable to proceed the request" when debugging.
To get exception details try to use following code:
RetrieveMultipleResponse retrieved = null;
try
{
retrieved = (RetrieveMultipleResponse)crmService.Execute(retrieve);
}
catch(SoapException se)
{
throw new Exception(se.Detail.InnerXml);
}

How to consume a LOB Adapter SDK-based design-time interfaces

I'm trying to build a web-based GUI to consume custom LOB Adapter SDK-based connectors.
In particular, I would like to browse the metadata using the IMetadataResolverHandler interface.
I'm having two problems:
The first problem happens when trying to instantiate the custom adapter. My plan is to obtain an instance of the IConnectionFactory interface, through which I could get a new IConnection and connect to the target LOB system.
Since the most interesting methods in the Adapter base class are protected, I can only seem to succeed using reflection (please, see the sample code below).
The second problem happens when trying to browse the metadata from the target system. The method Browse on the IMetadataResolverHandler interface expects an instance of a MetadataLookup object that I have no idea how to obtain.
Please, see the sample code below:
static void Main(string[] args)
{
var extension = new SqlAdapterBindingElementExtensionElement();
var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);
var isHandlerSupportedMethodInfo = adapter.GetType().GetMethod("IsHandlerSupported", BindingFlags.NonPublic | BindingFlags.Instance);
var buildConnectionUri = adapter.GetType().GetMethod("BuildConnectionUri", BindingFlags.NonPublic | BindingFlags.Instance);
var buildConnectionFactory = adapter.GetType().GetMethod("BuildConnectionFactory", BindingFlags.NonPublic | BindingFlags.Instance);
if (isHandlerSupportedMethodInfo == null || buildConnectionUri == null || buildConnectionFactory == null)
{
Console.WriteLine("Not a LOB adapter.");
Environment.Exit(1);
}
var isHandlerSupportedTHandler = isHandlerSupportedMethodInfo.MakeGenericMethod(typeof(IMetadataResolverHandler));
var isMetadataBrowseSupported = (bool)isHandlerSupportedTHandler.Invoke(adapter, new object[] { });
if (!isMetadataBrowseSupported)
{
Console.WriteLine("Metadata retrieval not supported.");
Environment.Exit(1);
}
var bindingElement = (SqlAdapterBindingElement)adapter;
bindingElement.AcceptCredentialsInUri = false;
bindingElement.InboundOperationType = InboundOperation.TypedPolling;
bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
bindingElement.PollingIntervalInSeconds = 10;
var binding = new CustomBinding();
binding.Elements.Add(adapter);
var parameters = new BindingParameterCollection();
var context = new BindingContext(binding, parameters);
var credentials = new ClientCredentials();
credentials.UserName.UserName = "username";
credentials.UserName.Password = "password";
var address = (ConnectionUri) buildConnectionUri.Invoke(adapter, new []{ new Uri("mssql://azure.database.windows.net//SampleDb?InboundId=uniqueId")});
var connectionFactory = (IConnectionFactory)buildConnectionFactory.Invoke(adapter, new object[] { address, credentials, context });
var connection = connectionFactory.CreateConnection();
connection.Open(TimeSpan.MaxValue);
MetadataLookup lookup = null; // ??
var browser = connection.BuildHandler<IMetadataBrowseHandler>(lookup);
connection.Close(TimeSpan.MaxValue);
}
Answering my own question, I figured it out by inspecting the code of the "Consume Adapter Service" wizard. The key is to use the IMetadataRetrievalContract interface which, internally, is implemented using up to three LOB-SDK interfaces, and in particular IMetadataResolverHandler.
Here is code that works without reflection:
var extension = new SqlAdapterBindingElementExtensionElement();
var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);
var bindingElement = (SqlAdapterBindingElement)adapter;
bindingElement.AcceptCredentialsInUri = false;
bindingElement.InboundOperationType = InboundOperation.TypedPolling;
bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
bindingElement.PollingIntervalInSeconds = 10;
var binding = new CustomBinding();
binding.Elements.Add(adapter);
const string endpoint = "mssql://azure.database.windows.net//SampleDb?InboundId=unique";
var factory = new ChannelFactory<IMetadataRetrievalContract>(binding, new EndpointAddress(new Uri(endpoint)));
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
factory.Open();
var channel = factory.CreateChannel();
((IChannel)channel).Open();
var metadata = channel.Browse(MetadataRetrievalNode.Root.DisplayName, 0, Int32.MaxValue);
((IChannel) channel).Close();
factory.Close();

Get id of new record in DNN Module

Am new to DNN Module development and using MVC and Linq. Have built a class and controller that allows me to create a record in a table on the database. Can anyone tell me the best way to retrieve the id of the newly created record? The part of the controller for creating the record is below.
class BlockController
{
public void CreateBlock(Block b)
{
using (IDataContext ctx = DataContext.Instance())
{
var rep = ctx.GetRepository<Block>();
rep.Insert(b);
}
}
}
Call to the controller from the code
var bC = new BlockController();
var b = new Block()
{
SectionId = int.Parse(ddlPickSection.SelectedValue),
PlanId = int.Parse(ddlPickPlan.SelectedValue),
BlockName = bId,
BlockDesc = "",
xPos = bX,
yPos = bY,
width = arrBWidths[i],
ModuleId = ModuleId,
CreatedOnDate = DateTime.Now,
CreatedByUserId = UserId,
LastModifiedOnDate = DateTime.Now,
LastModifiedByUserId = UserId,
};
bC.CreateBlock(b);
Thanks
When you submit changes (insert the record in DB) the ID would available in b object:
...
rep.InsertOnSubmit(b);
ctx.SubmitChanges();
int desireID = b.id;

Resources