Posted on

Token based authentication in ASP.NET Web API

Token based authentication

Nella “Token based authentication”, l’applicazione client invia prima una richiesta all’endpoint del server di autenticazione con le credenziali dell’utente; se il nome utente e la password sono corretti, il server di autenticazione invia un token al client come risposta. Questo token contiene dati sufficienti per identificare un determinato utente e un tempo di scadenza. L’applicazione client utilizza quindi il token per accedere alle risorse nelle richieste successive fino a quando il token risulta ancora valido (non scaduto).

Classe per validare le richieste del client

Aggiungete una classe come questa :

using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity.Owin;


namespace Mysite.Helpers
{
    public class MysiteAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated(); // 
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
            var user = await userManager.FindAsync(context.UserName, context.Password);
            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
            OAuthDefaults.AuthenticationType);

            context.Validated(oAuthIdentity);
        }
    }
}

Per attivare questa classe andate nel file App_Start/Startup.Auth.cs e aggiungete alla fine del metodo ConfigureAuth questo codice

var myProvider = new  MysiteAuthorizationServerProvider();
            OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = myProvider
            };
            app.UseOAuthAuthorizationServer(options);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

In cui si definisce il link http://mysite/token che restituisce un token di durata 1 giorno.

Dovrete aggiungere nel file il riferimento

using Microsoft.Owin.Security.OAuth;

E’ necessario aggiungere un metodo all’autenticazione. Andate nel file IdentityModel.cs e aggiungete questo metodo :

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager,
            string authenticationType)
        {
           var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
           return userIdentity;
        }

TEST CON POSTMAN

Per testare il tutto facilmente potete usare Postman .

Dovrete creare con Postman una chiamata post sul vostro link http://mysite/token. Nell’headers inserite la dicitura che vedete in figura :

Nel Body inserite il tipo di autneticazione (password) il vostro username e la vostra password.

Spingete “Send”. Se tutto ha funzionato riceverete il token

Utilizzo del Token

Una volta che il client ha ricevuto il token lo può utilizzare per tutte le successive operazioni senza dover passare lo username e la password: va passato solo il token che contiene queste informazioni. Facciamo una prova, creando un metodo che richiede autenticazione all’interno di un controller :

using System;
using System.Web.Http;

namespace MySite.Controllers
{
    public class SampleController : ApiController
    {
       [Authorize]
        [HttpGet]
        public IHttpActionResult GetForAuthenticate()
        {
            var identity = (ClaimsIdentity)User.Identity;
            return Ok("Hello " + identity.Name);
        }
   }
}

Usando postman, fate una chiamata GET al link : http://MySite/api/Sample/GetForAuhenticate

Dovrete passare al link il token che avete ottenuto qualche istante prima (nel nostro esempio è valido per 1 giorno). Per farlo in postman aggiungete la chiave Authorization con valore la parola Bearer seguita dal token.

THE END

Posted on

add Web API to an asp.net mvc site

Install the Web API Client Libraries

Use NuGet Package Manager to install the Web API Client Libraries package :

  • Microsoft.AspNet.WebApi.Client
  • Microsoft.AspNet.WebApi.Core
  • Microsoft.AspNet.WebApi.WebHost

Define a Web API Routing Configuration

Add App_Start\WebApiConfig.cs

using System.Web.Http;

class WebApiConfig
{
    public static void Register(HttpConfiguration configuration)
    {
        config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    }
}

Register the WebAPI Routing Configuration

If you added a new WebApiConfig.cs file, you need to register that on your Web Application’s main configuration class.

Import namespace System.Web.Http in Global.asax.cs.

Add this line before the registration of your classic routing

//api routing (before)
GlobalConfiguration.Configure(WebApiConfig.Register);
//existing normal route
RouteConfig.RegisterRoutes(RouteTable.Routes);

Create a sample Web API Controller

Create a new controller

using System;
using System.Web.Http;

namespace MySite.Controllers
{
    public class SampleController : ApiController
    {
       [HttpGet]
       public String Test()
       {
         return "Hello World!";
       }
   }
}

Based on the api routing you should call this method in your browser using

http://MySite/api/Sample/Test

with this result

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>Hello World!</string>

Posted on

Android java app with notification from asp.net mvc using firebase cloud messaging – part 3

Notification service in Android

Now we need to create in Android the service able to manage the notification incoming from firebase and to show these to user. Follow this usefull article Working easily with FCM push notifications in Android. You’ll have a class like this.

package com.mycompany.myfirstapp;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import androidx.core.app.NotificationManagerCompat;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

//is the class that we can find in the manifest as a service

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    public static final String TAG = "MsgFirebaseServ";

    @Override


    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        String title = "";
        String body = "";
        String objectId = "";
        String objectType = "";

        if (remoteMessage.getData() != null) {
            title = remoteMessage.getData().get("title");
            body = remoteMessage.getData().get("body");
            objectId = remoteMessage.getData().get("object_id");
            objectType = remoteMessage.getData().get("objectType");
        }

        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle(title)
                .setContentText(body)
                .build();
        NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
        manager.notify(/*notification id*/0, notification);
    }
}

Run your app on your device

Follow this instruction : https://developer.android.com/training/basics/firstapp/running-app

First test using your app in your device

  • Run the app on your device or emulator. The app should had created a new register id for the device and send it to asp.net mvc site. Now the device is registered.
  • Open Firebase console, go down in the menu on the left. Open Cloud Messaging session : you should find the possibility to send notification to your device starting from this page. So you can test correct developing of above class.

Send notification from asp.net mvc to firebase

For backend developers. You should create a class to manage notification to firebase. Follow the article Firebase push notifications using a .NET Backend to prepare a class to manage the notification to Firebase.

Then prepare your notification test task in a controller. Something like this :

        public Task<bool> NoteAsync()
        {
            var device = db.RegisteredDevices.Where(d => d.ENABLED == true);
            string[] da = new string[device.Count()];
            int i = 0;
            foreach (RegDevice r in device)
            {
                da[i] = r.ID;
                i++;     
            }
            string serverkey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
            return FCMPushNotification.SendPushNotification(da,serverkey,"Title","body");
        }

Firebase messaging, where to get Server Key?

Click the Settings (Cog wheel) icon next to your project name at the top of the new Firebase Console, as per screenshot below:

  1. Click Project settings.
  2. Click on the Cloud Messaging tab.


Final test

Call the asp.net mvc method created. You should see a notification in your device.


Android java app with notification from asp.net mvc using firebase cloud messaging – part 1

Android java app with notification from asp.net mvc using firebase cloud messaging – part 2

Links



Posted on

Android java app with notification from asp.net mvc using firebase cloud messaging – part 2

In this scenario we looking to send the device registration id to a server with user data to save it in our database.

Token based authentication in ASP.NET Web API

For backend developers. ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients. Follow the following article in order to implement Token based authentication using ASP.NET Web API 2. (Part 1 : Token based authentication in ASP.NET Web API)

To register the device you need a method like this

       [HttpPost]
       public HttpResponseMessage Register(string key)
        {
            
            var identity = (ClaimsIdentity)User.Identity;
            string message = "";
            if (!string.IsNullOrEmpty(key))
            {
                var userid = identity.GetUserId();
                RegDevice device = db.RegisteredDevices.Where(d => d.ID == key &&
                        d.USER == userid).FirstOrDefault();
                        if (device == null)
                        {
                            device = new RegDevice();
                            device.ID = key;
                            device.USER = userid;
                            db.RegisteredDevices.Add(device);
                            if (db.SaveChanges() > 0)
                                {
                                    return Request.CreateResponse(HttpStatusCode.OK);
                                }
                                else
                                {
                                    message = Vocabolario.ErrorInTemporaryStorage;
                                    //System.Diagnostics.Debug.WriteLine("PostServerLog. erore" + 
                                    message);
                                }
                        }  
            }
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest, "value");
            response.Content = new StringContent(message, Encoding.Unicode);
            return response;
        }

Bearer authentication on Java

For frontend developers. To authenticated in a asp.net mvc site, first of all you have to generate the token using the username and the password. The token will conserve all the user’s data more the validation time. We will use this token to talk to our server.

Getting a token is not a goal per se. It’s a necessary step to call a protected API. The token needs to be used to access a Web API. The way to do it is by setting the Authorization header to be “Bearer”, followed by a space, followed by the access token.

To generate the token you should use something like this :

package com.mycompany.myfirstapp;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;

import javax.net.ssl.HttpsURLConnection;

import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import java.io.InputStream;
import org.apache.wink.json4j.JSONArray;
import org.apache.wink.json4j.JSONObject;
import org.apache.wink.json4j.JSONException;

import java.nio.charset.StandardCharsets;

import java.security.cert.Certificate;
import javax.net.ssl.SSLPeerUnverifiedException;

public class MyServer {

    private final static String BASE_URL = "https://www.mysite.com";
    private final static String TOKEN_ENDPOINT = BASE_URL + "/token";
    private final static String REGDEVICE_ENDPOINT = BASE_URL + "/api/Account/Register";

//pass username and password in this example
    public static String getToken(String user, String pwd) throws IOException, JSONException {
        byte[] postData = getRequestBodyForAccessToken(user,pwd);
        int postDataLength = postData.length;

        URL url = new URL(TOKEN_ENDPOINT);
        HttpsURLConnection requestConn = (HttpsURLConnection) url.openConnection();
        requestConn.setRequestMethod("POST");
        requestConn.setDoOutput(true);
        requestConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        try (DataOutputStream dos = new DataOutputStream(requestConn.getOutputStream())) {
            dos.write(postData);
        }

        if (requestConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            if (requestConn.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM) {
                String serverURL = requestConn.getHeaderField("Location");
                System.err.println("Set the value of the server path to: " + serverURL);
            }
            System.err.println("Error in obtaining an access token. " + 
            requestConn.getResponseMessage());
        }

        String accessToken;
        try (InputStream tokenStream = requestConn.getInputStream()) {
            JSONObject tokenRes = new JSONObject(tokenStream);
            accessToken = (String) tokenRes.get("access_token");
        }
        return accessToken;
    }

    public static void RegisterNewDevice(String deviceKey, String atoken)
    {
        StringBuilder urlBuilder = new StringBuilder(REGDEVICE_ENDPOINT);
        urlBuilder.append("&key=").append(deviceKey);
        String pathWithQueryParams = urlBuilder.toString();
        
        InputStream restRegApiStream = null;
        try {
            HttpsURLConnection restRegApiConn = getRestApiConnection(pathWithQueryParams);
            addAuthenticationHeader(restRegApiConnn, atoken);
            restRegApiConn.setRequestMethod("POST");
            
            if (restRegApiConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                if (restRegApiConn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
                    if (restRegApiConn.getHeaderField("www-authenticate").contains("invalid_token")) {
                       
                    }
                } else if (restRegApiConn.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) {
                    
                }
                
            } else {
                restRegApiStream = restRegApiConn.getInputStream();
            }
        }
        catch(Exception ex)
        {

        }
    }

    private static HttpsURLConnection getRestApiConnection(String apiCall) throws IOException {
        URL restApiUrl = new URL(apiCall);
        HttpsURLConnection restApiURLConnection = (HttpsURLConnection) restApiUrl.openConnection();
        return restApiURLConnection;
    }

    private static void addAuthenticationHeader(HttpsURLConnection restApiURLConnection, String t) 
    {
        restApiURLConnection.setRequestProperty("Authorization", "Bearer " + t);
    }

    /**
     * Get the request body to be used for the POST request when requesting an access token.
     */
    private static byte[] getRequestBodyForAccessToken(String user, String pwd) {
        StringBuilder sb = new StringBuilder("grant_type=password");
        sb.append("&username=")
                .append(user)
                .append("&password=")
                .append(pwd);
        return sb.toString().getBytes(StandardCharsets.UTF_8);
    }

    private static void print_https_cert(HttpsURLConnection con){

        if(con!=null){

            try {

                System.out.println("Response Code : " + con.getResponseCode());
                System.out.println("Cipher Suite : " + con.getCipherSuite());
                System.out.println("\n");

                Certificate[] certs = con.getServerCertificates();
                for(Certificate cert : certs){
                    System.out.println("Cert Type : " + cert.getType());
                    System.out.println("Cert Hash Code : " + cert.hashCode());
                    System.out.println("Cert Public Key Algorithm : "
                            + cert.getPublicKey().getAlgorithm());
                    System.out.println("Cert Public Key Format : "
                            + cert.getPublicKey().getFormat());
                    System.out.println("\n");
                }

            } catch (SSLPeerUnverifiedException e) {
                e.printStackTrace();
            } catch (IOException e){
                e.printStackTrace();
            }

        }

    }

    private static void print_content(HttpsURLConnection con){
        if(con!=null){

            try {

                System.out.println("****** Content of the URL ********");
                BufferedReader br =
                        new BufferedReader(
                                new InputStreamReader(con.getInputStream()));

                String input;

                while ((input = br.readLine()) != null){
                    System.out.println(input);
                }
                br.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}

So now you have registered the device on the server. It’s time to send notification to your device


Android java app with notification from asp.net mvc using firebase cloud messaging – part 1

Android java app with notification from asp.net mvc using firebase cloud messaging – part 3

Links



Posted on

Android java app with notification from asp.net mvc using firebase cloud messaging – part 1

Firebase Project

For backend developers.

Follow the document : https://firebase.google.com/docs/android/setup

Important steps : Add Firebase using the Firebase console. After you have a Firebase project, you can add your Android app to it. Enter your app’s package name in the Android package name field. Click Download google-services.json to obtain your Firebase Android config file google-services.json)

Android app in java

For frontend developers

  • Install or update Android Studio to its latest version.
  • Make sure that your app meets the following requirements:
    • Targets API level 16 (Jelly Bean) or later
    • Uses Gradle 4.1 or later

In Android Studio create a new android app using java as language. To enable Firebase products in your app, pass to Project visualization (on the left of android studio) in your root-level Gradle file (build.gradle), add rules to include the Google Services Gradle plugin. Check that you have Google’s Maven repository, as well.

buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.3'  // Google Services plugin
  }
}

allprojects {
  // ...

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}

In your module (app-level) Gradle file (usually app/build.gradle), apply the Google Services Gradle plugin:

apply plugin: 'com.android.application'
// Add the following line:
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

android {
  // ...
}

To your module (app-level) Gradle file (usually app/build.gradle), add the dependencies for the Firebase products that you want to use in your app.

dependencies {
  // ...

  // Add the SDKs for the Firebase products you want to use in your app
  // For example, to use Firebase Authentication and Cloud Firestore
  implementation 'com.google.firebase:firebase-analytics:17.2.0'
  implementation 'com.google.firebase:firebase-messaging:20.1.0'

  // Getting a "Could not find" error? Make sure that you've added
  // Google's Maven repository to your root-level build.gradle file
}

Sync your app (at the top on the right of Android Studio) to ensure that all dependencies have the necessary versions.

Set up a Firebase Cloud Messaging client app on Android

For frontend developers. Follow the document : https://firebase.google.com/docs/cloud-messaging/android/client

Edit your app manifest. A service that extends FirebaseMessagingService. This is required if you want to do any message handling beyond receiving notifications

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.mycompany.myfirstapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature"/>
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:networkSecurityConfig="@xml/network_security_config"
        tools:ignore="GoogleAppIndexingWarning">
        <!-- [START fcm_default_icon] -->
        <!-- Set custom default icon. This is used when no icon is set for incoming notification messages. -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_stat_ic_notification" />
        <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />
        <!-- [END fcm_default_icon] -->
        <!-- [START fcm_disable_auto_init] -->
        <meta-data
            android:name="firebase_messaging_auto_init_enabled"
            android:value="false" />
        <meta-data
            android:name="firebase_analytics_collection_enabled"
            android:value="false" />
        <!-- [END fcm_disable_auto_init] -->
        <activity
            android:name=".EntryChoiceActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- [START firebase_service] -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <!-- [END firebase_service] -->
    </application>

</manifest>

Access the device registration token

On initial startup of your app, the FCM SDK generates a registration token for the client app instance.

The registration token may change when:

  • The app deletes Instance ID
  • The app is restored on a new device
  • The user uninstalls/reinstall the app
  • The user clears app data.

When you need to retrieve the current token, call FirebaseInstanceId.getInstance().getInstanceId(): For example

private void GetRegistrationToken()
    {
        FirebaseInstanceId.getInstance().getInstanceId()
                .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
                    @Override
                    public void onComplete(@NonNull Task<InstanceIdResult> task) {
                        if (!task.isSuccessful()) {
                            Log.w(TAG, "getInstanceId failed", task.getException());
                            return;
                        }

                        // Get new Instance ID token
                        String token = task.getResult().getToken();
                        regToken = token;
                        System.out.println("***************");
                        System.out.println(token);
                        //
                        // Log and toast
                        String msg = getString(R.string.msg_token_fmt, token);
                        Log.d(TAG, msg);
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();

                        //
                        new Thread(){
                            public void run(){
                                try {
                                    //SEND REGISTRATION TOKEN TO BACKEND SERVER
                                catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }.start();
                        //

                    }
                });
    }

As you can see above, after get the registration id you need to pass this to your backend server. In this way you will be able to save this data linking it to your user to permit, in the future, to send message only to selected users.


Android java app with notification from asp.net mvc using firebase cloud messaging – part 2

Android java app with notification from asp.net mvc using firebase cloud messaging – part 3

Links

Posted on Lascia un commento

ASP.NET MVC: PUBBLICAZIONE DI UN SITO

Visual Studio ci consente di pubblicare il nostro sito web su un web server interno (intranet) o su un web server esterno, per esempio ospitato su Azure.

Nel caso di un server in lan, su un web server avete creato tramite IIS un sito che risiede su una certa directory per adesso vuota. Altrimenti avete già pronto un sito esterno.

In Visual Studio, nel pannello a destra chiamato “Solution Explorer” facciamo click con il tasto destro del mouse sul nostro progetto e selezioniamo l’opzione “Publish“. Si apre la finestra “Publish” che riporta a sinistra i 4 step da fare per la pubblicazione.

Profile

Andate sul menu a tendina in alto al centro  e scegliete “New Custom Profile”. Inventatevi il nome di questo profilo. Una volta inserito, passerete direttamente allo step successivo.

Connection con il metodo “Web Deploy”

Publish Metod : scegliere Web Deploy sia che si pubblichi il sito in un server in lan, sia in un server esterno.

Server (web server in lan) : http://myserver

Server (esterno, per esempio Azure): mysite.azurewebsites.net:443

Site name (web server in lan) : nome della directory in cui deve risiedere il sito

Site name (esterno, per esempio Azure) : nome che avete dato al sito (mysite)

User Name e Password (web server in lan) : mettere uno username amministratore della macchina server. Se la macchina è in dominio usare un Amministratore locale.

User Name e Password (esterno) : ftp user

Destination Url : indirizzo del sito web. es : http://……………..

Settings

In questa tab il programma legge dal we.config le stringhe di connessione al database. Se nel vostro sito di destinazione il database è diverso, dovete specificare la giusta connessione. La pubblicazione sostituira le stringhe di destinazione alle stringhe di origine. Vedremo in seguito che esiste un metodo per inserire nel web.config ulteriori variazioni rispetto al web.config di origine.

Preview

Qui potete vedere i file che saranno inviati alla destinazione cioè i nuovi o  i modificati dopo l’ultimo invio. E potete pubblicare!


Configurazione del web.config

Il nostro sito web di destinazione può avere altre caratteristiche particolari, specificate nel web.config, diverse dal sito di partenza, oltre alle stringhe di connessione al database.
Ci possiamo creare un web.config specifico per ogni deploy.

Andate sul progetto. Nelle “Proprietà”, trovate la directory “PublishProfiles” che contiene i dati salvati precedentemente. Trovate un file .pubxml per ognuno dei deploy che avete creato. Andate su file che vi interessa, spingete il tasto destro del mouse e selezionate “Add Config Transform”.

Se andate nel web.config vedrete che esiste un file aggiuntivo che si chiama come il vostro deploy.  Vediamo alcuni esempi di quello che potete fare con tag che inserirete all’interno di <configuration>

<connectionStrings>
 <add name="MyDB"
 connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
 xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
 </connectionStrings>

Questa stringa sostituisce (xdt:Transform=”SetAttributes”) gli attributi del tag che si chiama (xdt:Locator=”Match(name)) “MyDB” con quelli che trova qui.

<appSettings><add key="myemail" value="info@contoso.com" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/></appSettings>

Questa stringa sostituisce gli attributi (xdt:Transform=”SetAttributes”) del tag che ha come key (xdt:Locator=”Match(key)) “myemai” con quelli che trova qui.

<system.net>
 <mailSettings xdt:Transform="Replace">
 <smtp deliveryMethod="Network" ........................
 </smtp>
 </mailSettings>
 </system.net>

Questa stringa trasforma (xdt:Transform=”Replace”) tutto il tag mailSettings ed il suo contenuto.

Posted on

ASP.NET MVC EMAIL DA SITO E PASSWORD DIMENTICATA

Il nostro sito ha necessità di inviare email ai suoi utenti, per esempio quando l’utente si dimentica la password di accesso. Per fare questo ci viene in soccorso la classe System.Net.Mail.SmtpClient.

Questa classe usa in automatico le impostazioni del smtp server memorizzate nel file Web.config. E’ sufficiente aggiungere a questo file i seguenti tag all’interno del configuration :

<system.net>
 <mailSettings>
 <smtp deliveryMethod="Network" from="mail_from">
 <network host="my_smtp_server" port="my_smtp_server_port" userName="user_name_smtp" password="password" clientDomain="my_domain" />
 </smtp>
 </mailSettings>
 </system.net>

PASSWORD DIMENTICATA

Nella view Account/Login , vedete in basso a sinistra il link a Account/ForgotPassword che è la pagina che permette all’utente il reset della password

Andate nel controller Account, nell’action post chiamata “ForgotPassword” e rendete operative, rimuovendole come commento, le linee di codice dedicate al recupero password.

Andate nel file IdentityConfig.cs, nella funzione

public Task SendAsync(IdentityMessage message)

e sostituite alla riga

return Task.FromResult(0);

le seguenti righe di codice

var sentFrom = "myemail@mydomain.com"
 //
 System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
 //
 client.EnableSsl = false;

// Create the message:
 var mail =
 new System.Net.Mail.MailMessage(sentFrom, message.Destination);

mail.Subject = message.Subject;
 mail.Body = message.Body;
 mail.IsBodyHtml = true;

// Send:
 return client.SendMailAsync(mail);

Avete attivato il recupero password

Posted on Lascia un commento

ASP.NET MVC LINQ MIGLIORATO

Linq è un elemento introdotto nel Framework 3.5. Attraverso di esso è possibile fare interrogazioni su liste, collezioni, tabella di database, file xml usando una notazione molto simile al linguaggio SQL.

Ritorniamo per esempio alla nostro modello Student.

[Table("STUDENTS")]
 public class Student
 {
 public int ID { get; set; }
 public string NAME { get; set; }
 public string SURNAME { get; set; }
 public int AGE {get;set;}
 }

Nel nostro context abbiamo l’istanza alla tabella

public DbSet<Student> Students { get; set; }

Attraverso Linq, possiamo chiedere :

var list = context.Studens.Where(s => s.NAME.StartsWith("M") and s.AGE > 18).OrderBy(s => s.SURNAME)

Il linguaggio Linq è lo strumento con cui il context, base dell’ASP.NET MVC, interroga il nostro database. Però Linq, a nostro avviso, proprio quando si lavora con le tabelle di un database ha dei limiti rispetto a SQL. Come vedete, la query sopra è preimpostata : cioè esiste un filtro sulla proprietà NAME e uno sulla AGE e un ordinamento sulla proprietà SURNAME. Questa base di dati sarà sempre ordinata così e al massimo potremo variare la query agendo sulla stringa “M”  e sul numero 18.

Le nostre query però sono variabili in genere. Immaginate di avere una griglia con colonne riordinabili. Usando linq dovreste gestire una query diversa per ognuna delle proprietà che possono essere ordinate ed inoltre dovreste gestire il verso. E se voleste mettere dei filtri ? Dovreste creare delle query in sequenza che, piano piano, filtrano i dati : una per la prima proprietà, uno per la seconda, etc.

Un pò scomodo.

A questo proposito ci viene in soccorso la libreria System.Linq.Dynamic https://github.com/kahanu/System.Linq.Dynamic

che ci permette di fare domande come :

var list = context.Studens.Where("NAME = \"JOHN\" and AGE >= 18 and  AGE <= 34").OrderBy(SURNAME asc, NAME)

Addio Linq , Grazie SQL.