Aug 29, 2018

ASP.NET Core localization - Shared resources - simplest scenario RePost

I need one simple shared resource file for placing my label and error text in one place. There is no need for localization but resource file is best choice.

I've picked only bare minimum from this post:

https://damienbod.com/2017/11/01/shared-localization-in-asp-net-core-mvc/

Currently I'm working on ASP.NET Core 2.1

1. Create Resources folder in your Web project and inside create SharedResources.resx. Select from access modifier of resource file designer "Public".

2. Create override of localization factory as explained in above post:

public class CustomLocalizationService
    {
        private readonly IStringLocalizer _localizer;
        public CustomLocalizationService(IStringLocalizerFactory factory)
        {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(nameof(SharedResource), assemblyName.Name);
        }
        public LocalizedString Get(string key)
        {
            return _localizer[key];
        }
    }
3. Register your new service in Startup:

     public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<CustomLocalizationService>();
            services.AddLocalization(options => options.ResourcesPath = "Resources");

4. Fix MVC options to support view localization and support for Data annotations error messages:

services.AddMvc()
                .AddViewLocalization()
                .AddDataAnnotationsLocalization(options =>
                  {
                      options.DataAnnotationLocalizerProvider = (type, factory) =>
                      {
                          var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
                          return factory.Create(nameof(SharedResource), assemblyName.Name);
                      };
                  }); 
5. Finally when using in View you must use your new localization wrapper:

@inject CustomLocalizationService SharedLocalizer

Data annotations should look like this:

[StringLength(200, ErrorMessageResourceName = "ValidationErrorTooLongText", ErrorMessageResourceType =typeof(SharedResource))]

For some reason I couldn't use dot in my resource key naming so instead of:

Validation.Error.TooLongText

; I had to write:

ValidationErrorTooLongText

Jul 10, 2018

ASP.NET Core custom validation for required on file upload or radio - dirty way

In some cases like radio group or file upload buttons standard Required validation with JQuery don't work.
There is legit way of registering custom validation attributes for both serves side Model and for client side.
This is dirty way ...

Just create in doom so small that is not visible (NOT HIDDEN! ) input with same dom name.

   <span asp-validation-for="ImageRaw" style="padding-left:15px" class="text-danger"></span>
                        <input style="width:0px;border:0px!important;padding:0px;" type="text" asp-for="ImageRaw" />

If you hide it JQuery validation will ignore it. Through JQ apply changes to real input on the hidden one.

  $(document).on('change', 'input[name="PersonImage"]', function () {
            $('input#ImageRaw').val($(this).val());
        });




Jun 14, 2018

.NET C# Operations with flagged Enumerations

[Flags]
public enum Category
{
Undefined = 0,
AdultsOnly = 1,
Family = 2,
AllInclusive = 4,
City = 8
}
void Main()
{
Category c = Category.AdultsOnly | Category.City; Category[] categories = new Category[2] { Category.AllInclusive, Category.Family};
Category category = categories.Aggregate((i, t) => i | t);
var isThereAtLeastOneMatch = (c & category) != Category.Undefined;
var hasExact = (c & Category.AdultsOnly )== Category.AdultsOnly;
}

Jun 11, 2018

asp.net core 2.0 DataFormatString DisplayFor

Propert display formatting that worked in ASP.NET Core 2.0 :

                        <span class="room-price">@(Html.DisplayFor(m => rate.Price))&euro;</span>

[DisplayFormat(DataFormatString = "{0:#,###.00}", ApplyFormatInEditMode =false, NullDisplayText ="")]
public decimal Price { get; set; }       

Important!  Don't use DisplayTextFor!

Jun 7, 2018

asp.net mvc core 2.0 validating checkbox

Explains how to force required on checkbox.

    <input type="checkbox" id="TermsOfUseFake">
                        <label for="TermsOfUseFake"><a href='@navLinks.GetSitePageLink(languageGroupId: "TermsOfUse")' target="_blank">@Localizer["Loyalty.RegisterForm.TermsOfUse"]</a></label><br>
                        <input style="width:0px;border:0px!important;padding:0px;" type="text" asp-for="TermsOfUse" />
                        <span asp-validation-for="TermsOfUse" class="text-danger"></span>                        


 $(document).on('change', '#TermsOfUseFake', function () {
                debugger;               
                if ($('#TermsOfUseFake:checked')[0]) {
                    $('#TermsOfUse').val("true");
                }
                else {
                    $('#TermsOfUse').val("");
                }
                $("form#registerForm").validate().element("#TermsOfUse");
            });

ASP.NET MVC Core 2.0 - Resource Key is not compiled from RESX file

Open RESX and change Access Modifier to Public.

Make sure that project builds without error. You can be misled that RESX cant be built while you have compile error.