Tag Archives: asp.net

AutoMapper DTO e POCO Object

Una delle soluzioni architetturali che ho imparato ad apprezzare ed utilizzare nel corso degli anni è quella che prevede:

- uno strato Model, contenente una o più entità POCO referenziate tra loro;
- uno strato Repository per l’accesso ai dati;
- uno strato Service;
- uno strato Presentation, che contiene le nostre pagine html/aspx (o le view se sviluppate in asp.net mvc).

Una pratica che vi consiglio caldamente di seguire è di non utilizzare gli oggetti POCO per la loro rappresentazione grafica, ma di affidarvi a dei DTO di appoggio.
In tal senso, oggi ho scoperto un utilissimo metodo fornito da AutoMapper, in sede di creazione della Map tra un oggetto POCO ed un DTO.

1
2
cfg.CreateMap<User, ViewModel.User.dtoUser>()
.ForMember(dest => dest.Property, opt => opt.NullSubstitute("N/A"))

L’utilizzo del metodo NullSubstitute vi consente di associare automaticamente un valore string di default nel caso in cui la proprietà risulti essere NULL. (nel mio caso voglio visualizzare N/A nel caso in cui Property sia NULL).

Related Posts:

Asp.Net carrello Paypal: problema con le spese di spedizione

SottoTitolo: (PayPal Shipping costs not added to total)

Negli ultimi tempi sto concentrando i miei sforzi, in raccordo con Emanuele, sullo sviluppo di una piattaforma e-commerce che abbiamo creato da zero (completamente customizzata – che, spero, andrà online molto presto).

Ho da poco riscontrato un problema nella gestione delle spese di spedizione da parte di PayPal.
Una premessa è dovuta: in sede di raccolta delle specifiche abbiamo deciso di ricorrere a PayPal WebSite Payments Standard (WPS) per il semplice motivo che, nonostante non fornisca tutta una serie di strumenti utili, consente al cliente di effettuare il pagamento anche nel caso in cui non possieda un account PayPal.

Il problema risiede nella gestione che PayPal fa dei costi di spedizione.
La variabile interessata è “shipping”. Leggendo il manuale fornito, alla voce “HTML Variables for Website Payments Standard” si legge che:

shipping – Optional – The cost of shipping this item. If you specify shipping and shipping2 is not defined, this flat amount is charged regardless of the quantity of items purchased.
This use of the shipping variable is valid only for Buy Now and Add to Cart buttons.
Default – If profile-based shipping rates are configured, buyers are charged an amount according to the shipping methods they choose.

Purtroppo, dopo vari test, mi sono reso conto che ciò non corrisponde al vero. Difatti, nonostante io abbia configurato l’account PayPal, alla sezione costi di spedizione, dicendo espressamente di volerli customizzare, il motore non leggeva in alcun modo il valore della variabile che gli passavo.

Dopo un bel pò di tempo passato a leggere il forum (peraltro colgo l’occasione per fare un complimento alla piattaforma x.com), ho trovato questo link: Shipping not being passed to paypal, dove molti sviluppatori lamentavano il fatto che la variabile che in realtà deve essere usata sia “handling_cart”. Sempre dallo stesso manuale si legge che:

handling_cart – Optional – Single handling fee to be charged cart-wide. If handling_cart is used in multiple Add to Cart buttons, the handling_cart value of the first item is used.

Leggendo il forum, mi trovo daccordo con gli sviluppatori. Piuttosto che modificare la documentazione, peraltro non ancora sistemata dopo ben 2 anni, sarebbe il caso che PayPal provvedesse a sistemare il proprio motore interno in modo che la variabile shipping assolva correttamente il suo compito.

Spero di essere stato d’aiuto a qualcuno.

Related Posts:

Asp.Net jQuery validate dialog: this[0] is undefined

Sviluppare in asp.net webform e jquery è sicuramente un’attività che consente di realizzare un prodotto con un codice molto pulito e ben strutturato, delegando correttamente le diverse azioni ad ogni modulo.

Tuttavia, al contrario di quanto non avvenga in asp.net mvc, bisogna fare molta attenzione a ciò che succede dietro le scene.

Oggi per esempio mi sono imbattuto in un comportamento che non avevo notato prima.

La situazione è quella in cui, al click di un pulsante, si apra una finestra popup, realizzata tramite jQuery UI dialog. La finestra conterrà una serie di campi e due pulsanti (annulla, salva): l’obiettivo è consentire l’inserimento su DB di una generica entità (ie: un utente).

In aggiunta, ho inserito una serie di regole di validazione ricorrendo a jQuery validation.
Tuttavia, sul change del campo di testo, la console javascript restituisce questo errore:

this[0] is undefined

Questo avviene perchè il dialog viene creato al di fuori del form presente nella master page (come riportato nella figura sottostante).

html di un form asp.net con un jquery dialog aperto

Per ovviare a questo problema, si deve intervenire sull’evento open del dialog, in modo che il codice del dialog venga inserito all’interno del form.

Di seguito uno snippet del codice necessario:

1
2
3
4
5
6
7
8
9
10
11
$("#popup").dialog({
  title: 'titolo',
  autoOpen: false,
  close: function () { $(this).remove(); },
  open: function () {
    $(this).parent().appendTo($('#aspnetForm'));
  },
  modal: true,
  width: 600,
  height: 300,
  ...

Related Posts:

ASP.NET Wizard Control e UpdatePanel

Con Emanuele stiamo sviluppando un prodotto con una deadline parecchio vicina.
Per questo motivo, dovendo sviluppare un wizard per finalizzare il pagamento su un prodotto Ecommerce, ho scelto di far uso del controllo fornito dal framework .NET ASP:Wizard.

Come tutti i controlli forniti da .net, è molto semplice da utilizzare e, sebbene mi piaccia poco ricorrere al loro utilizzo a causa del basso di livello di customizzazione che possiedono, ho dovuto comunque farne ricorso.

Nel tentativo di fare un qualcosa di fatto bene, ho scelto di accoppiare un UpdatePanel al controllo Wizard.
Ovviamente è crashato tutto, o meglio, il controllo Wizard non consentiva più di navigare tra i vari step a causa del non corretto refresh dell’UpdatePanel.

Dopo un’oretta di tentativi, devo ringraziare Jean Paul per aver fornito la soluzione su stackoverflow.

Related Posts:

Link della settimana #1

Related Posts:

Google Code

Con un mio collega, ho iniziato a sviluppare un componente per realizzare una griglia (un gridview, per intenderci) in asp.net mvc.

Abbiamo deciso di utilizzare Google Code come server repository. Pare funzionare benissimo, tra le altre funzionalità è comodo l’avere a disposizione un server subversion.

Tuttavia è incredibile come non abbiano dato la possibilità di aggiornare più di un indirizzo mail per le modifiche applicate al codice (funzionalità, per altro, già presente in google docs da parecchio tempo)

Related Posts:

ASP.NET ListView: itemPlaceHolder InvalidOperationException

Sto approcciandomi per la prima all’utilizzo del componente ListView, nettamente più potente e flessibile (soprattutto in termini di personalizzazione del layout) rispetto al GridView.

Seguendo l’esempio di Scott Gu, ho creato un ListView del tipo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<asp:ListView runat="server" ID="temp">
  <LayoutTemplate>
  <table>
    <asp:PlaceHolder ID="itemContainer" runat="server">
    </asp:PlaceHolder>
  </table>
  </LayoutTemplate>
 
  <ItemTemplate>
  <tr>
    <td>
      <%#Eval("Descrizione") %>
    </td>
  </tr>
  </ItemTemplate>
</asp:ListView>

Tuttavia, ricevo questo errore a run-time:

È necessario specificare un segnaposto di elemento nell’elemento ListView ‘temp’. Specificare un segnaposto di elemento impostando la proprietà ID di un controllo su “itemPlaceholder”. Il controllo segnaposto di elemento deve inoltre specificare runat=”server”.

Andreas Kraus suggerisce la soluzione corretta, cioè sostituire il valore itemContainer con itemPlaceHolder (nuovo valore di default dell’ ItemPlaceHolderId di ListView)

Il codice corretto, quindi, è:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<asp:ListView runat="server" ID="temp">
  <LayoutTemplate>
  <table>
    <asp:PlaceHolder ID="itemPlaceHolder" runat="server">
    </asp:PlaceHolder>
  </table>
  </LayoutTemplate>
 
  <ItemTemplate>
  <tr>
    <td>
      <%#Eval("Descrizione") %>
    </td>
  </tr>
  </ItemTemplate>
</asp:ListView>

A questo punto, tutto funziona correttamente: il controllo itemPlaceHolder viene sostituito a run-time con il contenuto esplcitato dell’ItemTemplate :)

Ovviamente, il valore della proprietà ID del componente asp:PlaceHolder dichiarato dentro il LayoutTemplate, è personalizzabile grazie all’attributo ItemPlaceholderID di ListView

Related Posts:

Fluent NHibernate mapping exception: Association references unmapped class

Ieri ho perso metà pomeriggio di lavoro per una mia non conoscenza del mapping delle Entity in Fluent NHibernate.

L’eccezione lanciata da NHibernate:

1
Association references unmapped class: YourClass

Il mapping delle mie Entity avviene tramite un metoto CreateSessionFactory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
FluentNHibernate.Cfg.Fluently.Configure()
  .Database
    (
      FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
        .ConnectionString(
          c => c.Server(DbConnectionValue.Server)
                    .Username(DbConnectionValue.User)
                    .Password(DbConnectionValue.Password)
                    .Database(DbConnectionValue.Database)
          )
        .ProxyFactoryFactory("
NHibernate.ByteCode.LinFu.ProxyFactoryFactory
,NHibernate.ByteCode.LinFu")
  )
  .Mappings
  (
    m => m.FluentMappings
.AddFromAssemblyOf<OneClass.Of.My.Repository>()
  )
  .BuildSessionFactory();

Bisogna fare attenzione che esistono 2 regole affinchè si possa correttamente caricare il mapping di Entity caricate tramite il metodo AddFromAssemblyOf:

1. dichiarare sempre public le classi di mapping;
2. definire sempre le proprietà Id;

Related Posts:

Asp.net MVC JavaScriptSerializer: non serializzare proprietà automatich

Immaginiamo di avere il seguente modello:

1
2
3
4
5
6
7
8
 
public class MyModel
{
  public string Cognome { get; set; }
  public string Nome { get; set; }
 
  public DateTime DataNascita { get; set; }
}

Immaginiamo di utilizzare questo modello per renderizzare una View. Successivamente, questa ipotetica View restituirà in post lo stesso Modello.

Una delle scelte archiettturali che si può seguire, è quella di serializzare MyModel in JSon per poi passarlo al server. Ipotizziamo, adesso, di non voler serializzare una delle proprietà di MyModel, ad esempio DataNascita. Per farlo, basta agganciare alla proprietà DataNascita, l’attributo ScriptIgnore:

1
2
3
4
5
6
7
8
9
 
public class MyModel
{
  public string Cognome { get; set; }
  public string Nome { get; set; }
 
  [ScriptIgnore]
  public DateTime DataNascita { get; set; }
}

Related Posts:

Jquery UI 1.8rc1, Jquery 1.4.1, Jquery masked input 1.2.2: datepicker bug

Recentemente ho riscontrato un bug nell’utilizzo del componente datepicker in accoppiata con il plugin masked input di query.
Quando si seleziona una data dal calendarietto associato e si cerca poi di modificarla manualmente, il sistema cancella completamente la data, costringendo l’utente ad inserirla nuovamente.

Ho aperto un ticket nella sezione dev di jquery.

Related Posts:

Asp.NET TextBox: attributo MaxLength in modalità MultiLine

Quando vi trovate ad utilizzare il componente asp:textbox in modalità multiline, noterete che l’attributo maxlength non funziona.

Non conosco ne conosco la ragione, però esiste un work-around:

private const int MAX_LENGTH = 100;
 
protected void Page_Load(object sender, EventArgs e)
{
string lengthFunction = "function isMaxLength(txtBox) {";
    lengthFunction += " if(txtBox) { ";
    lengthFunction += 
      "     return ( txtBox.value.length <=" + MAX_LENGTH + ");";
    lengthFunction += " }";
    lengthFunction += "}";
 
this.txtMyTextBox.Attributes.Add("onkeypress", 
      "return isMaxLength(this);");
      ClientScript.RegisterClientScriptBlock(
        this.GetType(), 
        "txtLength", 
        lengthFunction , true);
 
}

(via codegod.de)

Related Posts:

Asp.NET e Microsoft Reporting Services: ordinare una tabella Tablix da c#

In alcuni casi, nel realizzare un’applicazione web ha senso appoggiarsi a Microsoft Reporting Services per consentire agli utenti di stampare il risultato di una generica griglia sulla quale è possibile applicare un sorting.

Il problema è quello di riportare l’esatto sorting applicato sulla griglia anche sul report generato da Microsoft Reporting Services.

A tal fine, quindi, la strada che ho seguito è la seguente:

1. Creare due nuovi parametri all’interno del report: DIRECTION e SORTBY (parametri stringa con valore anche eguale a stringa vuota);

2. Entrare nelle proprietà della tabella Tablix, sezione ordinamento. Inserire le due seguenti espressioni:

=iif(Parameters!DIRECTION.Value="asc"
,Fields(Parameters!SORTBY.Value).Value,0)
=iif(Parameters!DIRECTION.Value="desc"
,Fields(Parameters!SORTBY.Value).Value,0)

Imporre che la prima sia un ordinamento “da A a Z” e la seconda un ordinamento “da Z ad A”

A questo punto è sufficiente impostare questi due parametri da codice c# ed il gioco è fatto :)

(via 15seconds.com)

Related Posts:

ASP.NET c# 3.5: cancellare il testo delle TextBox contenute nella pagina con LINQ

In rete esistono molti esempi di come si possa cancellare il testo contenuto nelle TextBox presenti nella propria pagina aspx.

Molti di questi esempi partono dal presupposto che la nostra pagina aspx non sia agganciata ad una masterpage. In questo caso, per la particolare gerarchia delle pagine aspx rispetto alla masterpage, bisogna apportare una piccola modifica al codice in questione.

Si deve infatti prima individuare il ContentPlaceHolder all’interno del quale insistono le TextBox di cui si vuole modificare la proprietà Text e successivamente utilizzare una lambda expression per eliminare il testo.

public void ClearTextBoxText()
{
ContentPlaceHolder mpContentPlaceHolder;
mpContentPlaceHolder = (ContentPlaceHolder)Master
                                 .("ContentPlaceHolder1");
 
if (mpContentPlaceHolder != null)
{
    List<TextBox> txt = mpContentPlaceHolder.Controls
                      .OfType<TextBox>()
                      .ToList()
                      .ForEach(t => t.Text = string.Empty);
}
}

Related Posts:

AspItalia Real Code Day 4 dicembre 2009 Firenze

Sono appena tornato dalla conferenza di ASPItalia “Real Code Day”, organizzata a Firenze nella struttura della Scuola Superiore Tecnologie Industriali (SSTI).

Tralascio l’organizzazione, appena sufficiente, considerati i problemi di rete e le continue sospensioni perchè dislocati in più aule collegate in wifi (numerosa partecipazione e, per dovere di cronaca, sentite scuse da parte di tutti anche di un tizio che credo sia il presidente/direttore/responsabile del SSTI.

Mi è piaciuta molto la disponibilità di Stefano Mostarda e Riccardo Golia al dialogo con tutti i partecipanti: una spanna sopra tutti.

Mi son piaciute molto meno le sessioni su WPF e Silverlight 4.0, troppo caciaroni e poco professionali gli speaker, il che, inevitabilmente, ha portato a disattenzione generale (soprattutto nelle aulee collegate in wireless) – una domanda su tutte: ma che ci frega di Silverlight e WPF e dello XAML, noi vogliamo vedere Blend (poi lo XAML ce lo leggiamo online).

Positivo il fatto che questa conferenza, come le altre due che ho seguito negli ultimi due mesi (ed organizzate direttamente da Microsoft), ti fanno tornare la passione di sviluppare applicazioni web di un certo livello e di approcciarsi al mondo dello sviluppo in un modo che non è per niente riscontrabile nella città di Roma (almeno nella mia diretta esperienza personale – spero esistano realtà diverse).

Related Posts:

ASP.NET v3.5 v2.0 IIS 5.1 Impossibile accedere al metabase IIS

Oggi sono incappato in questo errore che, ovviamente, mi ha fatto perdere un’ora di lavoro.

L’account di processo utilizzato per eseguire ASP.NET deve avere accesso in lettura al metabase IIS

Dopo alcune ricerche su Google, sono riuscito a risalire al problema. Per risolverlo, è sufficiente eseguire il comando

1
aspnet_regiis.exe -i

Related Posts:

Microsoft Visual Studio 2005: usare i dataset su SQL Server 2008

Per chi ancora nel 2009 si dovesse trovare ad utilizzare i dataset ed eventualmente in concomitanza con SQL Server 2008, potrebbe vedere questo errore in Visual Studio 2005, all’atto del tentativo di creazione di un TableAdapter:

“This server version is not supported. Only servers up to Microsoft SQL Server 2005 are supported.”

Per risolvere il problema, basta installare questa patch: VS80sp1-KB954961-X86-INTL

Grazie a Manuel per la segnalazione.

Related Posts:

Subsonic 2.1: GetCount() e GetRecordCount() System.InvalidCastException

Dopo una serie di polemiche sul forum, pare che finalmente siano stati risolti i problemi di Subsonic, relativi ai due metodi GetCount() e GetRecordCount() che potete richiamare sull’oggetto Select.

In realtà, la versione 2.1 final non è fixata. Potete farlo manualmente, modificando i sorgenti, facendo un rebuild della solution e sovrascrivendo il file Subsonic.dll che state utilizzando.

Fix:
Modify SqlQuery/SqlQuery.cs : line 1241
from
count = (int)scalar;
to
count = (int)Utility.ChangeType(scalar, typeof(int));

(via codplex)

Related Posts: