I have created Properties Management App with UI following the phonebook sample app for ASP.NET ZERO. I have multiple tabs on the Create Property popup, to segregate the UI contexts.
I can successully Create and Save a property listing. I can also open a listing and edit it and Save it. But, when I Create New Listing and Save the records, and want to edit without closing the popup , it's throwing an error. Note that since I have multiple tabs, I am not closing the popup at successful Save response.
Also, it after creating the record, the system is returning the newly created propertyId back all the way to the UI. That's the Id value that I send for the Edit action, that gets passed to EditPropertyAsync() that I have defined for Edit flow. I am trying to use the same method, sending it the Id that just got created, with only difference that I have not closed the popup and am trying to edit on the Create window itself.
Here's the log:
ERROR 2015-11-19 10:38:16,338 [16 ] lers.Filters.AbpExceptionFilterAttribute - AutoMapper.AutoMapperMappingException:
Mapping types:
Int32 -> Int32
System.Int32 -> System.Int32
Destination path:
Property.Address.Address.Id.Id
Source value:
0 ---> System.InvalidOperationException: The property 'Id' is part of the object's key information and cannot be modified.
at System.Data.Entity.Core.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata, Int32 ordinal, String memberName)
at System.Data.Entity.Core.Objects.EntityEntry.GetAndValidateChangeMemberInfo(String entityMemberName, Object complexObject, String complexObjectMemberName, StateManagerTypeMetadata& typeMetadata, String& changingMemberName, Object& changingObject)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName, Object complexObject, String complexObjectMemberName)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.Core.Objects.ObjectStateEntry.System.Data.Entity.Core.Objects.DataClasses.IEntityChangeTracker.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.DynamicProxies.Address_DC03C9817912E18A8FAA931110EEEF10FBB1519A7553CF5CAA7822ECD0C0FCBF.EntityMemberChanging(String )
at System.Data.Entity.DynamicProxies.Address_DC03C9817912E18A8FAA931110EEEF10FBB1519A7553CF5CAA7822ECD0C0FCBF.set_Id(Int32 )
at lambda_method(Closure , Object , Object )
at AutoMapper.Internal.PropertyAccessor.SetValue(Object destination, Object value)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.AssignValue(PropertyMap propertyMap, Object mappedObject, Object propertyValueToAssign)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap)
--- End of inner exception stack trace ---
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
at AutoMapper.MappingEngine.MapCore(Object source, Object destination, Type sourceType, Type destinationType, MappingOperationOptions options)
at AutoMapper.MappingEngine.Map[TSource,TDestination](TSource source, TDestination destination, Action`1 opts)
at AutoMapper.MappingEngine.Map[TSource,TDestination](TSource source, TDestination destination)
at AutoMapper.Mapper.Map[TSource,TDestination](TSource source, TDestination destination)
at Abp.AutoMapper.AutoMapExtensions.MapTo[TSource,TDestination](TSource source, TDestination destination)
at Joshi.IP.IpProperties.PropertyAppService.<EditPropertyAsync>d__11.MoveNext() in d:\Freelance Work\Nipun-SPA\SPA\island\Joshi.IP.Application\IpProperties\PropertyAppService.cs:line 77
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Joshi.IP.IpProperties.PropertyAppService.<CreateOrEditPropertyAsync>d__5.MoveNext() in d:\Freelance Work\Nipun-SPA\SPA\island\Joshi.IP.Application\IpProperties\PropertyAppService.cs:line 52
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithFinallyAndGetResult>d__c`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Abp.Extensions.ExceptionExtensions.ReThrow(Exception exception)
at Abp.WebApi.Controllers.Dynamic.Selectors.DynamicHttpActionDescriptor.<ExecuteAsync>b__0(Task`1 task)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
Here are the different code snippets that get involved at different points:
public async Task<int> CreatePropertyAsync(CreateOrEditPropertyInput input)
{
var property = input.Property.MapTo<Property>();
var propertyId = await _propertyRepository.InsertAndGetIdAsync(property);
return propertyId;
}
public async Task<int?> EditPropertyAsync(CreateOrEditPropertyInput input)
{
var property = await _propertyRepository.FirstOrDefaultAsync(p => p.Id == input.Property.Id);
input.Property.MapTo(property);
await _propertyRepository.UpdateAsync(property);
return input.Property.Id;
}
public class CreateOrEditPropertyInput : IInputDto
{
[Required]
public PropertyEditDto Property { get; set; }
}
[AutoMap(typeof(Property))]
public class PropertyEditDto
{
public const int MaxLength = 50;
public int? Id { get; set; }
public bool IsVacant { get; set; }
public bool IsPropertyToConsider { get; set; }
[Required]
[MaxLength(MaxLength)]
public string Dist { get; set; }
[Required]
[MaxLength(MaxLength)]
public string Sec { get; set; }
}
Javascript:
vm.init = function () {
propertyService.getPropertyForEdit({
id: vm.property.id
}).success(function (result) {
vm.property = result.property;
});
};
public async Task<GetPropertyForEditOutput> GetPropertyForEdit(NullableIdInput<int> input)
{
var output = new GetPropertyForEditOutput();
if (!input.Id.HasValue)//create
{
output.Property = new PropertyEditDto();
}
else //edit
{
var property = await _propertyRepository.FirstOrDefaultAsync(p => p.Id == input.Id.Value);
output.Property = property.MapTo<PropertyEditDto>();
}
return output;
}
public class GetPropertyForEditOutput : IOutputDto
{
public PropertyEditDto Property { get; set; }
}
Javascript:
//to save Property
function createOrEditProperty() {
vm.saving = true;
propertyService.createOrEditPropertyAsync({ property: vm.property }).success(function (data) {
vm.property.id = data;
abp.notify.info(app.localize('SavedSuccessfully'));
}).finally(function () {
vm.saving = false;
});
}
Thanks for the support!