Episerver PropertyList having Url type property does not storing data when upgraded to Episerver 11.3.1 which was working properly earlier in 10.10.1 - episerver

We are using PropertyList and which is working properly till we upgrade Episerver version to 11.3.1 from 10.10.1.
Here is the code snippet -
public class PropertyListBase<T> : PropertyList<T>
{
protected override T ParseItem(string value)
{
return JsonConvert.DeserializeObject<T>(value);
}
public override PropertyData ParseToObject(string value)
{
ParseToSelf(value);
return this;
}
}
Property class-
[PropertyDefinitionTypePlugIn]
public class PropertySliderList : PropertyListBase<Slider>
{
}
public class Slider
{
/// <summary>
/// Slide image in Carousel
/// </summary>
[UIHint(UIHint.Image)]
public ContentReference Image { get; set; }
/// <summary>
/// Display position of the slide in Carousel
/// </summary>
public int Rank { get; set; }
/// <summary>
/// Can be any link that to be associated with image in Carousel
/// </summary>
public Url AssociatedUrl { get; set; }
}
In the block there is property to store multiple slides-
public virtual IList<Slider> SliderBlock { get; set; }
When we tried to add slides in the block, it does not save value for AssociatedUrl property.
Any help will be appreciated.

Related

How determine fault StoryBoard

The initial problem is enough known - "Cannot animate '(0).(1)' on an immutable object instance".
There are many questions here in SO about it but all the solutions are more fixes or crutches. And most of questions are linked to concrete part of code.
Also there are few topics about this problem with possible causes:
https://wpftutorial.net/DebuggingAnimations.html
https://blogs.msdn.microsoft.com/mikehillberg/2006/09/25/tip-cannot-animate-on-an-immutable-object-instance/
I have huge corporate app where a have hundreds styles and storyboards. I can't disable them step by step and it's painstaking work to looking for problem part of code.
I look at these bug not from side of looking for in many xamls but from side of loging. I tried to research info in InvalidOperationException that is raised but there is no useful info like control place in xaml or smth else.
Also one idea is to create class inherited from Storyboard and to override methods.
But there is no methods to override.
Can someone propose how to log the internality of storyboard or other class that is responsible of animation?
At last I found sulution.
You should add classes: listener to animation, AttachedProperty and custom StoryBoard.
public static class TriggerTracing
{
static TriggerTracing()
{
// Initialise WPF Animation tracing and add a TriggerTraceListener
PresentationTraceSources.Refresh();
PresentationTraceSources.AnimationSource.Listeners.Clear();
PresentationTraceSources.AnimationSource.Listeners.Add(new TriggerTraceListener());
PresentationTraceSources.AnimationSource.Switch.Level = SourceLevels.All;
}
#region TriggerName attached property
/// <summary>
/// Gets the trigger name for the specified trigger. This will be used
/// to identify the trigger in the debug output.
/// </summary>
/// <param name="trigger">The trigger.</param>
/// <returns></returns>
public static string GetTriggerName(TriggerBase trigger)
{
return (string)trigger.GetValue(TriggerNameProperty);
}
/// <summary>
/// Sets the trigger name for the specified trigger. This will be used
/// to identify the trigger in the debug output.
/// </summary>
/// <param name="trigger">The trigger.</param>
/// <returns></returns>
public static void SetTriggerName(TriggerBase trigger, string value)
{
trigger.SetValue(TriggerNameProperty, value);
}
public static readonly DependencyProperty TriggerNameProperty =
DependencyProperty.RegisterAttached(
"TriggerName",
typeof(string),
typeof(TriggerTracing),
new UIPropertyMetadata(string.Empty));
#endregion
#region TraceEnabled attached property
/// <summary>
/// Gets a value indication whether trace is enabled for the specified trigger.
/// </summary>
/// <param name="trigger">The trigger.</param>
/// <returns></returns>
public static bool GetTraceEnabled(TriggerBase trigger)
{
return (bool)trigger.GetValue(TraceEnabledProperty);
}
/// <summary>
/// Sets a value specifying whether trace is enabled for the specified trigger
/// </summary>
/// <param name="trigger"></param>
/// <param name="value"></param>
public static void SetTraceEnabled(TriggerBase trigger, bool value)
{
trigger.SetValue(TraceEnabledProperty, value);
}
public static readonly DependencyProperty TraceEnabledProperty =
DependencyProperty.RegisterAttached(
"TraceEnabled",
typeof(bool),
typeof(TriggerTracing),
new UIPropertyMetadata(false, OnTraceEnabledChanged));
private static void OnTraceEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var triggerBase = d as EventTrigger;
if (triggerBase == null)
return;
if (!(e.NewValue is bool))
return;
if ((bool)e.NewValue)
{
// insert dummy story-boards which can later be traced using WPF animation tracing
var storyboard = new TriggerTraceStoryboard(triggerBase, TriggerTraceStoryboardType.Enter);
triggerBase.Actions.Insert(0, new BeginStoryboard() { Storyboard = storyboard });
//storyboard = new TriggerTraceStoryboard(triggerBase, TriggerTraceStoryboardType.Exit);
//triggerBase.ExitActions.Insert(0, new BeginStoryboard() { Storyboard = storyboard });
}
else
{
// remove the dummy storyboards
//foreach (TriggerActionCollection actionCollection in new[] { triggerBase.EnterActions, triggerBase.ExitActions })
foreach (TriggerActionCollection actionCollection in new[] { triggerBase.Actions })
{
foreach (TriggerAction triggerAction in actionCollection)
{
BeginStoryboard bsb = triggerAction as BeginStoryboard;
if (bsb != null && bsb.Storyboard != null && bsb.Storyboard is TriggerTraceStoryboard)
{
actionCollection.Remove(bsb);
break;
}
}
}
}
}
#endregion
private enum TriggerTraceStoryboardType
{
Enter, Exit
}
/// <summary>
/// A dummy storyboard for tracing purposes
/// </summary>
private class TriggerTraceStoryboard : Storyboard
{
public TriggerTraceStoryboardType StoryboardType { get; private set; }
public TriggerBase TriggerBase { get; private set; }
public TriggerTraceStoryboard(TriggerBase triggerBase, TriggerTraceStoryboardType storyboardType)
{
TriggerBase = triggerBase;
StoryboardType = storyboardType;
}
}
/// <summary>
/// A custom tracelistener.
/// </summary>
private class TriggerTraceListener : TraceListener
{
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
{
base.TraceEvent(eventCache, source, eventType, id, format, args);
if (format.StartsWith("Storyboard has begun;"))
{
TriggerTraceStoryboard storyboard = args[1] as TriggerTraceStoryboard;
if (storyboard != null)
{
// add a breakpoint here to see when your trigger has been
// entered or exited
// the element being acted upon
object targetElement = args[5];
// the namescope of the element being acted upon
INameScope namescope = (INameScope)args[7];
TriggerBase triggerBase = storyboard.TriggerBase;
string triggerName = GetTriggerName(storyboard.TriggerBase);
var str = "";
var element = targetElement as DependencyObject;
while (element != null)
{
str += element.ToString() + Environment.NewLine;
element = VisualTreeHelper.GetParent(element);
}
LoggingInfrastructure.DefaultLogger.Log(...);
}
}
}
public override void Write(string message)
{
}
public override void WriteLine(string message)
{
}
}
Then you could add property to xaml where you need:
<EventTrigger Ui:TriggerTracing.TriggerName="CopyTextBlockStyle PreviewMouseLeftButtonDown"
Ui:TriggerTracing.TraceEnabled="True" RoutedEvent="PreviewMouseLeftButtonDown">

Multiplicity constraint violated. The role 'Target' of the relationship '' has multiplicity 1 or 0..1."

I already found few similar questions on SO, but non of them really have the same case as mine. Basically I have two tables:
[Table("TestLoopStatistics")]
public class TestLoopStatisticsViewModel
{
public int ID { get; set; }
public int LoopNumber { get; set; }
public virtual ICollection<TestTimeStatisticsItemViewModel> TestTimeStatisticsItemViewModels { get; set; }
/// <summary>
/// Reference to the parent class to create one to many relationship
/// </summary>
public TestStatisticsViewModel TestStatisticsViewModel { get; set; }
/// <summary>
/// Id of the parent class will be used as a foreign key
/// </summary>
public int TestStatisticsViewModelId { get; set; }
}
and
[Table("TestTimeStatisticsItems")]
public class TestTimeStatisticsItemViewModel
{
public int ID { get; set; }
public TestTimeItemType ItemType { get; set; }
public string StartTime { get; set; }
[Column(TypeName = "datetime2")]
public DateTime StartTimeData { get; set; }
/// <summary>
/// Reference to the parent class to create one to many relationship
/// </summary>
public TestLoopStatisticsViewModel TestLoopStatisticsViewModel { get; set; }
/// <summary>
/// Id of the parent class will be used as a foreign key
/// </summary>
public int TestLoopStatisticsViewModelId { get; set; }
}
so class TestLoopStatisticsViewModel has One-To-Many relationship with TestTimeStatisticsItemViewModel, as simple as that.
However when I am trying to insert a new record into DB, I am getting:
Multiplicity constraint violated. The role 'TestTimeStatisticsItemViewModel_TestLoopStatisticsViewModel_Target' of the relationship 'MyProject.DAL.TestTimeStatisticsItemViewModel_TestLoopStatisticsViewModel' has multiplicity 1 or 0..1."
which is really confusing, I've already spent a day on it with no luck.
Thanks!

kendo grid sort datasource querystring in angular

Using the Kendo-Angular directives
<div kendo-grid k-data-source="MySource"
k-filterable="true" k-pageable="true"></div>
Have a kendo data source as part of my scope
$scope.MySource = new kendo.data.DataSource({
transport:{
read : {
url:"/MyUrl"
}
},
schema:{
data: "data"
total:function(response){return response.total},
model:{
fields:{
LastName:{type:"string"}
}
}
},
pageSize: 10,
serverFiltering: true,
serverPaging:true
})
The data loads fine (though I have a string issue where it does not paginate passed the 4th page that may be more related to the backend than this.
All that I'm doing is calling an asp.net controller route to return the data and as I mentioned the pagination seems to work fine but when I attempt to use the filterable the 'get' querystring looks somewhat like this...
/MyUrl?take=10&skip=0&page=1&pageSize=10&filter%5Bfilters%5D%5B0%5Bfield%5D=LastName&filter%5Bfilters%5D.........value%5D=Smith
My controller looks like this
public JsonResult MyUrl(int pageSize = 10, int skip = 10, string sort = "", string filter="")
{
// return jsonresult
}
What is going on with that URL and is my controller set up correctly? Do I need to setup a parameter map for the default kendo grid?
This is what the default parameter map is doing - passes the current data source state to jQuery. You can pass the state as JSON:
transport:{
read : {
url:"/MyUrl",
type: "POST",
contentType: "application/json"
},
parameterMap: function(options) {
return JSON.stringify(options);
}
},
Create a class like this
public class PagingOption
{
public PagingOption()
{
PageSizes = new List<int>();`enter code here`
}
/// <summary>
/// Specifies the current page number.
/// </summary>`enter code here`
public int take { get; set; }
/// <summary>
/// Specifies the number of items to show in a page.
/// </summary>
public int skip { get; set; }
public int page { get; set; }
public int pagesize { get; set; }
public List<SortDescription> sort { get; set; }
/// <summary>
/// Specifies different page sizes.
/// </summary>
public IList<int> PageSizes { get; set; }
}
public class SortDescription
{
public string field { get; set; }
public string dir { get; set; }
}
and pass it as a parameter to your web call on server side
public JsonResult MyUrl(PagingOption pagingoption)
{
// return jsonresult
}
it will convert the query paramters to paging option class

IoC-MEF injection problem

I use Caliburn.Micto as MVVM framework for my WPF application and also MEF for injection.
UML of my application look like this: http://i54.tinypic.com/2n1b4mx.png
My scenario is: I create in view-model-1 (in project is LogOnViewModel) new view-model-2 (in my project is MessengerViewModel) with shell-view-model method.
I need pass object from view-model-1 to constructor of view-model-2.
I use MEF on injection class from external assembly which is loaded in boostraper class.
On creation of new view-models I use abstract factory pattern, here is my implementation:
/// <summary>
/// Factory interfaces
/// </summary>
public interface IViewModelFactory
{
ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel);
IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account);
}
/// <summary>
/// Concrent implementation of factory
/// </summary>
[Export(typeof(IViewModelFactory))]
public class DefaulFactoryViewModel:IViewModelFactory
{
#region Implementation of IViewModelFactory
//create start up view-model
public ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel)
{
return new LogOnViewModel(shellViewModel);
}
//this method create new view model
//it is used in LogOnViewModel
public IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account)
{
return new MessengerViewModel(shellViewModel, account);
}
}
I use this factory class in my shell-view-model. Shell-view-model class look like this:
/// <summary>
/// Shell model interface
/// </summary>
public interface IShellViewModel
{
//create start up view-model
void ShowLogOnView();
//this method create new view model
//it is used in LogOnViewModel
void ShowMessengerView(PokecAccount account);
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
//factory interface
private readonly IViewModelFactory _factory;
[ImportingConstructor]
public ShellViewModel(IViewModelFactory factory)
{
//inject factory
_factory = factory;
//show startup view model
ShowLogOnView();
}
public void ShowLogOnView()
{
//create LogOnViewModel class with factory
var model = _factory.CreateLogOnViewModel(this);
ActivateItem(model);
}
/// <summary>
/// Create MessengerViewModel
/// </summary>
/// <param name="account">account in this case is send from LogOnViewModel class </param>
public void ShowMessengerView(PokecAccount account)
{
//create MessengerViewModel class with factory
var model = _factory.CreateMessengerViewModel(this, account);
ActivateItem(model);
}
}
}
Start up view-model. LogOnViewModel class:
public interface ILogOnViewModel : IScreen, IDataErrorInfo
{
string Nick { get; set; }
string Password { get; set; }
bool CanLogOn { get; set; }
void LogOn(string nick, string password);
}
public class LogOnViewModel : Screen, ILogOnViewModel
{
/// <summary>
/// inject class from external assembly
/// after creation of this class is still null
/// </summary>
[Import]
public IPokecConnection PokecConn { get; set; }
private readonly IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public LogOnViewModel(IShellViewModel shellViewModel)
{
_shellViewModel = shellViewModel;
_account = new PokecAccount();
}
//CREATE NEW VIEW MODEL
public void CreateNewView()
{
//create new view-model (MessengerViewModel)
_shellViewModel.ShowMessengerView(_account);
}
}
MessengerViewModel class:
public interface IMessengerViewModel : IScreen
{
BitmapImage AvatarImage { get; set; }
string AvatarStatus { get; set; }
KeyValuePair<string, Friend> SelectedFriend { get; set; }
}
public class MessengerViewModel : Screen, IMessengerViewModel
{
[Import]
private IPokecService _pokecService;
[Import]
private IPokecConnection _pokecConn;
private IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public MessengerViewModel(IShellViewModel shellViewModel, PokecAccount account)
{
_shellViewModel = shellViewModel;
_account = account;
}
}
I have problem with injection into view-model class. On creation of view-model classes I use factory pattern, but I need inject in this class also from external assembly.
For example: After creation of LogOnVieModel class is IPokecConnection PokecConn{ get; set;} still null.
What is the most suitable solution in my case? Where is it problem ? Thank for help.
The factory pattern you are using doesn't do any composition outside of composing the ViewScreenModel class itself. You need to tell MEF to compose your view models, if they are not being created through injection. Update your factory class to compose the instance before returning it;
public ILogOnViewModel CreateLogOnViewModel
{
var model = new LogOnViewModel();
var container = // set this to your reference of CompositionContainer
container.ComposeParts(model);
return model;
}
...where Bootstapper.Container is your instance of CompositionContainer.
On another note, why have you made another account, instead of using your current one

Validating method arguments with Data Annotation attributes

The "Silverlight Business Application" template bundled with VS2010 / Silverlight 4 uses DataAnnotations on method arguments in its domain service class, which are invoked automagically:
public CreateUserStatus CreateUser(RegistrationData user,
[Required(ErrorMessageResourceName = "ValidationErrorRequiredField", ErrorMessageResourceType = typeof(ValidationErrorResources))]
[RegularExpression("^.*[^a-zA-Z0-9].*$", ErrorMessageResourceName = "ValidationErrorBadPasswordStrength", ErrorMessageResourceType = typeof(ValidationErrorResources))]
[StringLength(50, MinimumLength = 7, ErrorMessageResourceName = "ValidationErrorBadPasswordLength", ErrorMessageResourceType = typeof(ValidationErrorResources))]
string password)
{ /* do something */ }
If I need to implement this in my POCO class methods, how do I get the framework to invoke the validations OR how do I invoke the validation on all the arguments imperatively (using Validator or otherwise?).
We have approached it like this:
We have a ValidationProperty class that takes in a RegularExpression that will be used to validate the value (you could use whatever you wanted).
ValidationProperty.cs
public class ValidationProperty
{
#region Constructors
/// <summary>
/// Constructor for property with validation
/// </summary>
/// <param name="regularExpression"></param>
/// <param name="errorMessage"></param>
public ValidationProperty(string regularExpression, string errorMessage)
{
RegularExpression = regularExpression;
ErrorMessage = errorMessage;
IsValid = true;
}
#endregion
#region Properties
/// <summary>
/// Will be true if this property is currently valid
/// </summary>
public bool IsValid { get; private set; }
/// <summary>
/// The value of the Property.
/// </summary>
public object Value
{
get { return val; }
set
{
if (this.Validate(value))//if valid, set it
{
val = value;
}
else//not valid, throw exception
{
throw new ValidationException(ErrorMessage);
}
}
}
private object val;
/// <summary>
/// Holds the regular expression that will accept a vaild value
/// </summary>
public string RegularExpression { get; private set; }
/// <summary>
/// The error message that will be thrown if invalid
/// </summary>
public string ErrorMessage { get; private set; }
#endregion
#region Private Methods
private bool Validate(object myValue)
{
if (myValue != null)//Value has been set, validate it
{
this.IsValid = Regex.Match(myValue.ToString(), this.RegularExpression).Success;
}
else//still valid if it has not been set. Invalidation of items not set needs to be handled in the layer above this one.
{
this.IsValid = true;
}
return this.IsValid;
}
#endregion
}
Here's how we would create a Validation property. Notice how the public member is a string, but privately I am using a 'ValidationProperty.'
public string TaskNumber
{
get { return taskNumber.Value.ToString(); }
set
{
taskNumber.Value = value;
OnPropertyChanged("TaskNumber");
}
}
private ValidationProperty taskNumber;
Now, whenever the value is set, the business layer will validate that it's a valid value. If it's not, it will simply throw a new ValidationException (in the ValidationProperty class). In your xaml, you will need to set NotifyOnValidationError & ValidatesOnExceptions to true.
<TextBox Text="{Binding TaskNumber, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}"/>
With this approach, you would probably have a form for creating a new 'User' and each field would valitate each time they set it (I hope that makes sense).
This is the approach that we used to get the validation to be on the business layer. I'm not sure if this is exactly what you're looking for, but I hope it helps.

Resources