Hello,
I need some help about the implementation of multi-lingual entities and the RAD tool.
As example, I have three entities :
concerning the query generated by the RAD tool how to adapt these queries in order to be sure that the Translations collection property is loaded, like :
var filteredEitPeople = _eitPersonRepository.GetAll()
.WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false || e.KeyName.Contains(input.Filter) || e.FirstName.Contains(input.Filter) || e.LastName.Contains(input.Filter) || e.Email.Contains(input.Filter) || e.Phone.Contains(input.Filter) || e.MobilePhone.Contains(input.Filter))
.WhereIf(!string.IsNullOrWhiteSpace(input.KeyNameFilter), e => e.KeyName.ToLower() == input.KeyNameFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.FirstNameFilter), e => e.FirstName.ToLower() == input.FirstNameFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.LastNameFilter), e => e.LastName.ToLower() == input.LastNameFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.EmailFilter), e => e.Email.ToLower() == input.EmailFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.PhoneFilter), e => e.Phone.ToLower() == input.PhoneFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.MobilePhoneFilter), e => e.MobilePhone.ToLower() == input.MobilePhoneFilter.ToLower().Trim());
var query = (from o in filteredEitPeople
join o1 in _eitPersonGenderTypeRepository.GetAll() on o.EitPersonGenderTypeId equals o1.Id into j1
from s1 in j1.DefaultIfEmpty()
join o2 in _eitPersonTitleTypeRepository.GetAll() on o.EitPersonTitleTypeId equals o2.Id into j2
from s2 in j2.DefaultIfEmpty()
select new GetEitPersonForView() { EitPerson = ObjectMapper.Map<EitPersonDto>(o)
, EitPersonGenderTypeName = s1 == null ? "" : s1.KeyName // TODO AJA : s1.DisplayName.ToString()
, EitPersonTitleTypeName = s2 == null ? "" : s2.Name.ToString()
})
.WhereIf(!string.IsNullOrWhiteSpace(input.EitPersonGenderTypeNameFilter), e => e.EitPersonGenderTypeName.ToLower() == input.EitPersonGenderTypeNameFilter.ToLower().Trim())
.WhereIf(!string.IsNullOrWhiteSpace(input.EitPersonTitleTypeNameFilter), e => e.EitPersonTitleTypeName.ToLower() == input.EitPersonTitleTypeNameFilter.ToLower().Trim());
var totalCount = await query.CountAsync();
var eitPeople = await query
.OrderBy(input.Sorting ?? "eitPerson.id asc")
.PageBy(input)
.ToListAsync();
return new PagedResultDto<GetEitPersonForView>(
totalCount,
eitPeople
);
In the "join", I tried
join o2 in _eitPersonTitleTypeRepository.GetAllIncluding(p => p.Translations) on o.EitPersonTitleTypeId equals o2.Id into j2
but, this is not working.
Another question, how to implement the filtering with the Translation values ?
Thanks for your help
Best regards,
Albert
Hello @Rodriguo,
Thanks for your help.
It was indeed a case sensitivity problem.
The name of the object in JSon returned by the app service was "eitLocationType",
while in the generated index.js, the name of this object was "eITLocationType" when used as a parameter for the _ createOrEditModal.Open method,
and was "EITLocationType" when assigning DataTable data properties.
I assume that this problem is due to the use of more than one uppercase letter at the beginning of the entity name.
Best regards,
Albert
Hi @ismcagdas
The use case is to support multi-lingual entity properties. The solution is :
Best regards Albert
Hello,
In aspnet zero, what is the best way to discover which is the current language inside of an entity accessor ?
Thanks,
Albert
Hello ismcagdas,
Thanks for your replies. We do like you explain in other .NET project not using AspNet Zero.
We make also some modifications in the DB Context to support the localization by adapting some treatments.
Best regards,
Albert
Hello,
In the context of Asp.Net Zero, what is the best solution to localize application content, from the DB to the entity properties ?
Thanks for any advices
Hello,
After making the change, it works.
Can you explain the difference between attributes,
AutoMap AutoMapFrom AutoMapTo
Because in the documentation, the following is used :
[AutoMapFrom(typeof(Person))] public class PersonListDto : FullAuditedEntityDto { public string Name { get; set; } public string Surname { get; set; } public string EmailAddress { get; set; } }
This is for List DTO
and for Input DTO (it's here that I made the mistake)
[AutoMapTo(typeof(Person))] public class CreatePersonInput { [Required] [MaxLength(Person.MaxNameLength)] public string Name { get; set; } [Required] [MaxLength(Person.MaxSurnameLength)] public string Surname { get; set; } [EmailAddress] [MaxLength(Person.MaxEmailAddressLength)] public string EmailAddress { get; set; } }
Thanks,
Best regards,
Albert
Hello alirizaadiyahsi,
I'm using Chrome, I cleared the cache, same result.
I tried with another browser Firefox, never used with this application and I get the same result.
I don't understand why the generated abp wep api controller is specifying HTTP Get verb and not POST.
Best regarsd,
Albert
Hello,
I get an error on save for the creation of an entity.
The error is :
{"message":"An error has occurred.","exceptionMessage":"There is an action CreateSubject defined for api controller app/subject but with a different HTTP Verb. Request verb is GET. It should be Post","exceptionType":"System.Web.HttpException","stackTrace":" at Abp.WebApi.Controllers.Dynamic.Selectors.AbpApiControllerActionSelector.GetActionDescriptorByActionName(HttpControllerContext controllerContext, DynamicApiControllerInfo controllerInfo, String actionName)\r\n at Abp.WebApi.Controllers.Dynamic.Selectors.AbpApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at Castle.Proxies.DynamicApiController`1Proxy_4.ExecuteAsync_callback(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at Castle.Proxies.Invocations.ApiController_ExecuteAsync_4.InvokeMethodOnTarget()\r\n at Castle.DynamicProxy.AbstractInvocation.Proceed()\r\n at Abp.WebApi.Controllers.Dynamic.Interceptors.AbpDynamicApiControllerInterceptor`1.Intercept(IInvocation invocation)\r\n at Castle.DynamicProxy.AbstractInvocation.Proceed()\r\n at Castle.Proxies.DynamicApiController`1Proxy_4.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}
The ISubjectAppService is :
public interface ISubjectAppService : IApplicationService
{
ListResultDto<SubjectsListDto> GetSubjects(GetSubjectsInput input);
Task CreateSubject(CreateSubjectInput input);
}
The implementation is :
public class SubjectAppService : EspertisAppServiceBase, ISubjectAppService
{
private readonly IRepository<Subject> _subjectRepository;
public SubjectAppService(IRepository<Subject> subjectRepository)
{
_subjectRepository = subjectRepository;
}
public ListResultDto<SubjectsListDto> GetSubjects(GetSubjectsInput input)
{
var subjects = _subjectRepository
.GetAll()
.WhereIf(
!input.Filter.IsNullOrWhiteSpace(),
p => p.Name.Contains(input.Filter) ||
p.Surname.Contains(input.Filter) ||
p.EmailAddress.Contains(input.Filter)
)
.OrderBy(p => p.Name)
.ThenBy(p => p.Surname)
.ToList();
return new ListResultDto<SubjectsListDto>(subjects.MapTo<List<SubjectsListDto>>());
}
public async Task CreateSubject(CreateSubjectInput input)
{
Subject subject = input.MapTo<Subject>();
await _subjectRepository.InsertAsync(subject);
}
}
The js code to save the modal is :
(function($) {
app.modals.CreateSubjectModal = function () {
var _modalManager;
var _subjectService = abp.services.app.subject;
var _$form = null;
this.init = function (modalManager) {
_modalManager = modalManager;
_$form = _modalManager.getModal().find('form');
_$form.validate();
};
this.save = function () {
if (!_$form.valid()) {
return;
}
var subject = _$form.serializeFormToObject();
_modalManager.setBusy(true);
_subjectService.createSubject(subject).done(function () {
_modalManager.close();
location.reload();
}).always(function () {
_modalManager.setBusy(false);
});
};
};
})(jQuery);
Thanks for your help,
Best regards,
Albert