Túl sok segédvonal Visual Studioban

2014.10.29. 4:00 Hozzászólás

Feltetted a Productivity Power Toolst talán mert jó kis függőleges segédvonalakat szerettél volna látni a szerkesztőben, de mielőtt bármit is beállítottál volna, megjelentek maguktól mindenhol?

vs-guidelines-too-much

Ráadásul bármennyire pontosan kattintasz rájuk, ki sem tudod kapcsolni őket, mert a Remove Guideline menüpont mindig inaktív?

vs-guidelines-menu-disabled

Íme a megoldás: ne a Column Guides, hanem a Structure Visualizert kapcsold ki, az a bűnös:

vs-guidelines-options

Ezzel persze pár tooltipet is elvesztesz, de legalább oda tehetsz segédvonalat, ahova csak szeretnél.

 

Technorati-címkék:
Kategóriák:Visual Studio 2013 Címke:

Visual Studio: Unable to check out the current file

2014.10.27. 7:02 Hozzászólás

Érdekes hibába futottam bele, miközben egy szolgáltatás referenciát próbáltam felvenni Visual Studioba. Az URL egy .svc fájlra mutatott, aminek a szerkezetét az Add Service Reference dialógusablak gond nélkül felismerte, ám az ablak bezárásakor a Studio a következő hibaüzenettel örvendeztetett meg:

Unable to check out the current file.  The file may be read-only or locked, or you may need to check the file out manually.

Bár az adott projekt történetesen valóban source control alatt volt, Git-ről lévén szó a “check out” kifejezés nem tűnt helyénvalónak. Az igazság az, hogy a fenti hibaüzenet teljesen rossz és semmi köze a verziókezelőhöz, és a megoldás az, hogy nem közvetlenül az Add Service Reference, hanem azon belül az Advanced gombra, majd az Add Web Reference gombra kattintva megjelenő dialógusablakot kell használni az adott szolgáltatás esetén.

 

Technorati-címkék: ,,

WebAPI dokumentáció kibővítése

Írtam már arról, hogy a Microsoft.AspNet.WebApi.HelpPage NuGet csomaggal milyen könnyen generálhatunk dokumentációt a WebAPI-nkhoz. Mint minden készen kapott megoldással, ezzel is akkor kezdődnek a nehézségek, amikor az ember olyasmit szeretne, amire helyből nincs felkészítve. Szerencsére ebben az esetben a teljes forráskód rendelkezésre áll, így viszonylag egyszerűen testreszabhatjuk a működést és a megjelenést.

Példaként tegyük fel, hogy az API-nk úgy épül fel, hogy minden action hiba esetén a hozzá tartozó enum valamelyik elemét adja vissza hibakódnak a hozzá tartozó hibaüzenettel együtt, és a feladat az, hogy ezek a hibakódok megjelenjenek a dokumentációnkban.

Egy saját attribútummal – amit itt ErrorCodeType-nak hívtam, –  könnyen hozzákapcsolhatjuk a hibakódokat tartalmazó enumot (itt MyErrorCodeEnum) az actionhöz:

[ErrorCodeType(typeof(MyErrorCodeEnum))]

Ezt az információt a következő lépésekkel tehetjük bele a dokumentációba:

1. A Models mappába hozzunk létre egy új osztályt, ami majd egy konkrét hibaág leírására lesz alkalmas, hívjuk ezt ErrorCodeDescription-nek:

public class ErrorCodeDescription
{
  public int Code { get; set; }
  public string Message { get; set; }
}

 

2. A HelpPageApiModel.cs fájl írja le azt a view-modellt, ami alapján a dokumentáció oldal megjelenik. Ebbe az osztályba vegyünk fel egy új tulajdonságot, ami az összes hibalehetőséget fogja tartalmazni egy listában:

public List<ErrorCodeDescription> ErrorResponses { get; set; }

 

3. A HelpPageConfigurationExtensions.cs fájlban található az a GenerateApiModel metódus, ami felépíti a HelpPageApiModel típusú apiModel nevű változóban található view-modellt. Itt a meglévőek mintájára készíthetünk egy saját metódust, ami kiolvassa a csatolt attribútumot, és az alapján felépíti az ErrorResponses listát, például így:

private static void GenerateErrorResponses(HelpPageApiModel apiModel)
{
  ErrorCodeTypeAttribute attribute = apiModel.ApiDescription.ActionDescriptor
    .GetCustomAttributes<ErrorCodeTypeAttribute>().FirstOrDefault();
  Type enumType = attribute.ErrorCodeEnumType;
  string[] names = Enum.GetNames(attribute.ErrorCodeEnumType);

  foreach (string name in names)
  {
    apiModel.ErrorResponses.Add(new ErrorCodeDescription
    {
      Code = (int) Enum.Parse(enumType, name),
      Message = "TODO"
    });
  }
}

 

4. A modell kirenderelését a Views/Help/DisplayTemplates/HelpPageApiModel.cshtml nézet végzi. A meglévő kódok mintájára ide felvehetjük az alábbi blokkot, ami az ErrorResponses lista megjelenítését az ErrorResponses partial view-ra bízza:

@if (Model.ErrorResponses.Any()) 
{ 
  <h3>Error Responses</h3> 
  @Html.DisplayFor(m => m.ErrorResponses, "ErrorResponses") 
}

 

5. Természetesen létre kell hoznunk ugyanebben a mappában egy ErrorResponses.cshtml fájlt, ami @model-ként egy List<ErrorCodeDescription> példányt fog kapni, amit utána úgy jelenítünk meg a weboldalon, ahogy csak szeretnénk.

 

Ez elsőre sok lépésnek tűnik, de valójában egészen logikus, érdemes megbarátkozni vele.

 

Technorati-címkék: ,
Kategóriák:Webfejlesztés Címke:

WebAPI dokumentáció generálása több szerelvényből

2014.10.3. 10:09 Hozzászólás

A Microsoft.AspNet.WebApi.HelpPage NuGet csomag segítségével nagyon könnyen generálhatunk egészen barátságos dokumentációt a WebAPI-nkhoz. A megoldás alapja, hogy a WebAPI projekt kommentjeiből a C# fordítót felhasználva XML fájlt készítünk, amit aztán egy MVC controller felolvas, és barátságos HTML oldalakká fordít.

A problémák akkor jönnek, ha a a REST API publikus interfészén olyan típusok találhatóak, amik nem a WebAPI projektben vannak, hanem egy másik DLL-ben, ugyanis a másik DLL – tipikusan library – kommentjeiből generált XML fájl ugyan bekerül az API bin mappájába, de a webdeploy már nem viszi magával, tehát futási időben nem lesz ott a megfelelő helyen.

A probléma két lépésben orvosolható:

  1. A library XML fájljának bele kell kerülnie a webdeploy csomagba.
  2. A controllert át kell írni, hogy több XML fájllal is működjön.

 

A webdeploy csomag kiegészítése

A webdeploy csomag úgy készül, hogy fordítás után összemásolódik az összes fájl egy mappába, majd ennek a mappának a tartalmából áll össze a csomag. Mivel ezt a folyamatot az MSBuild vezérli, kis trükkel újabb fájlt is be tudunk tenni ebbe az ideiglenes mappába. Mindössze a WebAPI projekthez tartozó .csproj fájlt kell kiegészítenünk:

<Target Name="CopyAdditionalFiles">
  <Message Text="Copy additional files..." Importance="high"/>

  <ItemGroup>
    <_CustomFiles Include="$(ProjectDir)bin\MyLib.xml" />
    <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
      <DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

<PropertyGroup>
  <CopyAllFilesToSingleFolderForMsdeployDependsOn>
    CopyAdditionalFiles;
    $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
  </CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

A fenti módosítás Visual Studio 2012-től kezdve működik, a korábbi verziókhoz képest ugyanis átnevezték a CopyAllFilesToSingleFolderForMsdeployDependsOn elemet.

 

Dokumentáció generálása több XML fájlból

A fent említett NuGet csomag egyetlen XML fájlból tud dokumentációt előállítani. Ha azt szeretnénk, hogy több fájllal is megbirkózzon, akkor módosítanunk kell az XmlDocumentationProvider osztály konstruktorát:

public XmlDocumentationProvider(IEnumerable<string> documentPaths)
{
  if (documentPaths == null)
  {
    throw new ArgumentNullException("documentPaths");
  }

  XDocument finalDoc = null;
  foreach (string documentPath in documentPaths)
  {
    if (finalDoc == null)
    {
      finalDoc = XDocument.Load(File.OpenRead(documentPath));
    }
    else
    {
      XDocument additionalDoc = XDocument.Load(File.OpenRead(documentPath));
      finalDoc.Root.XPathSelectElement("/doc/members")
        .Add(additionalDoc.Root.XPathSelectElement("/doc/members").Elements());
    }
  }

  _documentNavigator = finalDoc.CreateNavigator();
}

A módosítás eredményeként a konstruktornak már több fájl útvonalát kell átadni a korábbi egy helyett. Az elsőt ugyanúgy fogja betölteni, mint korábban, a többit pedig utána fogja fűzni a memóriában. A végeredmény egyetlen nagy XML dokumentum, így a NuGet csomag többi részét nem is kell módosítanunk.

Természetesen a HelpPageConfig.cs-ben már tömb paraméterrel kell meghívnunk a konstruktort, például:

string[] documentPaths = 
{
  HttpContext.Current.Server.MapPath("~/bin/MyAPI.xml"),
  HttpContext.Current.Server.MapPath("~/bin/MyLib.xml")
};
config.SetDocumentationProvider(new XmlDocumentationProvider(documentPaths));

 

Technorati-címkék: ,,
Kategóriák:Webfejlesztés Címke:

Kód futtatása tesztelés elején és végén

Aki Visual Studioban írt már unit teszteket, biztosan találkozott a [TestClass] és [TestMethod] attribútumokkal, amelyekkel a teszteket tartalmazó osztályokat és a konkrét teszteket meg tudjuk jelölni. Hasonlóképpen használhatunk attribútumokat olyan kódok jelölésére, amelyeknek a tesztek előtt vagy után kell lefutniuk:

A TestInitialize és TestCleanup attribútumokkal ellátott metódusok minden teszt előtt és után futnak le.

A ClassInitialize és ClassCleanup attribútumokkal ellátott metódusok az osztályban található első teszt futtatása előtt és az utolsó futtatása után futnak le.

Az AssemblyInitialize és AssemblyCleanup attribútumokkal ellátott metódusok a szerelvényben található első teszt futtatása előtt és az utolsó futtatása után futnak le.

Az utóbbiak különösen hasznosak tudnak lenni CI esetén.

 

Technorati-címkék: ,
Kategóriák:Visual Studio 2013 Címke:

Windows 10: Kinek-mit-mikor?

2014.09.30. 17:41 Hozzászólás

A mai nap a Microsoft bejelentette a Windows következő, “Threshold” kódnevű változatának első előzetesét. Az előzetessel (preview) kapcsolatban nagyon fontos megérteni, hogy a cég jelentősen más stratégiát fog követni a végleges változat előtti kiadásokkal, mint korábban. Biztosan sokan emlékeznek még az alfa-béta-RTM időkre, amit azután felváltott a CTP-CTP-RC-RTM sorozat. Az új Windows verzió a mostani tervek szerint több előzetes, azaz preview formájában fog megjelenni, de nem is az elnevezés a lényeg, hanem hogy az egyes előzetesek jól meghatározott célközönségnek fognak szólni.

Ez a mostani az ún. enterprise preview, azaz a nagyvállalati ügyfeleknek szóló előzetes, amit a következő egy év folyamán újabb előzetesek fognak követni, várhatóan ebben a sorrendben és időzítéssel:

windows-threshold-elozetesek

Jelen pillanatban senki sem tudja pontosan megmondani, hogy az egyes verziókban mi lesz benne, csak az biztos, hogy amit a mostani Windows 10 előzetesben látunk, az még sokat fog változni. Bár a mostani előzetesben is találunk leginkább végfelhasználóknak szóló újdonságokat (több desktop, modern alkalmazások ablakban, Start menü, keresés stb.), ezek még jócskán változhatnak, hiszen ennél a kiadásnál nem ezekre koncentráltak a fejlesztők.

Mit érdemes most kipróbálni? Elsősorban a nagyvállalatoknak szóló újdonságokat, de természetesen lehet visszajelzéseket küldeni minden más funkcióval kapcsolatban is, hiszen a fejlesztőcsapat minden feedbacket komolyan vesz. Sok idő van még a végleges verzióig, sok képlékeny rész van, ami majd a visszajelzések alapján fog kialakulni. Csak épp kimondottan sokat nem érdemes olyan dolgokon pörögni, amik nem az adott kiadás fókuszába esnek.

 

Technorati-címkék:
Kategóriák:Windows Címke:

GUID definiálása XSD-ben

2014.09.30. 14:30 Hozzászólás

XML dokumentumokban gyakran előfordul, hogy egy elem vagy attribútum GUID értéket tartalmaz. Mivel egy XML a hozzá tartozó XSD nélkül fabatkát sem ér, nem ritka feladat, hogy XSD-ben elő kellene írnunk, hogy az adott érték csak GUID lehet. Az XSD sokféle beépített típust támogat, de sajnos GUID nincs, így marad a klasszikus regexes megoldás:

<xs:schema ...>

  <xs:simpleType name="guid">
    <xs:restriction base="xs:string">
      <xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-
[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
    </xs:restriction>
  </xs:simpleType>

Ha ez megvan, akkor pontosan úgy hivatkozhatunk a saját guid típusunkra, mint a beépítettekre:

<xs:attribute name="id" type="guid" use="required" />

Érdemes megfigyelni, hogy a regex elején és végén nincs $ és ^ jel, ugyanis a minta mindig a teljes értékre vonatkozik.

 

Technorati-címkék: ,
Kategóriák:Webfejlesztés Címke:
Követem

Értesítést küldünk minden új bejegyzésről a megadott e-mail címre.

Csatlakozz a 78 követőhöz

%d blogger ezt szereti: