Base solution for your next web application
Open Closed

Deserialize current Json object #6223


User avatar
0
evbenerji created

Hi all, Can anybody help to solving this problem. I try to add list of UserContacts to the User using repeater. (One to many relation) I get error about Json to Json array deserialization.

Entities;

User

public class User : AbpUser<User>
    {
        public virtual Guid? ProfilePictureId { get; set; }
        ...
        public virtual ICollection<UserContact> UserContacts { get; set; }
    }

UserContacts

[Table("UserContacts")]
public class UserContact : FullAuditedEntity<long> 
    {
        [Required]
	public virtual string ContactName { get; set; }
		
	[Required]
	public virtual string ContactPhone { get; set; }
        
	public virtual long UserId { get; set; }
	public User User { get; set; }
    }

DTO

    public class UserContactDto : EntityDto<long>
    {
        public string ContactName { get; set; }

        public virtual string ContactPhone { get; set; }

        public long UserId { get; set; } 
    }

UserAppService

public async Task<GetUserForEditOutput> GetUserForEdit(NullableIdDto<long> input)
        {
            //Getting all available roles
            ...

            var relatedUserContacts = await _userContactRepository.GetAll().Where(c=>c.UserId == input.Id.Value).ToListAsync();

            var output = new GetUserForEditOutput
            {
                Roles = userRoleDtos,
                ...
                RelatedUserContacts = ObjectMapper.Map<List<UserContactDto>>(relatedUserContacts)
            };

            if (!input.Id.HasValue)
            {
                ...
            }
            else
            {
                ...
            }

            return output;
        }

CreateOrUpdateUserInput

public class CreateOrUpdateUserInput
    {
        [Required]
        public UserEditDto User { get; set; }

        ...

        public List<UserContactDto> RelatedUserContacts { get; set; }

        public CreateOrUpdateUserInput()
        {
            ...
            RelatedUserContacts = new List<UserContactDto>();
        }
    }

GetUserForEditOutput

public class GetUserForEditOutput
    {
        ...

        public UserEditDto User { get; set; }

        ...

        public List<UserContactDto> RelatedUserContacts { get; set; } 
    }

_CreateOrEditModal.cshtml

@model CreateOrEditUserModalViewModel

...
<div id="UserContacts" name="userContacts">
                    <div class="form-group m-form__group" id="UserContacts">
                        <label>@L("UserContacts")</label>
                        <div data-repeater-list="UserContacts" class="col-lg-10">
                            @foreach (var userContact in Model.RelatedUserContacts)
                            {
                                <div data-repeater-item class="form-group m-form__group row align-items-center">
                                    <div class="col-md-4">
                                        <input type="hidden" name="Id" value="@userContact.Id" />
                                        <div class="m-form__group m-form__group--inline">
                                            <div class="m-form__label">
                                                <label>@L("ContactName"):</label>
                                            </div>
                                            <div class="m-form__control">
                                                <input id="ContactName" type="text" name="contactName" value="@userContact.ContactName" class="form-control m-input">
                                            </div>
                                        </div>
                                        <div class="d-md-none m--margin-bottom-10"></div>
                                    </div>
                                    <div class="col-md-4">
                                        <div class="m-form__group m-form__group--inline">
                                            <div class="m-form__label">
                                                <label class="m-label m-label--single">@L("ContactPhone"):</label>
                                            </div>
                                            <div class="m-form__control">
                                                <input id="ContactPhone" type="text" name="contactPhone" value="@userContact.ContactPhone" class="form-control m-input">
                                            </div>
                                        </div>
                                        <div class="d-md-none m--margin-bottom-10"></div>
                                    </div>
                                    <div class="col-md-4">
                                        <div data-repeater-delete="" class="btn-sm btn btn-danger m-btn m-btn--icon m-btn--pill">
                                            <span>
                                                <i class="la la-trash-o"></i>
                                                <span>@L("Delete")</span>
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            }
                        </div>
                    </div>
                    <div class="m-form__group form-group row">
                        <label class="col-lg-2 col-form-label"></label>
                        <div class="col-lg-4">
                            <div data-repeater-create="" class="btn btn btn-sm btn-brand m-btn m-btn--icon m-btn--pill m-btn--wide">
                                <span>
                                    <i class="la la-plus"></i>
                                    <span>Add</span>
                                </span>
                            </div>
                        </div>
                    </div>
                </div>
                ...

_CreateOrEditModal.js

            ...
            $("#UserContacts").repeater({
                initEmpty: false,
                show: function () {
                    $(this).slideDown()
                },
                hide: function (e) {
                    $(this).slideUp(e)
                }
            })
            ...
            
            this.save = function () {
            ...
            _userService.createOrUpdateUser({
                user: user,
                assignedRoleNames: assignedRoleNames,
                sendActivationEmail: user.SendActivationEmail,
                SetRandomPassword: user.SetRandomPassword,
                organizationUnits: _organizationTree.getSelectedOrganizations(),
                relatedUserContacts: JSON.stringify(user.UserContacts)
            }).done(function () {
                ...
            }).always(function () {
                ...
            });
        };

Firstly, I know the description a little bit long but I am confused and stuck. Thanks.


4 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    HI @evbenerji, can you share the error stacktrace for JSON serialization as well?

  • User Avatar
    0
    evbenerji created

    Mvc.ExceptionHandling.AbpExceptionFilter - Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Project.Resource.Dtos.UserContactDto]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
    To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List&lt;T&gt;) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
    Path 'relatedUserContacts.0', line 1, position 667. (relatedUserContacts.0)
    
  • User Avatar
    0
    ryancyq created
    Support Team

    Hi, what is the data type for user.UserContacts?

    It seems that JSON.stringify(user.UserContacts) is producing JSON object instead of JSON array

  • User Avatar
    0
    evbenerji created

    Hi @ryancyq This problem solved when I map the userContacts in _CreateOrEditModal.js like;

    this.save = function () {
                ...
                var user = $('#UserInformationsForm,#UserDetailsForm').serializeFormToObject();
                var userCont = $.map(user.UserContacts, function (el) { return el });
                ...
                _userService.createOrUpdateUser({
                    user: user,
                    ...
                    relatedUserContacts: userCont
                }).done(function () {
                    abp.notify.info(app.localize('SavedSuccessfully'));
                    _modalManager.close();
                    abp.event.trigger('app.createOrEditUserModalSaved');
                }).always(function () {
                    ...
                });
            };
    

    Thanks for your suggestions and thanks for your interest.