I am developing a plugin in crm 5.0 to retrieve date "ct_valuedate" from an entity called "ct_marketvalue" and formatting and saving in a field called "ct_dateserial"
I get an error while I debug "The given key was not present in the dictionary"
public class MarketValueDateFormatting : PluginBase
{
protected override void ExecutePlugin()
{
try
{
switch (_crmMessage)
{
case CrmPluginMessageEnum.Create:
if (_context.InputParameters.Contains("ct_marketvalue"))
{
//Obtain the logical name of the entity
string moniker1 = ((EntityReference)_context.InputParameters["EntityMoniker"]).LogicalName;
//Verify that the target entity represents an Account.
//If not, this plug-in was not registered correctly.
if (moniker1.Equals("ct_marketvalue"))
{
Entity marketvalueimage = (Entity)_context.PostEntityImages["ct_marketvalue"];
Guid marketvalueid = marketvalueimage.Id;
if (marketvalueimage.Contains("ct_valuedate"))
{
DateTime dateserial = (DateTime)marketvalueimage.Attributes["ct_valuedate"];
String dateserialstring = dateserial.ToString("YYYYMMdd");
Ct_marketvalue marketvalue = new Ct_marketvalue();
marketvalue.Ct_dateserial = dateserialstring;
marketvalue.Id = marketvalueid;
_serviceContext.UpdateObject(marketvalue);
}
}
}
break;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
Few notes about your code.
You should check in your code that _context.PostEntityImages contains "ct_marketvalue". It's possible either to forgot register or to do a mistake in image name.
Might be better use .ToEntity rather than access attributes using .Attributes["ct_valuedate"].
I'm not sure what is purpose of the plugin you wrote, but it looks it is post stage plugin and it updates the same entity instance, that was in InputParameters. Might be better to make this plugin pre stage and update value directly in InputParameters. Because, if not "The given key was not present in the dictionary" exception, it will cause infinite loop. You will need check context.Depth.
Related
I upgrade from Play 2.5 to 2.7, and am having a problem with saving my forms.
When fields are changed and I call the Model.update() the changes are not persisted in the database (even though they show changed when debugging before the update is done)
When however I set them specifically, then they do persists. So it must have to do something with the fact that it does not detect the change and does not see the object as changed. I use getter and setters in the model, and all the properties are private.
This is the controller function (with the two lines to persist those two fields)
#Check(UserTask.MANAGER)
public Result updateSceneSet(Http.Request request) {
Messages messages = messagesApi.preferred(request);
Form<StreamingSceneSet> form = formFactory.form(StreamingSceneSet.class).bindFromRequest(request);
if (form.hasErrors()) {
if (form.rawData().get("id") != null && form.rawData().get("id").length() > 0) {
long itemId = Long.parseLong(form.rawData().get("id"));
StreamingSceneSet item = StreamingSceneSet.findById(itemId);
return badRequest(views.html.streaming.editSceneSetView.render(form, item, messages, request));
} else {
return badRequest(views.html.streaming.createSceneSetView.render(form,messages, request));
}
}
// Form is OK, has no errors we can proceed
StreamingSceneSet item = form.get();
item.setName(item.getName());
item.setDescription(item.getDescription());
// Insert or update?
if (item.getId() == null) {
item.insert();
flash("success", messages().at("addedSceneSet", item.getName()));
} else {
item.update();
flash("success", messages().at("updatedSceneSet", item.getName()));
}
return redirect(routes.Streaming.sceneSets());
}
It seems because when I started the upgrade I had some legacy classes I didn't have getters and setters, and as I had some issue I put in:
play.forms.binding.directFieldAccess = true
Removing this made everything work again.
strong text [Plugin error at Note entity][1]
[1]: http://i.stack.imgur.com/hRIi9.png
Hi,Anyone resolved my issue i got a Plug-in error which i worked at Update of "Note" entity.Basically i want a Plugin which converted pre-exiting Note attachment XML file into new .MMP extension file with the same name.
I have done following procedure firstly i created a "Converter_Code.cs" dll which contains Convert() method that converted XML file to .MMP file here is the constructor of the class.
public Converter(string xml, string defaultMapFileName, bool isForWeb)
{
Xml = xml;
DefaultMapFileName = defaultMapFileName;
Result = Environment.NewLine;
IsForWeb = isForWeb;
IsMapConverted = false;
ResultFolder = CreateResultFolder(MmcGlobal.ResultFolder);
}
In ConvertPlugin.cs Plug-in class firstly i retrieved Note entity attachment XML file in a string using following method in
IPluginExecutionContext context =(IPluginExecutionContext)serviceProvider.
GetService (typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory= (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService
(context.UserId);
if (context.InputParameters.Contains("Target")
&& context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
var annotationid = entity.GetAttributeValue<Guid>("annotationid");
if (entity.LogicalName != "annotation")
{
return;
}
else
{
try
{
//retrieve annotation file
QueryExpression Notes = new QueryExpression { EntityName ="annotation"
,ColumnSet = new ColumnSet("filename", "subject", "annotationid",
"documentbody") };
Notes.Criteria.AddCondition("annotationid", ConditionOperator.Equal,
annotationid);
EntityCollection NotesRetrieve = service.RetrieveMultiple(Notes);
if (NotesRetrieve != null && NotesRetrieve.Entities.Count > 0)
{
{
//converting document body content to bytes
byte[] fill = Convert.FromBase64String(NotesRetrieve.Entities[0]
.Attributes["documentbody"].ToString());
//Converting to String
string content = System.Text.Encoding.UTF8.GetString(fill);
Converter objConverter = new Converter(content, "TestMap", true);
objConverter.Convert();
}
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("something is going wrong");
}
}
}
}
and than A string is passed to "Converter" constructor as a parameter.
finally i merged all dll using ILMerge following method:
ilmerge /out:NewConvertPlugin.dll ConvertPlugin.dll Converter_Code.dll
and NewConvertPlugin is registered successfully but while its working its generate following error:
Unexpected exception from plug-in (Execute): ConverterPlugin.Class1: System.Security.SecurityException: That assembly does not allow partially trusted callers.
i also debug the plugin using Error-log but its not worked so i could not get a reason whats going wrong.
The error is caused by the library you merged inside your plugin.
First of all you are using CRM Online (from your screenshot) and with CRM Online you can use only register plugins inside sandbox.
Sandbox means that your plugins are limited and they run in a partial-trust environment.
You merged an external library that requires full-trust permissions, so your plugin can't work and this is the reason of your error.
Because you are in CRM Online, or you find another library (the Converter) that requires only partial-trust, hoping that the merge process will work, or you include (if you have it) the source code of the converter library directly inside your plugin.
I am trying to update a dataclass table with extra values after inserting some fields in the columns,again if i want insert the details in the same column,its not working,it gets in the second row,could anyone please help me,i want this answer as soon as possible
This is how I updated the row in bluemix by getting a particular column value position. Here is the code.
This is the code for getting the entire values from the bluemix table:
IBMQuery<Company> query = IBMQuery.queryForClass(Company.CLASS_NAME);
query.find().continueWith(new Continuation<List<Company>, Void>() {
public Void then(Task<List<Company>> task) throws Exception {
final List<Company> objects = task.getResult();
// Log if the find was cancelled.
if (task.isCancelled()) {
Log.e(CLASS_NAME, "Exception : Task " + task.toString()
+ " was cancelled.");
}
// Log error message, if the find task fails.
else if (task.isFaulted()) {
Log.e(CLASS_NAME, "Exception : "
+ task.getError().getMessage());
}
// If the result succeeds, load the list.
else {
companyList.clear();
for (IBMDataObject storeObject : objects) {
companyList.add((Company) storeObject);
}
if (task.isCompleted()) {
handler.sendEmptyMessage(2);
}
}
Where Company is the name of the Table and companyList is the company class array list.
After this code is executed the companylist will get all the rows and columns values stored in bluemix from which we can get the required row by using the query
query.whereKeyEqualsTo(User.RegisterName, userName);
query.whereKeyEqualsTo(User.Password, password);
Where User is the table name
RegisterName and Password are static variable defined in the User Class
userName and password is the user defined given inputs.
By getting the position of the required row retrieved in companyList, I do the update in the following way:
Company companyObject=Company.getPosition(position);
companyObject.setName("Something");
companyObject.save() query......
Now the problem is I'm able to do the update properly, but I'm not able to retrieve the table values from bluemix using the code which I mentioned in the top.
// Find a set of objects by class
IBMQuery<Item> queryByClass = IBMQuery.queryForClass(Item.class);
// Find a specific object
IBMQuery<Item> queryForObject = myItem.getQuery();
query.find().continueWith(new Continuation<List<Item>, Void>() {
#Override
public Void then(Task<List<Item>> task) throws Exception {
if (task.isFaulted()) {
// Handle errors
} else {
// do more work
List<Item> objects = task.getResult();
}
return null;
}
});
This code came from http://mbaas-gettingstarted.ng.bluemix.net/android
I am using scala and play framework. I want to use play security Authorization in my app.
Previously I implemented it in project using java and play like following :
public class Secured extends Security.Authenticator {
private static String EMAIL = "Email";
private static String U_COOKIE = "ucookie";
public String getUsername(Context ctx) {
String decodedText = null;
String CHARSET = "ISO-8859-1";
Cookies cookies = play.mvc.Controller.request().cookies();
try {
Cookie emailCookie = cookies.get(EMAIL);
Cookie uCookie = cookies.get(U_COOKIE);
if (uCookie !=null && uCookie.value() != null) {
String userId = uCookie.value();
}
if (emailCookie != null && emailCookie.value() != null) {
String email = emailCookie.value();
try {
decodedText = new String(Base64.decodeBase64(email.getBytes(CHARSET)));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Logger.error(e.getMessage());
}
return decodedText;
}
public Result onUnauthorized(Context ctx) {
String done = play.mvc.Controller.request().path();
return redirect(routes.RegController.signIn(done));
}
}
and I used above Authorization in all of my method using
#Security.Authenticated(Secured.class)
Before any of my methods throughout my application.
When I call any method #before that method gives call to secured class and authenticate user.
Now I want to implement same thing using scala. Following are my questions....
1) Is it possible to use # to inherit and call methods of secured class??
2) What is the right method to call play's security authentication??
P.S. I want to use cookies for implementation of security Authentication/Authorization.
Any help or workaround will be great favor..
If you build an application intended for production:
Don't do it
Use one of the many frameworks out there:
Deadbolt2 : https://github.com/schaloner/deadbolt-2
SecureSocial: http://www.securesocial.ws/
Silhouette : http://silhouette.mohiva.com/
They are also a great starting point to look for best practices.
If you want to do it mainly for learning and there are no real scecurity concerns go for:
https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition
There look for the heading auth it gives some information how to do it.
To have the authentication kick in before any method you could use a Filter to intercept the request:
https://www.playframework.com/documentation/2.3.x/ScalaInterceptors
I am having trouble in validating and reseting some fields based on the role of a user.
I am trying to develop a rest api with grails and my problem appears when i try to reset some fields based on the role of an user. I send a json with the desired "not allowed" changes via PUT to the controller. I modify the not allowed fields to ones that are correct for me and then call .save() and the "not alowed" fields are updated with their sent value, not with the modified by me values. Here is the code.
THE MODEL
package phonebook
class User {
String firstName
String lastName
String phoneNo
String address
String email
String password
boolean active = false
String hash
String authToken = ""
String role = "user"
static hasMany = [contacts:Contact]
static constraints = {
firstName(blank: false)
lastName(blank: false)
address(blank: true)
phoneNo(unique: true)
email(blank: false, unique: true)
password(blank: false)
role(blank: false, inList: ["user", "admin"])
hash(blank: true)
authToken(blank: true)
active(inList:[true,false])
}
}
THE METHOD FROM CONTROLLER:
#Transactional
def update(User userInstance) {
if (!isAuthenticated()){
notAllowed()
return
}
if (userInstance == null) {
notFound()
return
}
//if(isAdmin()){
def userBackup = User.findById(userInstance.id)
userInstance.role = userBackup.role
userInstance.active = userBackup.active
userInstance.hash = userBackup.hash
userInstance.authToken = userBackup.authToken
//}
if (userInstance.hasErrors()) {
respond userInstance.errors, view:'edit'
return
}
userInstance.save flush:false
request.withFormat {
'*'{ respond userInstance, [status: OK] }
}
}
THE JSON SENT VIA PUT
{
"id":"1",
"firstName": "Modified Name 23",
"role":"admin",
"active":"true",
"hash":"asdasd"
}
The above code should not modify my values for hash or active or role even if they are sent.
Any ideas?
Thanks.
The reason your changes are being saved is because by default any changes made to a domain instance will be flushed at the end of the session. This is known as open session in view with automatic session flushing. I recommend you do some reading on some of the main issues people face with GORM.
Proper use of discard may solve your issue. Discard your instance changes before you exit your controller.
For example:
if (!isAuthenticated()){
notAllowed()
userInstance.discard()
return
}
Edit
Based on conversation in the comments this perhaps may be the way to address your issue. A combination of discard and attach.
userInstance.discard()
def userBackup = User.findById(userInstance.id)
userInstance.role = userBackup.role
userInstance.active = userBackup.active
userInstance.hash = userBackup.hash
userInstance.authToken = userBackup.authToken
userInstance.attach()
I was helped by this method.
getPersistentValue
Example
def update(ShopItem shopItemInstance) {
if (shopItemInstance == null) {
notFound()
return
}
if (!shopItemInstance.itemPhoto){
shopItemInstance.itemPhoto =
shopItemInstance.getPersistentValue("itemPhoto");
}
if (shopItemInstance.hasErrors()) {
respond shopItemInstance.errors, view:'edit'
return
}
shopItemInstance.save flush:true
redirect(action: "show", id: shopItemInstance.id)
}
In your case:
userInstance.role = userInstance.getPersistentValue("role")
userInstance.active = userInstance.getPersistentValue("active")
userInstance.hash = userInstance.getPersistentValue("hash")
userInstance.authToken = userInstance.getPersistentValue("authToken")
It's better if you'll use the command objects feature. You can bind a command object with the request payload, validate it and than find and update the domain object.
You can find more details here:
http://grails.org/doc/2.3.x/guide/theWebLayer.html#commandObjects
And off the record you shoudn't use #Transactional in your controller. You can move that code into a service.
Eq:
def update(Long id, UserCommand cmd){
// Grails will map the json object into the command object and will call the validate() method if the class is annotated with #Validatable
}