Month: September 2014

Dowiedziane przy okazji DevDay

Posted on Updated on

Pola i konstruktor lądują na dole klasy bo nas nie interesują.

[RoutePrefix("api/declarations")]
public class DeclarationsController : ApiController
{
    [Route("{declarationId:int}")]
    public IHttpActionResult GetDeclaration(int declarationId)
    {
        Declaration declaration = declarationsRepository.Get(declarationId);
        if (declaration == null)
        {
            return NotFound();
        }
        return Ok(declaration);
    }

    // methods

    // fields and contructor
    readonly DeclarationsRepository declarationsRepository;

    public DeclarationsController(DeclarationsRepository declarationsRepository)
    {
        this.declarationsRepository = declarationsRepository;
    }
}

Domyślnie nie tworzyć klas public. Pomoże to w enkapsulacji. Ma to zastosowanie gdy mamy architekturę wielowarstwową (która mieści się w wielu projektach). Jeśli mamy tylko jeden projekt to też piszmy bez public i tak wszystko będzie widoczne. Klasy domyślnie dostają internal, który oznacza że są widoczne w obrębie projektu.
Jeśli chodzi o testy to można nadać

[assembly: InternalsVisibleTo("App.Tests")]

FireShot – zrób screenshot całej stronie

Posted on Updated on

W firefoxie można zainstalować dodatek:

https://addons.mozilla.org/pl/firefox/addon/fireshot/

  • trzeba go zainstalować i pojawi się w prawym górnym rogu (literka ‘S’)
  • będąc na stronie z ofertą można kliknąć ten przycisk i poczekać aż program zrobi zdjecia całej stronie,
  • potem można edytować, na górze jest przycisk “Text”,
  • dalej klikamy gdzieś w obrazek i możemy dodawać własne opisy,
  • po prawej stronie jest można też zmieniać kolory i rozmiar napisów.

Visual Basic .NET – częste problemy

Posted on Updated on

Przekazywanie argumentów ByRef

W Visual Basic .NET w sygnaturze funkcji explicite podajemy czy argument jest przekazywany ByVal (przez wartość) czy ByRef (przez referencję). W C# domyślnie jest to przez wartość np

void Foo(int number)

W C# trzeba dodać specjalny modifykator ref, żeby po wyjściu z funkcji mieć inną wartość (14).

void Foo(ref int number)
{
    number = 14;
}

void Bar()
{
    int sum = 5;
    Foo(sum);
    Console.WriteLine(sum); // 14
}

Ten kod wygląda na nienormalny i czegoś takiego nie powinniśmy nigdy pisać. Jeśli chcemy dostać coś z funkcji to robimy to poprzez zwracane argumenty a nie modyfikowanie istniejących.
W Visual Basic takie sytuacje zdarzają się dosyć często więc dużo trudniej przewidzieć co się dzieje w kodzie, gdy ma się pewne nawyki z C#.
Proponuję więc aby wszystkie parametry były przekazywane ByVal W istniejącym kodzie dla czytelności i zrozumienia newralgicznych kawałków które refaktorujemy, proponuję zamieniać ByRef na ByVal. Czasem może to wymagać w kodzie np:

Private Sub Foo(..., ByRef number As Integer)
        ' ....
	number = 14
End Sub

na

Private Function Foo(...) As Integer
        ' ....
	Return 14
End Function

czyli całkiem prostych. Czasem będzie to jednak trudniejsze …

“And” to nie to samo co “AndAlso”

W C# zdarza się pisać następujący warunek. Operator && nie wykona drugiego sprawdzania jeśli pierwsze zwróci ‘false’.

if(student != null && student.Age >= 18){}

W VB już nie jest to takie oczywiste. Mamy dwa operatory: And oraz AndAlso i tylko ten drugi jest odpowiednikiem C#’owego &&.

If student IsNot Nothing And student.Age >= 18 Then ' Pewny strzał w NullReferenceException prędzej czy później.
End If

If student IsNot Nothing AndAlso student.Age >= 18 Then ' prawidłowo
End If

Operator “And” wykona również drugi warunek mimo że pierwszy zwróci false. Jest to bardzo nieintuicyjne jak na to w jaki sposób pisze w .NET programy.

Moja rada to przerobić cały kod, aby korzystał z AndAlso.

Instalacja SQL Management Studio 2012

Posted on

Po pobraniu i uruchomieniu trzeba wybrać aktualną instancję SQL Server (Express) i dopiero wtedy gdzieś w opcjach dodatkowych doinstalować Management Studio.

Nancy – zasłanianie się danych podczas bindowania z POST

Posted on Updated on

Mamy następujący kawałek kodu. Nancy – moduł REST który coś tam robi.

public class TopicsModule : NancyModule
{
    public class Note
    {
        public int Id { get; set; }
        public string Content { get; set; }
    }

    public TopicsModule()
        : base("/api/topics")
    {
        Post["/{id:int}"] = parameters =>
        {
            var id = (int)parameters.id.Value;

            Note note = this.Bind<Note>();
            // note.Id == ?
          
            // ...
        }
    }
}

Wywołujemy request typu POST pod adres http://localhost/api/topics/11 z następującym body:

{ 
  id: 44, 
  content: 'nowy tekst'
}

Teraz pytanie – Jaka będzie wartość note.Id?

Spodziewałem się wartości 44 i trochę się namęczyłem szukając dlaczego nie jest to 44.
Mechanizm bindowania działa tak, że najpierw brane są wartości z URLa, później z Query stringa, a dopiero na końcu z body requestu. W powyższym przypadku note.Id wynosić więc będzie 11.

Musimy więc w kodzie zapewnić aby nie było kolizji tych nazw, np:

public class TopicsModule : NancyModule
{
    public class Note
    {
        public int Id { get; set; }
        public string Content { get; set; }
    }

    public TopicsModule()
        : base("/api/topics")
    {
        Post["/{topicId:int}"] = parameters =>
        {
            var topicId = (int)parameters.topicId.Value;

            Note note = this.Bind<Note>();
            // note.Id == 44
          
            // ...
        }
    }
}