Hi, guys I hope you are well on this Friday :)
I am facing a strange error with a simple update from application service that is called from js.
Let me share some screens and code so that you can review it and maybe you can help me get past through it
this is the js from modal
var _candidateService = abp.services.app.candidate;
var _modalManager;
var _$candidateLanguageForm = null;
_$candidateContactInformationForm = _modalManager.getModal().find('form[name=CandidateContactInformation]');
var candidateLanguage = _$candidateLanguageForm.serializeFormToObject();
console.log(candidateLanguage);
_modalManager.setBusy(true);
_candidateService.updateCandidateLanguage({
candidateLanguage
}).done(function () {
abp.notify.info(app.localize('SavedSuccessfully'));
//_modalManager.close();
//abp.event.trigger('app.createOrEditCandidatesModalSaved');
}).always(function () {
_modalManager.setBusy(false);
});
This is the app service method input
[AbpAuthorize(AppPermissions.Pages_Administration_Candidates_Edit)]
public async Task UpdateCandidateLanguage(UpdateCandidateLanguageInput input)
{
//Debug.Assert(input.CandidateId == null, "input.Candidate.Id should be set.");
var candidate = await _candidateRepository.GetAsync(input.Id);
if (candidate == null)
{
throw new UserFriendlyException("Candidate does not exist!");
}
candidate.CorrespondanceLanguage = input.CorrespondanceLanguage;
candidate.NativeLanguage = input.NativeLanguage;
await _candidateRepository.UpdateAsync(candidate);
}
dto
public class UpdateCandidateLanguageInput
{
public long Id { get; set; }
public string NativeLanguage { get; set; }
public CandiadteCorrespondanceLanguage? CorrespondanceLanguage { get; set; }
}
viewmodel
public class CandidateLanguageViewModel : UpdateCandidateLanguageInput
{
public IReadOnlyList<ComboboxItemDto> SpokenLanguages { get; set; }
public CandidateLanguageViewModel(long candidateId, CandiadteCorrespondanceLanguage? language, string nativelanguage, IReadOnlyList<ComboboxItemDto> spokenLanguages)
{
Id = candidateId;
CorrespondanceLanguage = language;
NativeLanguage = nativelanguage;
// output.MapTo(this);
SpokenLanguages = spokenLanguages;
}
}
filling of the viewmodel on controller
[AbpMvcAuthorize(AppPermissions.Pages_Administration_Candidates_Create, AppPermissions.Pages_Administration_Candidates_Edit)]
public async Task<PartialViewResult> CreateOrEditModal(int? id)
{
var output = await _candidateAppService.GetCandidateForEdit(new NullableIdDto<long> { Id = id });
var viewModel = new CreateOrEditCandidateModalViewModel(output);
//get two list item types with one db call
var nationalitiesAndSpokenLanguages = _listAppService.GetListItemsByType
(new GetListItemInput()
{
ListType = new[] { RecruitingConsts.ListTypes.Country, RecruitingConsts.ListTypes.SpokenLanguage }
});
viewModel.ManagersAndTeamLeaders =
await
_candidateAppService.FindUsersInRole(new FindUsersInput()
{ Roles = new[] { StaticRoleNames.Tenants.Manager, StaticRoleNames.Tenants.TeamLeader } });
//split two list items in memory
viewModel.Nationalities = nationalitiesAndSpokenLanguages.Items.Where(dto => dto.ListType == RecruitingConsts.ListTypes.Country)
.Take(10).OrderBy(o=> o.Text)
.Select(e => new ComboboxItemDto(e.Id.ToString(), e.Text)).ToList();
var spokenLanguages = nationalitiesAndSpokenLanguages.Items.Where(dto => dto.ListType == RecruitingConsts.ListTypes.SpokenLanguage)
.Take(10).OrderBy(o => o.Text)
.Select(e => new ComboboxItemDto(e.Id.ToString(), e.Text)).ToList();
if (id.HasValue)
{
var candidateLanguage = new UpdateCandidateLanguageInput();
candidateLanguage.Id = viewModel.Candidate.Id.Value;
candidateLanguage.NativeLanguage = viewModel.Candidate.NativeLanguage;
candidateLanguage.CorrespondanceLanguage = viewModel.Candidate.CorrespondanceLanguage;
// viewModel.Candidate.MapTo<UpdateCandidateLanguageInput>();
viewModel.AddressViewModel = new CandidatesAddressViewModel(viewModel.CandidateAddress, viewModel.Nationalities);
viewModel.ContactInformationViewModel = new CandidateContactInformationViewModel(viewModel.CandidateContactInformation);
viewModel.LanguagesViewModel = new CandidateLanguageViewModel(viewModel.Candidate.Id.Value, viewModel.Candidate.CorrespondanceLanguage,
viewModel.Candidate.NativeLanguage, spokenLanguages);
}
return PartialView("_CreateOrEditModal", viewModel);
}
form
@using Abp.Application.Services.Dto
@using Abp.Extensions
@using Marseco.Recruiting.Web.Helpers
@model Marseco.Recruiting.Web.Areas.Mpa.Models.Candidates.CandidateLanguageViewModel
<div class="row">
<form name="CandidateLanguageForm" role="form" novalidate class="form-validation">
<input type="hidden" name="Id" value="@Model.Id"/>
<div class="row">
<div class="col-md-12">
<div class="form-group form-md-line-input">
<label for="NativeLanguage" class="col-md-4 control-label">@L("NativeLanguageLabel")</label>
<div class="col-md-5">
<div class="dropdown-menu open" role="combobox" style="max-height: 316px; overflow: hidden;">
<div class="bs-searchbox">
<input type="text" class="form-control" autocomplete="off" role="textbox" aria-label="Search">
</div>
</div>
@Html.DropDownList("NativeLanguage", new SelectList(Model.SpokenLanguages.Select(i => i.ToSelectListItem()),
"Text", "Text", Model.NativeLanguage),
new
{
@class = "edited form-control bs-select",
data_live_search = "true",
data_size = "5",
required = "required",
id = "RegionId"
})
</div>
</div>
<div class="form-group form-md-line-input">
<label for="CorrespondanceLanguage" class="col-md-4 control-label">@L("CorrespodenceLanguageLabel")</label>
<div class="col-md-5">
@Html.LocalizedEnumDropDownListFor(m => m.CorrespondanceLanguage, L("CorrespodenceLanguageLabel"),
new {@class = "form-control edited"})
<label>@L("CorrespodenceLanguageLabel"):</label>
<div class="form-control-focus"> </div>
</div>
</div>
</div>
</div>
</form>
</div>
I dont know what I am missing I am making sure that the form has the values but on modal when I click save the UpdateCandidateInput allways is comming null on properties... I hope you see something that I am not :(
Hi, guys once again thanks for these great frameworks ABP and Apbzero to my knowledge are the best frameworks for building DDD with .net at the time.
However, when dealing with junior developers most of the times its hard to explain everything and the best approach that I find are to make them learn by doing, or my copy pasting the code and making it fit for the task in hand.
So I am kindly requesting that you take some time and make something better than <a class="postlink" href="https://www.aspnetzero.com/Documents/Developing-Step-By-Step-MPA">https://www.aspnetzero.com/Documents/De ... y-Step-MPA</a>
My opinion is that we take a Blog as an example and try to cover: Blog with Posts Post with many Tags Tag with many posts Comments (this way we cover one to many and many to many maybe one to one relationships)
with entity change event or domain events - post edited notify via email moderators background job if post date is > than 1-month archive post some notifications like subscribe to new posts of the blog etc.
I hope I am not asking too much but I rather find this to be more appropriate and will have great business value to your products.
At least please update the PhoneBook sample to cover entity change events and Domain events and maybe notification subscriptions.
Thank you in advance! Best Regards
is there anything new on this topic, official documentation...
Hello guys, I need your opinion/code example on something.
I read that application services should not call each other and I agree with it.
I have a scenario where I have to create a user using UserManger get the id and use that Id to create another entity.
CheckErrors(await UserManager.CreateAsync(user));
await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.
candidate.UserId = user.Id;
await _candidateRepository.InsertAsync(candidate);
What do you think of such case? Is there a better way to deal with this scenario maybe do this in the same UoW or using a domain service.
For the moment I managed it like you said on [http://forum.aspnetboilerplate.com/viewtopic.php?f=2&t=116&p=239&hilit=resource#p239])
Is there a way to do something like this for DTOs / ViewModels
[Required(ErrorMessage = L("Password", Constants.LocalizationSourceName)] public string Password { get; set; }
Or any other way to localize the data annotations so we dont need to end by localizing the html on the views.