Conditionally overwrite destination if no destination object is used - automapper

I would like to setup an Automapper mapping that follows the following rules.
If the "in place" destination syntax is not used, map a particular member to a value
If an object is passed in, then use the destination value
I've tried this every way I can think of. Something like this:
Mapper.CreateMap<A, B>()
.ForMember(dest => dest.RowCreatedDateTime, opt => {
opt.Condition(dest => dest.DestinationValue == null);
opt.UseValue(DateTime.Now);
});
This always maps the value. Essentially what I want is this:
c = Mapper.Map<A, B>(a, b); // does not overwrite the existing b.RowCreatedDateTime
c = Mapper.Map<B>(a); // uses DateTime.Now for c.RowCreatedDateTime
Note: A does not contain a RowCreatedDateTime.
What are my options here? It's very frustrating since there appears to be no documentation on the Condition method, and all the google results seem to be focused around where the source value is null, rather than the destination.
EDIT:
Thanks to Patrick, he got me on the right track..
I figured out a solution. If anyone has a better way of doing this, please let me know. Note I had to reference dest.Parent.DestinationValue rather than dest.DestinationValue. For some reason, dest.DestinationValue is always null.
.ForMember(d => d.RowCreatedDateTime, o => o.Condition(d => dest.Parent.DestinationValue != null))
.ForMember(d => d.RowCreatedDateTime, o => o.UseValue(DateTime.Now))

I believe you need to set up two mappings: one with the Condition (which determines IF a mapping should be performed) and one which defines what to do if the Condition returns true. Something like this:
.ForMember(d => d.RowCreatedDateTime, o => o.Condition(d => d.DestinationValue == null);
.ForMember(d => d.RowCreatedDateTime, o => o.UseValue(DateTime.Now));

Related

Automapper - an expression tree lambda cannot contain a null propagating operator

I have a following mapping in Automapper
.ForMember(d => d.Comment1, opt => opt.MapFrom(src => src.Comments?.FirstOrDefault(c => c.Type == "COMMENT1")?.Text))
But I am able to figure a way around the error
an expression tree lambda cannot contain a null propagating operator
Is there a simple way for doing this?

Automapper will not ignore property

I have a mapping between two classes:
CreateMap<A, B>()
.ForMember(b => b.Foo, cfg => cfg.MapFrom(a => a.Aoo.Foo))
.ReverseMap()
.IgnoreAllPropertiesWithAnInaccessibleSetter()
.IgnoreAllSourcePropertiesWithAnInaccessibleSetter()
.ForMember(a => a.Aoo, opts => opts.Ignore());
I would expect, from the last Ignore() alone, that when mapping a B to an A, Automapper would not try to assign a value to A. However, I do such a thing here:
var a = _mapper.Map<A>(b);
And I get the following exception:
System.NullReferenceException : typeMapDestination.Aoo cannot be null because it's used by ForPath.
Why is it trying to assign a value here? I even looked at the source code and this exception only gets thrown when the setter for that property is null!

ModX Revo getimagelist snippet. How can I search for a string in the field?

$output = $modx->runSnippet('getImageList',array(
'tvname' => 'workOrders',
'where' => $_GET['search'] ,
'tpl' => 'workOrdersList',
'docid' => 3
));
One of the fields is a string with parameters. How can I check whether my search string is a part of that field? I have looked up how to use "where" parameter to accomplish this task but I am still stuck.
If you just use this extra (getUrlParam), you can call this instead of refering to the GET directly:
So your call could look like this:
$output = $modx->runSnippet('getImageList', array(
'tvname' => 'workOrders',
'where' => $modx->runSnippet('getUrlParam', array('name' => 'search`)),
'tpl' => 'workOrdersList',
'docid' => 3
));
This also takes care of malicious url parameters.
Where needs to be formatted as a JSON value, so you would need to define which field you are querying against and format as JSON. E.g. 'where' => $modx->toJSON(array('pagetitle'=>$_GET['search']))

Getting destination member expression by source expression in AutoMapper

Let say I have mapping like this:
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))
Is it possible to get back the destination member expression by its relative source expression. Something like this:
Expression<Func<CalendarEventForm, object>> destinationExpression = Mapper.GetMemmberExpression(src => src.EventDate.Date);
Thanks in advance.

Drupal 6: Working with Hidden Fields

I am working on an issue i'm having with hooking a field, setting the default value, and making it hidden. The problem is that it is taking the default value, but only submitting the first character of the value to the database.
//Here is how I'm doing it
$form['field_sr_account'] = array( '#type' => 'hidden', '#value' => '45');
I suppose there is something wrong with the way that I have structured my array, but I can't seem to get it. I found a post, http://drupal.org/node/59660 , where someone found a solution to only the first character being submitted
//Here is the format of the solution to the post - but it's not hidden
$form['field_sr_account'][0]['#default_value']['value'] = '45';
How can I add the hidden attribute to this?
Have you tried using #default_value insted of #value?
Also if you're trying to pass some data to the submit that will not be changed in the form you should use http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#value .
The answer was actually to set the value and the hidden attribute separately, then set the value again in the submit handler using the following format.
I'm not sure if it's all necessary, I suppose I probably don't need to assign it in the form alter, but it works, so I'm going to leave it alone...
$form['#field_sr_account'] = $club;
$form['field_sr_account'] = array( '#type' => 'hidden','#value' => $club);
}
}
/*in submit handler, restore the value in the proper format*/
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));
An interesting solution from http://drupal.org/node/257431#comment-2057358
CCK Hidden Fields
/**
* Implementation of hook_form_alter().
*/
function YourModuleName_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && isset($form['#node'])) {
### Make a CCK field becoming a hidden type field.
// ### Use this check to match node edit form for a particular content type.
if ($form_id === 'YourContentTypeName_node_form') {
$form['#after_build'] = array('_test_set_cck_field_to_hidden');
}
}
}
function _test_set_cck_field_to_hidden($form, &$form_state) {
$form['field_NameToBeHidden'][0]['value']['#type'] = 'hidden';
$form['field_NameToBeHidden'][0]['#value']['value'] = 'testValue';
return $form;
}

Resources