I need to modify the title and content of the Email Confirmation email template. Is there a way to apply my modifications to all tenants? Or can tenants inherit the title and content from the tenant with tenantId set to null (host)? so I don't need to update for each tenant one by one.
These modifications involve language texts and text templates.
thanks your answer, I checked the link you gave me and this one https://abp.io/docs/latest/suite/editing-templates
but could find the instruction on how to use these variables:
%%%%item-dto-properties%%%%item-dto-np-properties%%%%item-dto-nc-properties
this is Server.AppService.ItemCreateDto.txt and I am trying to update it to including my RegularExpression, i.e.:
[RegularExpression(@"^[^<>'""`]*$", ErrorMessage = "Invalid characters detected")]
public new string Address { get; set; }
using System; using System.ComponentModel.DataAnnotations; using System.Collections.Generic;
namespace %%solution-namespace%%%%<if:ApplicationContractsNotExists>%%%%.AppServices%%</if:ApplicationContractsNotExists>%%.%%entity-namespace%% { public %%custom-code-abstract-modifier%% class %%entity-name%%CreateDto%%custom-code-base%% { %%child-master-entity-primary-key%%%%item-dto-properties%%%%item-dto-np-properties%%%%item-dto-nc-properties%% } }
if you ran the project, you can see that it can't pass the validate: ValidateModel()
the error is(same as the login page):
An unhandled exception occurred while processing the request. AbpValidationException: ModelState is not valid! See ValidationErrors for details. Volo.Abp.AspNetCore.Mvc.Validation.ModelStateValidator.Validate(ModelStateDictionary modelState)
Stack Query Cookies Headers Routing AbpValidationException: ModelState is not valid! See ValidationErrors for details. Volo.Abp.AspNetCore.Mvc.Validation.ModelStateValidator.Validate(ModelStateDictionary modelState) Volo.Abp.AspNetCore.Mvc.UI.RazorPages.AbpPageModel.ValidateModel() Tapp.Web.Pages.Account.RegisterModel.RegisterLocalUserAsync() in Register.cshtml.cs + ValidateModel(); Tapp.Web.Pages.Account.RegisterModel.OnPostAsync() in Register.cshtml.cs + user = await RegisterLocalUserAsync(); Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Convert<T>(object taskAsObject) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Execute(object receiver, object[] arguments) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync() Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync() Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync() Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger) Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+InterfaceMiddlewareBinder+<>c__DisplayClass2_0+<<CreateMiddleware>b__0>d.MoveNext()
*can you show me where the code for the switch tenant pop up window is? I couldn't find it
This code comes from the layout of the theme. * I meant the modal, I found it for the mauiblazor , but couldn't find it for the MVC project: <Modal @ref="SwitchTenantModal" Closing="@SwitchTenantModal.CancelClosingModalWhenFocusLost"> <ModalContent Centered="true"> <Form> <ModalHeader> <ModalTitle>@L["SwitchTenant"]</ModalTitle> <CloseButton Clicked="CloseSwitchTenantModalAsync"/> </ModalHeader> <ModalBody> <Field> <FieldLabel>@L["Name"] *</FieldLabel> <TextEdit @bind-Text="TenantName" Autofocus="true"/> <div class="form-text">@L["SwitchTenantHint"]</div> </Field> </ModalBody> <ModalFooter> <Button Color="Color.Secondary" Clicked="CloseSwitchTenantModalAsync">@L["Cancel"]</Button> <SubmitButton Clicked="@SwitchTenantAsync"/> </ModalFooter> </Form> </ModalContent> </Modal>
Thanks! it worked, pls also check the register page in my project, it has same issue.
I can see we have the code in layout default.cshtml <div> <div class="row"> <div class="col"> <span style="font-size: .8em;" class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br /> <h6 class="m-0 d-inline-block"> @if (CurrentTenant.Id == null) { <span> @MultiTenancyStringLocalizer["NotSelected"] </span> } else { <strong> @(CurrentTenant.Name ?? CurrentTenant.Id.Value.ToString()) </strong> } </h6> </div> <div class="col-auto"> <a id="AbpTenantSwitchLink" href="javascript:;" class="btn btn-sm btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a> </div> </div> </div>
We wanted to prevent an adversary to execute unsanitized JavaScript in browser, *the suggestion online is User input should be validated as strictly as possible and have an appropriate permitted length based on the kind of content that it is expected to contain (i.e., personal names should consist of letters while excluding symbols and numbers; a year should be composed of 4 digits; e-mail addresses should be validated with a regular expression). 2. User input should be HTML-encoded whenever it is reflected in an application’s response. Special characters, including < > " ' and =, should be encoded with the corresponding HTML entities (lt gt etc). * I actually saw a post talking this issue here https://github.com/abpframework/abp/issues/7751
anyway, I am thinking to do: using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text.RegularExpressions; using Tapp.Enums;
namespace Tapp.DataHub.TappOrganizations { public class TappOrganizationCreateDto : TappOrganizationCreateDtoBase { public Guid? Id { get; set; } [Required] [RegularExpression(@"^[^<>'""`]*$", ErrorMessage = "Invalid characters detected")] public string Position { get; set; } = String.Empty; public Guid UserId { get; set; } [Required(ErrorMessage = "Please select at least one code.")] public List
[Required]
[RegularExpression(@"^[^<>'""`]*$", ErrorMessage = "Invalid characters detected")]
public new string Address { get; set; }
[Required]
[RegularExpression(@"^[0-9+\-\(\)\s]*$", ErrorMessage = "Invalid phone number format")]
public new string OfficePhone { get; set; }
public List<Guid>? TappThemeAttributeList { get; set; } = new List<Guid>();
}
}
and
<abp-modal-header title="@Html.Raw(HttpUtility.HtmlEncode(L["NewTappOrganization"].Value))"></abp-modal-header>
and private void SanitizeInput(TappOrganizationCreateViewModel model) { if (model == null) return;
// HTML encode all string properties
model.Position = HttpUtility.HtmlEncode(model.Position);
model.Address = HttpUtility.HtmlEncode(model.Address);
model.OfficePhone = HttpUtility.HtmlEncode(model.OfficePhone);
model.OrgName = HttpUtility.HtmlEncode(model.OrgName);
model.WebsiteUrl = HttpUtility.HtmlEncode(model.WebsiteUrl);
model.OrganizationNumber = HttpUtility.HtmlEncode(model.OrganizationNumber);
model.Country = HttpUtility.HtmlEncode(model.Country);
model.Region = HttpUtility.HtmlEncode(model.Region);
model.Community = HttpUtility.HtmlEncode(model.Community);
model.PostalCode = HttpUtility.HtmlEncode(model.PostalCode);
model.StreetAddress = HttpUtility.HtmlEncode(model.StreetAddress);
model.AddressNumber = HttpUtility.HtmlEncode(model.AddressNumber);
model.AddressFormatted = HttpUtility.HtmlEncode(model.AddressFormatted);
model.NaicsCodes = HttpUtility.HtmlEncode(model.NaicsCodes);
}
but I am wondering if abp provides a better solution? Or rather, a solution that I can:
thank you
I've just sent you an email with same subject. thank you so much
the action value is null and I got this error:
An unhandled exception occurred while processing the request. AbpValidationException: ModelState is not valid! See ValidationErrors for details. Volo.Abp.AspNetCore.Mvc.Validation.ModelStateValidator.Validate(ModelStateDictionary modelState)
Stack Query Cookies Headers Routing AbpValidationException: ModelState is not valid! See ValidationErrors for details. Volo.Abp.AspNetCore.Mvc.Validation.ModelStateValidator.Validate(ModelStateDictionary modelState) Volo.Abp.AspNetCore.Mvc.UI.RazorPages.AbpPageModel.ValidateModel() Tapp.Web.Pages.Account.TappLoginModel.OnPostAsync(string action) in Login.cshtml.cs + ValidateModel(); Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Convert<T>(object taskAsObject) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Execute(object receiver, object[] arguments) Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync() Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync() Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
That's what I did, and your code has errors. However, if I fix those errors, I still encounter the issue I reported in my original post. Please check my first post.
public TappLoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IAbpRecaptchaValidatorFactory recaptchaValidatorFactory,
IAccountExternalProviderAppService accountExternalProviderAppService,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IOptions<IdentityOptions> identityOptions,
IOptionsSnapshot<reCAPTCHAOptions> reCaptchaOptions) : base(
schemeProvider,
accountOptions,
recaptchaValidatorFactory,
accountExternalProviderAppService,
currentPrincipalAccessor,
identityOptions,
reCaptchaOptions)
{
}