I am struggling with how I do the following in LightSwitch. I am 'intercepting' the entity during the partial void tblStaffExtendeds_Updating(tblStaffExtended entity) and then pulling some data from our local ldap and trying to set one of the properties of the entity to a specific value, like so:
partial void tblStaffExtendeds_Updating(tblStaffExtended entity)
{
string ldapPath = #"LDAP://DC=myLDAP,DC=myLDAP";
string user = entity.GPEmployeeID.ToString();
string[] props = {
ActiveDirectoryInfo.strings.DISPLAYNAME, ActiveDirectoryInfo.strings.EMAIL,
ActiveDirectoryInfo.strings.LOGONALIAS, ActiveDirectoryInfo.strings.PHONE,
ActiveDirectoryInfo.strings.OFFICE, ActiveDirectoryInfo.strings.TITLE,
ActiveDirectoryInfo.strings.GPEMPLOYEEID
};
var propResults = ActiveDirectoryInfo.UserPropertySearchByGPEmpID(user, ldapPath, props);
entity.tblAdminStaffType.StaffType = propResults[ActiveDirectoryInfo.strings.TITLE];
entity.WorkEmail = propResults[ActiveDirectoryInfo.strings.EMAIL];
entity.UserID = propResults[ActiveDirectoryInfo.strings.LOGONALIAS];
entity.WorkPhone = propResults[ActiveDirectoryInfo.strings.PHONE];
}
Now for fields like WorkEmail and WorkPhone this works fine as those properties are just strings and that is what I am getting from LDAP.
However I do I go about setting the StaffType which is a reference to an Admin Table entry? LDAP returns a string which matches the description on the Admin Table but on the Entity I would need to set it to the correct ID, I am assuming.
Is there someway to do this, short of creating "Look Up" methods to find the ID from the Admin Table by matching the Description to my String from LDAP?
The solution should look something like this:
string title = propResults[ActiveDirectoryInfo.strings.TITLE];
var qryAdminStaffType = from st in DataWorkspace.ApplicationData.StaffTypes
where st.Title == title
select st;
entity.tblAdminStaffType.StaffType = qryAdminStaffType.FirstOrDefault();
In this example, I'm assuming that your data source is called ApplicationData (the LS default name), that the StaffTypes table holds your staff types, and that you are matching the Title attribute. Note that if there is no match to the title, FirstOrDefalt() will return null.
Related
I have a viewmodel to update data (from API, not view) with params like below:
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
i just want to update "name", so my param like below:
{
"name": "my name"
}
its name changed become "my name" but its email and phone become null. how to avoid params changed to be null if they don't exist in input form?
Thanks...
You'll have to adjust whatever does the update so that it understands "null means do not set a value, rather than set the value to null"
For example if you're running a db update query you could:
UPDATE person
SET
name = COALESCE(#name, name),
email = COALESCE(#email, email),
phone = COALESCE(#phone, phone)
WHERE
id = #id
Now if any value is supplied as null the update will set the column to the same value it is currently (ie no-op)
If you're adjusting a c# object you can take a similar approach:
var p = db.FindPerson(viewmodel.PersonId);
p.Name = viewmodel.Name ?? p.Name;
...
As I see, you have a problem or misunderstanding in your software design.
If this API endpoint is meant to just update the name field, then you should not have the other fields in your ViewModel. However, if you update the other fields in some cases, then you should pass their values as well.
So maybe you need to call a Get endpoint first to get the all data you need in your client "web page for example" and then allow this client to resend the full JSON, not just the name.
Or you may just need an endpoint that just takes the name.
Another solution, in case you're using EF, is to ignore the null fields when updating the EF entity.
e.g.
...
var entity = dbContext.Employees.FirstOrDefault(e => e.Id == 3);
entity.Name = request.Name;
await dbContext.SaveChangesAsync();
...
I need to create an item with Person/People field.
I am able to populate fields like Title, DateTime, TextField as seen below, but I am not able to populate Person field at all.
I have tried sending Display Name, User ID and UPN.
var fieldValueSet = new FieldValueSet();
fieldValueSet.AdditionalData = new Dictionary<string, object>();
fieldValueSet.AdditionalData.Add("Title#odata.type", "Edm.String");
fieldValueSet.AdditionalData.Add("Title", task.Title);
fieldValueSet.AdditionalData.Add("Plan#odata.type", "Edm.String");
fieldValueSet.AdditionalData.Add("Plan", plan.Title);
fieldValueSet.AdditionalData.Add("Assigned#odata.type", "Edm.String");
fieldValueSet.AdditionalData.Add("Assigned", assignee.UserPrincipalName);
fieldValueSet.AdditionalData.Add("DueDate#odata.type", "Edm.String");
fieldValueSet.AdditionalData.Add("DueDate", task.DueDateTime);
var listItem = new ListItem
{
Fields = fieldValueSet
};
await graphServiceClient.Sites["SPURL:/sites/ITOddeleni:"].Lists["ListName"].Items
.Request()
.AddAsync(listItem)
Does your user principal name look like an email? (e.g. some.person#yourtenant.onmicrosoft.com). If that is the case then you should probably try to convert it to a sharepoint-claim version: i:0#.f|membership|some.dude#yourtenant.onmicrosoft.com.
If you have an authenticated ClientContext in your app, then you could resolve the username by calling the SharePoint utility:
Utility.ResolvePrincipal(context, context.Web, userEmail, PrincipalType.User, PrincipalSource.All, null, true);
If you don't have a context then you can try and combine strings (not as robust, but should work as well).
This answer suggests that you should try and set the LookupId value for the field (sorta the same way you set user values using the SharePoint's REST api):
var assigneeLookupId = // Get the assignee's user id on the site (wssid)
fieldValueSet.AdditionalData.Add("AssignedLookupId#odata.type", "Edm.Int32");
fieldValueSet.AdditionalData.Add("AssignedLookupId", assigneeLookupId);
The following schema would allow you to insert multiple person values:
SOLUTION
After help from comments i got this answer which worked
{
"AssignedLookupId#odata.type" : "Collection(Edm.Int32)"
"AssignedLookupId": [1,2,3]
}
This approach is in line with the way MS Graph returns values for Lookup fields.
I have tried to create a opportunity with suite talk API. while updating the entity field value it returns error because it needs internal id value of the field but it is not feasible to address the internal id.
ReflectionExtensions.SetPropertyValue(NS_OPPURTUNITY, map.Dst_Fld_Name, new RecordRef()
{
internalId = "2551",
type = RecordType.customer,
typeSpecified = true
});
i want to get rid of that static id to reference the entity.
As far as I know, you need the internal ID to reference any object through web services. You can however find the internal ID by first searching for the item you need to reference.
You can use a CustomerSearch to find the internal ID of your customer:
CustomerSearch custSearch = new CustomerSearch();
SearchStringField name = new SearchStringField();
name.SearchValue = "firstName";
name.operatorSpecified = true;
name.#operator = SearchStringFieldOperator.#is;
CustomerSearchBasic custBasic = new CustomerSearchBasic();
custBasic.firstName= customerEntityID;
custSearch.basic = custBasic;
// Search for the customer entity
SearchResult res = _service.search(custSearch);
//Get the internal ID of the customer
string internalID = ((Customer) (res.recordList[0])).internalId;
You can search for the customer using other fields besides 'firstName' as well. Check which other fields are available on the CustomerSearchBasic object here: CustomerSearchBasic
You can update the entity field on basis of external ID also but for this you need to remember certain things
1. You need to set externalID during creation of any record.
2. External ID is unique around the system.
3. Some records don't support external ID such as Custom List.
InventoryItem inventory = new InventoryItem();
inventory.externalId = "abc";
inventory.displayname = "Hello";
setPreferences();
WriteResponse writeRes = _service.update(inventory );
I am new in coding world :) it would be helpful if somebody can help me with my below query.
We have created two custom entity called Sector and Sub sector which are having an 1:N relationship with Account. Since they are relation fields hence they are lookup type and populated on the Account form.
On another part, we have InsideView( 3rd party tool) integrated with our Contact and account form. We have mapped certain fields from Inside view with CRM fields to update the data from the inside view when it is being synced however Inside view does not support Lookup type field hence we cannot map lookup field type data.
We discovered this barrier recently when we tried to map our custom entity (sector and Subsector) with inside view. Since we cannot map lookup field type we thought to have two text field instead and map it with Inside view. Once data is synced these two text fields will get filled out with the sector and subsector name.
Now, we want to copy information from text fields to the lookup field (custom fields Sector and Sub sector)
thanks in advance for your help :)
Bhavesh
I am not understanding your requirement but you can fill a lookup field with some text.
Use following code:
function setLookupField() {
var context = Xrm.Page.context;
var UserID = context.getUserId();// your id
var UserName=context.getUserName();//your text
var lookupData = new Array();
var lookupItem = new Object()`enter code here`;
//Set the GUID
lookupItem.id = UserID;
//Set the name
lookupItem.name = UserName;
lookupItem.entityType = "systemuser";// entity name of lookup
lookupData[0] = lookupItem;
//If existing value is empty, then set new value
var existingValue = Xrm.Page.getAttribute("new_usercreatedby").getValue();
if (existingValue === null) {
Xrm.Page.getAttribute("new_usercreatedby").setValue([{
id: UserID,
name: UserName,
entityType: "systemuser"
}]);
} else {
return;
}
}
I have a model like below
public class XYZModel
{
public string Id; // GUID, primary key;
public string Name;
public string AssociationId; // GUID, AllowNull;
}
what I am doing..
This is working fine
XYZModel abc = new XYZModel();
abc.Id = Convert.ToString(Guid.NewGuid());
abc.Name = "ABC Name";
xyzDbContext.XYZModels.Add(abc);
xyzDbContext.SaveChanges();
What is my goal ? Get entity by id, Edit it, Change its primary key Id value, and add it as a new entry. but error occurred while adding.
XYZModel xyz = xyzDbContext.XYZModels.Find("xyzguid");
//modifying it
xyz.AssociationId = xyz.Id;
xyz.Id = Convert.ToString(Guid.NewGuid());
xyz.Name = "New Name";
//trying to add it as new entry
xyzDbContext.XYZModels.Add(xyz);// Error
xyzDbContext.SaveChanges();
It throw an error
The property 'Id' is part of the object's key information and cannot be modified.
You can do that only if the xyz object is detached from Context.
Two ways to do that:
XYZModel xyz = xyzDbContext.XYZModels.Find("xyzguid");
xyzDbContext.Entry(xyz).State = EntityState.Detached;
Or using AsNoTracking.FirstOrDefault
XYZModel xyz = xyzDbContext.XYZModels.AsNoTracking().FirstOrDefault(s => s.Id =="xyzguid");
Your code with first approach:
XYZModel xyz = xyzDbContext.XYZModels.Find("xyzguid");
xyzDbContext.Entry(xyz).State = EntityState.Detached;
//modifying it
xyz.AssociationId = xyz.Id;
xyz.Id = Convert.ToString(Guid.NewGuid());
xyz.Name = "New Name";
//trying to add it as new entry
xyzDbContext.XYZModels.Add(xyz);// No Error
xyzDbContext.SaveChanges();
Note:
You must use DatabaseGeneratedOption.None annotation on Id property.
Entity Framework tracks objects as you edit them. If you want a new row inserted into the database, create a new object in memory with the values you want and add that. A library like AutoMapper might come in handy here.