Category Archives: .NET

all .net development, c# mainly

ASP.NET Core : Overriding controller AuthorizeAttribute for just one action

Standard

In Asp.Net Core, creating custom authorize attributes is over. You’d better deal with policies now. If you want to override the controller AuthorizeAttribute for just one action with a stronger policy, nothing simpler :

[Authorize]
public class AuthorizedController : Controller
{
    [HttpGet("do-authorized-stuff/{id}")]
    public IActionResult Whatever(int id)
    { }

    [Authorize(Consts.AdminOnly)]
    [HttpGet("do-admin-stuff/{id}")]
    public IActionResult WhateverAdminStuff(int id)
    {
    }

}

But what if you want to override it with a weaker policy ? For example you want to override the admin policy just for one action which would be available to any authenticated user like so :

[Authorize(Consts.AdminOnly)]
public class AuthorizedController : Controller
{

    [Authorize] //admin policy is still applied :o(
    [HttpGet("do-authorized-stuff/{id}")]
    public IActionResult Whatever(int id)
    { }

    [HttpGet("do-admin-stuff/{id}")] //admin policy is applied
    public IActionResult WhateverAdminStuff(int id)
    { }

This won’t work as policies are accumulated, in other words it’s an AND not an OR.
Still, Asp.Net Core has a lot of possibilities and you could simply do in Startup.cs file :

services.AddAuthorization(options =>
{
    var simplyAuthenticated = new AuthorizationPolicy(new DenyAnonymousAuthorizationRequirementOverrideOthers().Yield(), new List<string>());
    options.AddPolicy(name: PolicyConsts.AuthenticatedOnlyOverridePolicyName, policy: simplyAuthenticated);
    options.AddPolicy(name: PolicyConsts.Admin, configurePolicy: policy => policy.RequireAssertion(e =>
    {
        if (e.Resource is AuthorizationFilterContext afc)
        {
            var noPolicy = afc.Filters.OfType<AuthorizeFilter>().Any(p => p.Policy.Requirements.Count == 1 && p.Policy.Requirements.Single() is DenyAnonymousAuthorizationRequirementOverrideOthers);
            if (noPolicy)
                return true;
        }
        return e.User.IsInRole(Consts.Admin);
    }));

}

and here’s the custom DenyAnonymousAuthorizationRequirementOverrideOthers :


namespace Whatever
{
    using Microsoft.AspNetCore.Authorization.Infrastructure;

    public class DenyAnonymousAuthorizationRequirementOverrideOthers : DenyAnonymousAuthorizationRequirement
    { }
}

 

and here’s the controller :


[Authorize(PolicyConsts.AdminOnly)]
public class AuthorizedController : Controller
{

    [Authorize(PolicyConsts.AuthenticatedOnlyOverride)]
    [HttpGet("do-authorized-stuff/{id}")]//admin policy is bypassed thanks to our startup.cs code
    public IActionResult Whatever(int id)
    { }

    [HttpGet("do-admin-stuff/{id}")] //admin policy is applied coming from controller
    public IActionResult WhateverAdminStuff(int id)
    { }
}

And you can add any custom policy you want and make it override others in the RequireAssertion Func of other policies.

Hope it helps, see ya !

TagHelpers : using the post method with html anchor tags

Standard

Want to make an anchor which would issue a post call to the server rather than a get ?

post anchor tag

instead of writing the ugly :

<form asp-controller="Account" asp-action="Logout" method="post" id="logout-form"></form>

 <a href="javascript:document.getElementById('logout-form').submit()"></a>

Why not use a tag helper to generate this behind the scenes and keep your html clean ? Here’s mine, I made it simple, your anchor must have an id, a href and a asp-post attribute to work with it.

    [HtmlTargetElement("a", Attributes = ForAttributeName + ",id,href")]
    public class PostAnchorTagHelper : TagHelper
    {
        private const string ForAttributeName = "asp-post";
        private IHtmlGenerator _generator;

        public PostAnchorTagHelper(IHtmlGenerator generator)
        {
            _generator = generator;
        }

        [HtmlAttributeName(ForAttributeName)]
        public string For { get; set; }

        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }

        public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var href = context.AllAttributes["href"].Value.ToString();
            var id = context.AllAttributes["id"].Value.ToString();
            output.Attributes.RemoveAll("href");
            var form = new TagBuilder("form");
            form.Attributes.Add("action", href);
            form.Attributes.Add("method", "post");
            form.Attributes.Add("asp-antiforgery", "true");
            var idForm = id + "-form";
            form.Attributes.Add("id", idForm);
            var antiforgeryTag = _generator.GenerateAntiforgery(ViewContext);
            if (antiforgeryTag != null)
            {
                form.InnerHtml.AppendHtml(antiforgeryTag);
            }
            output.Attributes.Add("href", $"javascript:document.getElementById('{idForm}').submit()");
            output.PostElement.AppendHtml(form);
            return base.ProcessAsync(context, output);
        }
    }

Now, just write :

<a id="logout" href="@Url.Action("Logout", "Account")" asp-post="true"></a>

And you’re good to go !

Localizing validation messages in asp.net core : fallback on shared resources if not found

Standard

Right now in asp.net core, when you want to localize your validation messages, you have to create a resource file with the exact same name as your viewmodel, as explained here : https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization#dataannotations-localization

What if you want to keep this smart mechanism but still get a fallback to a shared resource file ? For example, let’s say you want to have the message “This field is absolutely required please !” instead of the standard message, for all required fields in all your viewmodels. You obviously don’t want to specify this message in every localized resource file named like your viewmodel.

Here’s a basic solution. In the startup.cs file, add something like :

services.AddMvc().AddDataAnnotationsLocalization(o =>
o.DataAnnotationLocalizerProvider = (modelType, stringLocalizerFactory) =>
{
   var sl = stringLocalizerFactory.Create(modelType);
   var shared = stringLocalizerFactory.Create(typeof(SharedResources));
   var ezSl = new MyDataAnnotations.ResourceManagerStringLocalizer(sl, shared);
   return ezSl;
})

And this is how your class MyDataAnnotations.ResourceManagerStringLocalizer could look like :

Read the rest of this entry

Beware of IEnumerable with Entity Framework

Standard

Sometimes you want to build a generic data access layer out of your entity framework concrete context, and you want to use the precious generic method on the DbContext such as the generic Set(). If it can spare you some time… Beware than when you do :

         public IEnumerable<T> Get<T>() where T : class
        {
            return _context.Set<T>();
        }

When the function returns, your query is already materialized, the query to the database has been made ! Because the Get function’s return type, IEnumerable, implies an implicit cast to get it from a DbSet. EF is probably making a ToList() inside to transform to IEnumerable, and thus, making the roundtrip to database and materializing objects.

To keep a lazy set, it’s better to switch to  :

       public IQueryable<T> Get<T>() where T : class
        {
            return _context.Set<T>();
        }

 

Charger des scripts dans une vue partielle

Standard

En ASP.NET MVC,  il arrive que l’on veuille écrire ou référencer des scripts depuis une vue partielle, afin de déléguer l’entière responsabilité de certains scripts et de leur fonctionnement à ce bout de vue uniquement. Par exemple, une vue partielle destinée à de la conversation instantanée, à du « chat », présentera tous les éléments UI nécessaires à l’envoi et à la réception de messages instantanés si la personne est authentifiée et s’occupera également de s’assurer que les bons scripts, tels que SignalR par exemple, ont été chargés et exécutés en vue du bon fonctionnement du chat.

Ces scripts nécessitent souvent que d’autres scripts aient été chargés au préalable, comme JQuery par exemple. Malheureusement, une vue partielle se situe souvent en milieu de document et les scripts de base, eux, souvent juste avant la balise de fermeture du body, afin de ne pas bloquer le rendu de la page et de conserver de bonnes performances. Sachant qu’ils se chargent et s’exécutent dans l’ordre de leur référencement, les scripts situés dans la vue partielle ne fonctionneront pas car les dépendances n’auront pas encore été chargées.

Ce problème se résout facilement dans une vue basique car il est possible de redéfinir une section en ASP.NET MVC : le développeur peut redéfinir la section « Scripts » qui se situerait après les scripts de base de fin de body. Mais dans une vue partielle, il est impossible de redéfinir une section. Ainsi, un script présent dans une vue partielle nécessitant JQuery risque de planter en disant que $ est « undefined ».

Read the rest of this entry

Gestion des erreurs en ASP.NET MVC

Standard

Article publié dans le magazine Programmez ! – Avril 2014 – N° 173

Lors de la conception d’une application web, gérer le comportement du système en cas d’erreur est important et ne devrait pas être laissé au hasard. D’une part, visualiser une page système peu accueillante, non stylisée, et loin des couleurs du site n’est pas toujours agréable pour l’utilisateur qui vient en plus de recevoir une erreur. D’autre part, si certains paramétrages ne sont pas effectués, l’utilisateur pourrait avoir accès aux détails techniques de l’exception. Un visiteur mal intentionné pourrait se servir de ces détails pour accumuler des connaissances sur la structure technique du site et trouver plus facilement une faille de sécurité à exploiter. Ainsi, il appartient à l’équipe de réalisation du site de déterminer en amont le niveau de détails d’erreur à délivrer à l’utilisateur, les codes d’erreur HTTP à renvoyer en fonction des situations et les pages d’erreur qui seront affichées. En somme, il s’agit de décider d’un comportement applicatif en cas d’erreur qui soit uniformément suivi au cours des développements.

ASP.NET MVC offre de nombreuses solutions pour gérer une exception de manière centralisée et rediriger vers une ressource en particulier. Gérer les erreurs peut donc se faire de plusieurs façons et peut s’adapter à divers scénarios. Ces différentes manières seront exposées au cours de cet article, du niveau le plus global à celui le plus fin.

Read the rest of this entry

Parsing an xml to get a c# object with dynamic type

Standard

Okay, okay you’re right, thank you Leo 😉 So let’s render unto Caesar the things which are Caesar’s… Microsoft took into account the power of those weakly-typed languages such as JavaScript, the ones which allow you to deal with types you don’t know yet. Within .NET 4, they release the dynamic type, in reference to those languages, which they specifically call dynamic languages.

So now, if you derive from DynamicObject to create your own one, you can use pretty much the same code I used previously in JavaScript to get a c# object from Xml. You can create any property you’d like at runtime, only by accessing it like an array. Just write myDynamic[“house”]=whatever and it gets created in the meantime. In the end, you’ll be able to access any property you created in a totally transparent manner like myDynamic.house….

Plus, with the

TryConvert(ConvertBinder binder, out object result)

you can get the statically typed object you were expecting if you ever need a strongly typed object.

Enough of this talking, here you can find some more explanations about dynamic and how to take advantage of it :
http://msdn.microsoft.com/en-us/library/dd233052.aspx
http://msdn.microsoft.com/en-us/library/dd264736.aspx
http://msdn.microsoft.com/en-us/library/dd264741.aspx

and here’s the code:
https://docs.google.com/open?id=0BwW7tKeWhpnKcFZUakpJVENvOWs

WPF TabControl + Mvvm datatemplate binding = Attached properties are lost

Standard

At the moment, I’m trying to create some kind of chat with WPF following mvvm pattern so that I can learn and have fun at the same time. Must admit I’m a total beginner in WPF and decided to learn from Josh Smith’s very interesting and teaching article http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030 and get inspired  by his workspaces model. Just like his demo, I needed tabs displaying the same view but with different datacontexts of course since one tab would be dedicated to one conversation (we don’t want to intermingle recipients !). I really admired the elegant and simple way of applying a view to a viewmodel, no code behind, everything centralized in a uncoupled resources dictionary :

<DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
    <vw:AllCustomersView />
  </DataTemplate>

Moving forward in building my project based on these patterns, creating my “conversation” view, attached properties came into play. I needed a particular behavior on one UI element to be triggered by another control’s itemssource’s event (on new item for instance). Searching the web, I heard about attached properties. But imagine my surprise when I saw my attached property only working for the first tab…

Read the rest of this entry

Calling a server method (asp.net) from the browser

Standard

Sometimes,  you use JQuery within your Asp.Net projects to provide richer and more interactive web experience. The user now can drag and drop, admire your smooth animations, interact in many ways with the page and experience a whole bunch of other funny things. On top of that, you could appreciate how integrating JQuery with ASP.NET projects is pretty straightforward.

Moreover, to get your page to work properly, you sometimes have to  focus on client-sided effects only and to forget about… postbacks ! Your HTML elements then won’t be bound to the server and won’t trigger any postbacks nor be referenced in any aspx class. They will have nothing to do with the viewstate and they won’t notify any data change.  As a consequence, if the user changes the webpage content, some properties or the order of a few elements  through JQuery manipulations, the server won’t be able to retrieve by itself those changes. Let’s stick with our previous example : the dynamic forms (dynamic webforms with JQuery). The user wants to create his own forms. It was all implemented through Javascript and JQuery, adding, dragging, dropping.

>> Could we now save it all to our database thanks to a little Asp.Net method ? which means formatting the data, sending it to the server which will eventually treat it. So how to send back data to  the server ?
>>How to call a server method without the postback mechanism but just with pure raw HTML controls never bound to the server ?
Of course, a simple Ajax call will do the trick !
We’ll see how  to :

  1. build this simple Ajax call to the asp.net server
  2. how to format basic data with JSON
  3. how to format more complex data like serializing and deserializing Javascript-.NET object, even with inheritance. Read the rest of this entry

Downloading a file within an asp updatepanel

Standard

In this article, we’ll see how to make full page postback controls work in an update panel.
We will then raise the problem of a button field in a gridview cell in an update panel that requires full page postback registration and suggest a workaround.

How basically the update panel works ?

The asp update panel is a native control which performs an asynchronous postback to render selected parts of the webpage. If you already know ajax mechanisms, update panel shouldn’t be mysterious for you. It deals indeed with Ajax and partial-page update to allow richer and more ergonomic web application.

Thus, unlike with a full page postback, a partial page postback sends a request back to the server through client-side script. Only the html markup inside the update panel is updated through Javascript again which deals with the server response to inject the new html content inside the update panel. The update panel waits for the server to return a special snippet of html code in a certain format. While the async request is sent out, update panels wait for this specifically formatted response.

Why my upload or download file function won’t work within an update panel ?

All of the controls placed inside the update panel are converted into partial postback controls. That’s pretty coherent because we want the page to be fast and user-friendly so the nested controls won’t raise a full reload of the page.  But those controls will go on working as long as they don’t need full postback.

But some controls might require full page postback to work, in other words they demand a classic and complete HTTP response to write into, to flush and to end. They won’t stand an async postback with a partial http markup response to inject in the page through JavaScript. What do you need to do then ?

Read the rest of this entry