Created Entity using plugin has no valid Entity.Id Value - entity

I have managed to execute the statement to create an entity successfully without any errors, but the id of the entity remains as default 00000000-0000-0000-0000-000000000000. In CRM, the created entity did not appear too.
I have not included all fields in the entity, and only inputting 1 field for testing.
Is it due to some mandatory fields not being filled, that is causing the above false positive that the entity is created?
Below is my code snippet:
Call CreateCase(row)
foreach (DataRow row in caseTable.Rows)
{
Entity caseEntity = helper.GetCasebyID((string)row[Excel.ID]);
if (caseEntity == null)
{
caseEntity = CreateCase(row);
}
}
CreateCase(row):
private Entity CreateCase(DataRow row)
{
Entity caseEntity = new Entity("new_case");
if (!(string.IsNullOrEmpty(row[Excel.sourcename].ToString().Trim())))
{
caseEntity.Attributes[Case.sourcename] = row[Excel.sourcename];
}
helper.GetOrganizationService().Create(caseEntity);
Logger.Info(caseEntity.LogicalName + " " + caseEntity.Id + " created. ");
//output: case 00000000-0000-0000-0000-000000000000 created.
}
Helper class:
public class Helper
{
private OrganizationServiceProxy _proxy;
private IOrganizationService _org;
public IOrganizationService GetOrganizationService()
{
if (_org == null)
{
var credential = new ClientCredentials();
credential.Windows.ClientCredential.Domain = ConfigurationManager.AppSettings["Domain"];
credential.Windows.ClientCredential.UserName = ConfigurationManager.AppSettings["Username"];
credential.Windows.ClientCredential.Password = Decrypt(ConfigurationManager.AppSettings["Password"]);
Uri organizationUri = new Uri(ConfigurationManager.AppSettings["OrganizationUri"]);
Uri homeRealmUri = null;
_proxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credential, null);
_proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
_org = new OrganizationService(_proxy);
}
return _org;
}
}

You should not use the same object to check if record created or guid is available.
Below line in your code return Guid datatype and not subset of object.
helper.GetOrganizationService().Create(caseEntity);
Also when you create a record, Try to add atleast Primary name attribute value.
In your case it shall be new_name
So you should have your code as
Guid newlyCreatedCaseRecord = helper.GetOrganizationService().Create(caseEntity);
Logger.Info(caseEntity.LogicalName + " " + newlyCreatedCaseRecord + " created. ");
You could also fetch newly created Record from Database as Entity object.
Guid newlyCreatedCaseRecord = helper.GetOrganizationService().Create(caseEntity);
Entity newlyCaseEntity = helper.GetOrganizationService().Retrieve("new_case",newlyCreatedCaseRecord , new ColumnSet(true));
Logger.Info(newlyCaseEntity .LogicalName + " " + newlyCaseEntity.Id + " created. ");
Note: There can be Typo in code, try validating in Visual studio.

Related

Trying to update a row value in SQL with ASP.NET Core 6

I am trying to update a row value in SQL with my DbContext in ASP.NET Core 6. The column is named TextField but I get this error:
InvalidOperationException: The instance of entity type 'TextField' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
Here is my code:
[HttpPost]
public IActionResult UploadText(string newText, string section)
{
MgvaKrantransportContext DBContext = new MgvaKrantransportContext();
var textSelection = DBContext.TextFields.Where(m => m.Section.Equals(section)).ToList();
TextField newTextField = new TextField();
foreach (var textField in textSelection)
{
newTextField = new TextField() { Id = textField.Id, Section = section, TextContent = newText };
}
DBContext.Entry(newTextField).Property(x => x.TextContent).IsModified = true;
DBContext.SaveChanges();
return RedirectToAction("Index");
}
Thanks in advance
Best regards Max
If you want to update using a stub entity, don't query the database first. Simply remove this line
var textSelection = DBContext.TextFields.Where(m => m.Section.Equals(section)).ToList();
Alternatively, update the returned TextField(s) and don't create a new one.
eg
foreach (var textField in textSelection)
{
textField.TextContent = newText ;
}
DBContext.SaveChanges();

Localization With Database MVC

I am working on a multilingual ASP.NET MVC application (MVC4).
I want to make my resource file strings to be editable at runtime without recompiling the application and without app pool recycling And it doesn't look possible with .resx file, so I migrate to store string resources in Database.
I have to Get Each Label/String Resource From Database, so there will be more hits to database for each request. How to fix that?
I have googled around and someone suggests to load the resource in a dictionary and store it as application variable, at login/Sign In page and use that dictionary as resource instead of database hit.
I am confused, what will be effective approach.Can someone guide me in right direction to avoid more database hits?
Any help/suggestions will be highly appreciated.
Thanks
I ran into the same concerns using .resx files for localization. They just did not work well when the persons doing the translation were not programmers. Now, we have a translation page in our admin area. Works great.
One area which we still don't have a good solution for are the data annotations, which still use the .resx files. I have trimmed the source below to remove any references to our actual database structures or tables.
There is a fallback to using the underlying .resx file, if an entry does not exist in the database. If there is not an entry in the .resx file, I split the word whenever a capitol letter is found ( CamelSpace is a string extension method ).
Lastly, depending on your implementation, you may need to remove the context caching, especially if you are caching out of process.
A few examples of usage:
#LanguageDb.Translate("Enter your first name below","FirstNamePrompt")
#LanguageDb.Me.FirstName
#String
.Format(LanguageDb
.Translate(#"You can be insured for
{0} down and {1} payments of {2}"),
Model.Down,Model.NumPayments,
Model.InstallmentAmount)
public class LanguageDb : DynamicObject
{
public static dynamic Me = new LanguageDb();
private LanguageDb() { }
public static string Translate(string englishPhrase, string resourceCode = null)
{
return GetTranslation(englishPhrase, resourceCode) ?? englishPhrase;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = GetTranslation(binder.Name);
return true;
}
private static string GetTranslation(string resourceName, string resourceCode = null)
{
resourceCode = resourceCode ?? resourceName;
if (resourceCode.Contains(" ") || resourceCode.Length > 50)
{
resourceCode = resourceName.GetHashCode().ToString(CultureInfo.InvariantCulture);
}
var lang = (string)HttpContext.Current.Request.RequestContext.RouteData.Values["lang"] ?? "en";
// cache entries for an hour
var result = Get(subagent + "_" + lang + "_" + resourceCode, 3600, () =>
{
// cache a datacontext object for 30 seconds.
var context = Get("_context", 30, () => new YourDataContext()) as YourDataContext;
var translation = context.Translations.FirstOrDefault(row => row.lang == lang && row.Code == resourceCode);
if (translation == null)
{
translation = new Lookup {
Code = resourceCode,
lang = lang,
Value = Language.ResourceManager.GetString(resourceName, Language.Culture)
?? resourceName.CamelSpace()
};
context.Translations.Add(translation);
context.SaveChanges();
}
return translation.Value;
});
return result;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// ignore this
return true;
}
public static T Get<T>(string cacheId, int secondsToCache, Func<T> getItemCallback) where T : class
{
T item = HttpRuntime.Cache.Get(cacheId) as T;
if (item == null)
{
item = getItemCallback();
if (secondsToCache > 0)
{
HttpRuntime.Cache.Insert(
cacheId, item, null, Cache.NoAbsoluteExpiration,
new TimeSpan(0, 0, secondsToCache), CacheItemPriority.Normal, null);
}
else
{
HttpRuntime.Cache.Insert(cacheId, item);
}
}
return item;
}
}

MS Dynamics CRM. Get users who current record shared with

I have a entity record which is shared with or more users. I would like to unshare this record when Deactivate it. I want to do that in Plugin. But I can't understand how to get all users from sharing list who have access to this record. How to do that?
Here is my code snippet:
protected void ExecutePostPersonSetStateDynamicEntity(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
var context = localContext.PluginExecutionContext;
var targetEntity = (Entity)context.InputParameters["EntityMoniker"];
var state = (OptionSetValue)context.InputParameters["State"];
var columns = new ColumnSet(new[] { "statecode" });
var retrivedEntity = localContext.OrganizationService.Retrieve(targetEntity.LogicalName, targetEntity.Id, columns);
if (state.Value == 1)
{
RevokeAccessRequest revokeRequest = new RevokeAccessRequest()
{
Target = new EntityReference(personEntity.LogicalName, personEntity.Id),
Revokee = new EntityReference(neededEntity.LogicalName, needed.Id)
};
// Execute the request.
}
}
As you can see, I need an entity "neededEntity", I don't know how to get it from "targetEntity" or "retrievedEntity".
You need to use a RetrieveSharedPrincipalsAndAccessRequest
http://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.retrievesharedprincipalsandaccessrequest.aspx
You can start from the included example, basically inside the foreach you call your RevokeAcessRequest

Check for existing mapping when writing a custom applier in ConfORM

I am writing my first custom column name applier for ConfORM.
How do I check if another column has already been map with same mapping name?
This is what I have so far:
public class MyColumnNameApplier : IPatternApplier<PropertyPath, IPropertyMapper>
{
public bool Match(PropertyPath subject)
{
return (subject.LocalMember != null);
}
public void Apply(PropertyPath subject, IPropertyMapper applyTo)
{
string shortColumnName = ToOracleName(subject);
// How do I check if the short columnName already exists?
applyTo.Column(cm => cm.Name(shortColumnName));
}
private string ToOracleName(PropertyPath subject)
{
...
}
}
}
I need to shorten the generated column names to less than 30 characters to fit in with Oracle's 30 character limit. Because I am shortening the column names it is possible that the same column name can potentially be generated two different properties. I would like to know when a duplicate mapping occurs.
If I don't handle this scenario ConfORM/NHibernate allows two different properties to 'share' the same column name - this is obviously creates a problem for me.
if column names are mapped twice you will get exception about parameter count on first load. You can can check after configuring:
foreach (var clazz in config.ClassMappings)
{
var propertiesWithOneColumn = clazz.PropertyClosureIterator.Where(p => p.ColumnSpan == 1);
var distinctColumns = new HashSet<string>();
foreach (var prop in propertiesWithOneColumn)
{
var col = prop.ColumnIterator.First().Text;
if (distinctColumns.Add(col))
{
Console.WriteLine("duplicate column "+ col + " found for property " + prop.PersistentClass.ClassName + "." + prop.Name);
}
}
}

How to get the selected value of a dynamically created selectlist component

I am not sure whether this is even possible, but I am trying to get the values of dynamically created selectlists in a VisualForce Apex controller class.
I am dynamically creating a selectlist for each field in a particular object (e.g. Contact) using the code below, but now I do not know how to get the selected value back. I have tried setting the value of each in the constructor and on a separate line (not in code sample below), but this does not seem to work.
VisualForce page:
<apex:dynamicComponent componentValue="{!contactPageBlockSection}" />
Apex controller:
public Component.Apex.PageBlockSection GetContactPageBlockSection(string objectName)
{
Map<string, Schema.SObjectField> FieldMap;
FieldMap = Schema.SObjectType.Contact.fields.getMap();
Set<string> FieldSet = FieldMap.keySet();
List<string> FieldList = new List<string>();
FieldList.addAll(FieldSet);
FieldList.sort();
Component.Apex.PageBlockSection pbs = new Component.Apex.PageBlockSection(columns = 2);
for (string fieldName : FieldList)
{
Component.Apex.PageBlockSectionItem pbsi = new Component.Apex.PageBlockSectionItem();
Schema.DescribeFieldResult field = (FieldMap.get(fieldName)).getDescribe();
if (field.isUpdateable() && field.IsAccessible())
{
Schema.DisplayType dt = field.getType();
Component.Apex.OutputLabel lblText = new Component.Apex.OutputLabel(escape = false);
lblText.value = field.getLabel();
pbsi.childComponents.add(lblText);
Component.Apex.SelectList selList = new Component.Apex.SelectList(id = field.getName(), multiselect = false, size = 1, style = 'width:200px;');
if (dt == Schema.DisplayType.Integer || dt == Schema.DisplayType.Double || dt == Schema.DisplayType.Currency || dt == Schema.DisplayType.Percent)
{
AddSelectOption(selList, 'Keep highest value');
AddSelectOption(selList, 'Keep lowest value');
AddSelectOption(selList, 'Keep master value');
pbsi.childComponents.add(selList);
pbs.childComponents.add(pbsi);
}
}
}
return pbs;
}
private void AddSelectOption(Component.Apex.SelectList selList, string option)
{
Component.Apex.SelectOption selOption = new Component.Apex.SelectOption();
selOption.itemLabel = option;
selOption.itemValue = option;
selList.childComponents.add(selOption);
}
Many thanks in advance
just bind the value attribute of the dynamically created select list to a string property using expression syntax like:
String selectedValue {get; set;}
...
setList.expressions.value = '{!selectedValue}';
the property should then store the selected value just as it would in a static declarative definition of the select list.
You could try and use dynamic visualforce binding. I.E.
map<String,String> FieldToString {get; set;}
...
selList.expressions.value = '{!FieldToString[\'' + fieldname + '\']}';
However, I have never used dynamic visualforce bindings within dynamic visualforce so caveat emptor.