Dostop do map v skupni rabi v drugih strežnikih iz aplikacije ASP.NET Core (različica programa z omrežjem)

Stran posodobljena :
Datum ustvarjanja strani :

Okolje za preverjanje delovanja

Visual Studio
  • Visual Studio 2022
ASP.NET jedro
  • 8 (britvice strani, MVC)
Windows Server
  • 2022 (ASP.NET osnovne sistemske zahteve)
  • 2019 (strežnik za uvajanje map v skupni rabi)
Storitve IIS
  • 10.0

Delovno okolje

V vseh primerih ga nismo preizkusili, vendar bi moral na splošno delovati pod naslednjimi pogoji:

Visual Studio
  • Vse, kar lahko razvije projekt ASP.NET Core
ASP.NET jedro
  • Vsaka različica (MVC, Razor Pages, API)
Windows Server
  • Windows Server 2008 ali novejša različica
Storitve IIS
  • 7.0 ali novejši

Pogoj

  • ASP.NET Osnovne aplikacije naj bi se izvajale v storitvah IIS.
  • Ker za preverjanje pristnosti uporablja API-je za Windows, ne deluje v napravah, ki niso Windows.

okolje

Preverjeno je v naslednjem okolju.

Namen uporabe osebnih računalnikov in strežnikov
Windows 11 (lokalno) Okolje za razvoj programov.
SV2022Test Okolje, v katerem se izvajata storitvi IIS in ASP.NET Core. Od tu dostopajte do mape v skupni rabi SV2019Test
SV2019Test Strežniki z mapami v skupni rabi

Poleg tega so različne nastavitve naslednje.

Vrednost imena parametra
Dostop do uporabniškega imena SharedUser
Ime mape v skupni rabi Mapa v skupni rabi

Ustvarjanje strežnika map v skupni rabi

Ustvarjanje uporabnika

Ustvarite uporabnika za dostop do skupne mape. V tem primeru bomo ustvarili lokalni račun, če pa imate opravka s strežniki in računi v domeni, kot je Active Directory, lahko uporabite tudi to.

Postopek ustvarjanja uporabnika presega obseg teh nasvetov, zato se ne bomo spuščali v preveč podrobnosti.

SharedUser V tem primeru ga bomo ustvarili z imenom . Ker ta uporabnik ne upravlja zaslona ali spreminja nastavitev, gesla ni mogoče spremeniti.

Če pustite privzeto, se lahko s tem uporabnikom prijavite z oddaljenim namizjem itd., Zato odstranite iz skupine Users .

Ustvarjanje mape v skupni rabi

Ni pomembno, kje ga ustvarite. To je zato, ker drugim strežnikom ni mar za lokacijo fizične mape. V tem primeru bomo ustvarili mapo, imenovano neposredno pod SharedFolder pogonom C, in jo delili.

Odprite lastnosti in konfigurirajte nastavitve skupne rabe.

Ime mape v skupni rabi bi moralo SharedFolder biti . To ime bo vidno drugim strežnikom. Dodajte SharedUser dovoljenja.

Everyone Izbrišite obstoječo .

Potrdite z dovoljenjem »Spremeni«.

Ker smo dodali samo dovoljenja, do katerih je mogoče dostopati od zunaj, ga bomo nastavili interno SharedUser , da bo lahko deloval v tej mapi.

Potrdite z dovoljenjem »Spremeni«.

Ustvarite datoteko, da preverite operacijo. V tem programu se kodiranje obdeluje v UFT-8, zato ga shranite v UTF-8.

V redu je, če lahko dostopate v Raziskovalcu iz \\<サーバー名>\ drugega računalnika, se prijaviteSharedUser z in si ogledate datoteko.

Ustvarjanje programa za branje in pisanje datotek iz mape v skupni rabi iz aplikacije ASP.NET Core

Operacija gospoda / gospe je, da kliknete gumb.

  • Naložite datoteke v mapo v skupni rabi in jih prikažite na zaslonu
  • Pisanje nove datoteke v mapo v skupni rabi

proces.

Primeri tega so strani z britvico in koda MVC, vendar je program, ki dostopa do mape v skupni rabi, enak za oba. Enako velja za spletne API-je. Če kaj, bi moral delovati tudi v odjemalskem programu.

Proces, ki vzpostavi povezavo z omrežjem za čas trajanja določenega procesa

Ustvarite naslednjo kodo kjer koli v projektu. Ime razreda je SharedFolderAccessor , vendar je ime poljubno. SharedFolderAccessor Do mape v skupni rabi lahko dostopate, dokler ne ustvarite primerka Dispose . using Omogoča vam, da določite časovno obdobje, v katerem je dostop mogoč v izrecnem obsegu.

using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;

/// <summary>
/// 共有フォルダにユーザー名とパスワードでアクセスするためのクラスです。
/// using を使用すればそのスコープの間、共有フォルダにアクセスできます。
/// </summary>
public class SharedFolderAccessor : IDisposable
{
  private readonly string _networkName;

  /// <summary>
  /// コンストラクタです。
  /// </summary>
  /// <param name="networkName">共有フォルダのあるサーバーを「\\&lt;サーバー名&gt;」形式で指定します。</param>
  /// <param name="credentials">共有フォルダにアクセスするための資格情報です。</param>
  /// <exception cref="Win32Exception"></exception>
  public SharedFolderAccessor(string networkName, NetworkCredential credentials)
  {
    _networkName = networkName;

    // 接続するネットワークの情報を設定
    var netResource = new NetResource
    {
      Scope = ResourceScope.GlobalNetwork,
      ResourceType = ResourceType.Disk,
      DisplayType = ResourceDisplaytype.Share,
      RemoteName = networkName,
    };

    // ドメインがある場合はドメイン名も指定、ない場合はユーザー名のみ
    var userName = string.IsNullOrEmpty(credentials.Domain)
        ? credentials.UserName
        : $@"{credentials.Domain}\{credentials.UserName}";

    // 共有フォルダにユーザー名とパスワードで接続
    var result = WNetAddConnection2(netResource, credentials.Password, userName, 0);

    if (result != 0)
    {
      throw new Win32Exception(result, $"共有フォルダに接続できませんでした。(エラーコード:{result})");
    }

    // 正常に接続できれば WNetCancelConnection2 を呼び出すまではプログラムで共有フォルダにアクセス可能
  }

  ~SharedFolderAccessor()
  {
    // Dispose を呼び忘れたときの保険
    WNetCancelConnection2(_networkName, 0, true);
  }

  public void Dispose()
  {
    WNetCancelConnection2(_networkName, 0, true);
    GC.SuppressFinalize(this);  // Dispose を明示的に呼んだ場合はデストラクタの処理は不要
  }

  /// <summary>
  /// ネットワーク リソースへの接続を確立し、ローカル デバイスをネットワーク リソースにリダイレクトできます。
  /// </summary>
  /// <param name="netResource">ネットワーク リソース、ローカル デバイス、ネットワーク リソース プロバイダーに関する情報など。</param>
  /// <param name="password">ネットワーク接続の作成に使用するパスワード。</param>
  /// <param name="username">接続を確立するためのユーザー名。</param>
  /// <param name="flags">接続オプションのセット。</param>
  /// <returns></returns>
  [DllImport("mpr.dll")]
  private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);

  /// <summary>
  /// 既存のネットワーク接続を取り消します。
  /// </summary>
  /// <param name="name">リダイレクトされたローカル デバイスまたは切断するリモート ネットワーク リソースの名前。</param>
  /// <param name="flags">接続の種類。</param>
  /// <param name="force">接続に開いているファイルまたはジョブがある場合に切断を行う必要があるかどうか。</param>
  /// <returns></returns>
  [DllImport("mpr.dll")]
  private static extern int WNetCancelConnection2(string name, int flags, bool force);

  /// <summary>
  /// NETRESOURCE 構造体を定義しています。
  /// </summary>
  [StructLayout(LayoutKind.Sequential)]
  private class NetResource
  {
    public ResourceScope Scope;
    public ResourceType ResourceType;
    public ResourceDisplaytype DisplayType;
    public int Usage;
    public string LocalName = "";
    public string RemoteName = "";
    public string Comment = "";
    public string Provider = "";
  }

  /// <summary>
  /// ネットワークリソースのスコープ。
  /// </summary>
  private enum ResourceScope : int
  {
    /// <summary>ネットワークリソースへの現在の接続。</summary>
    Connected = 1,
    /// <summary>すべてのネットワークリソース。</summary>
    GlobalNetwork = 2,
    Remembered = 3,
    Recent = 4,
    /// <summary>ユーザーの現在および既定のネットワークコンテキストに関連付けられているネットワークリソース。</summary>
    Context = 5,
  };

  /// <summary>
  /// リソースの種類。
  /// </summary>
  private enum ResourceType : int
  {
    /// <summary>印刷リソースとディスクリソースの両方のコンテナー、または印刷またはディスク以外のリソースなど。</summary>
    Any = 0,
    /// <summary>共有ディスクボリューム。</summary>
    Disk = 1,
    /// <summary>共有プリンター。</summary>
    Print = 2,
    Reserved = 8,
  }

  /// <summary>
  /// ユーザーインターフェイスで使用する必要がある表示の種類。
  /// </summary>
  private enum ResourceDisplaytype : int
  {
    /// <summary>リソースの種類を指定しないネットワークプロバイダーによって使用されます。</summary>
    Generic = 0x0,
    /// <summary>サーバーのコレクション。</summary>
    Domain = 0x01,
    /// <summary>サーバー。</summary>
    Server = 0x02,
    /// <summary>共有ポイント。</summary>
    Share = 0x03,
    File = 0x04,
    Group = 0x05,
    /// <summary>ネットワークプロバイダー。</summary>
    Network = 0x06,
    Root = 0x07,
    Shareadmin = 0x08,
    /// <summary>ディレクトリ。</summary>
    Directory = 0x09,
    Tree = 0x0a,
    Ndscontainer = 0x0b,
  }
}

Ker uporablja API-je Win32 in WNetAddConnection2 WNetCancelConnection2 , deluje samo v okolju Windows. Zaenkrat imam pripombo, če pa želite izvedeti več, jo prosim poiščite na internetu. Poleg map v skupni rabi lahko izvajate tudi postopke za dostop do omrežnih virov.

Je enostaven za uporabo in če napišete naslednje, lahko med obsegom dostopate using do mape v skupni rabi.

using (new SharedFolderAccessor($@"\\{serverName}", credentials))
{
  // この間は共有フォルダにアクセスできる
}

Vendar pa v resnici WNetCancelConnection2 povezava ni takoj prekinjena ob času klicanja , tako da using lahko dostopate do mape v skupni rabi tudi po obsegu.

Preskusna koda z uporabo SharedFolderAccessor

Ker postopek dostopa do mape v skupni rabi ni odvisen od ogrodja, ustvarimo skupno metodo za testiranje, ki bere in piše datoteke. Pazorske strani in MVC je treba imenovati enake.

Vsebina je proces, ki zapiše besedilo, posredovano argumentu v mapo v skupni rabi, prebere besedilno datoteko, ki je že v mapi v skupni rabi, in vrne besedilo.

using System.Net;

public static class Util
{
  public static string ReadAndWrite(string text)
  {
    var serverName = "ServerName";
    var folderName = "SharedFolder";
    var inputFileName = "Input.txt";
    var outputFileName = "Output.txt";
    var username = "SharedUser";
    var password = "password";

    var credentials = new NetworkCredential(username, password);
    using (new SharedFolderAccessor($@"\\{serverName}", credentials))
    {
      // ファイルの書き出し
      System.IO.File.WriteAllText(Path.Combine($@"\\{serverName}\{folderName}", outputFileName), text);

      // ファイルの読み込み
      return System.IO.File.ReadAllText(Path.Combine($@"\\{serverName}\{folderName}", inputFileName));
    }
  }
}

Britvice strani

V Razor Pages postavimo gumb v Index.cshtml, ga kliknemo, zaženemo testno kodo in rezultate prikažemo na zaslonu. V nekaterih primerih mapa v skupni rabi morda ni dostopna, zato je priložena v poskusni ulov.

Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace SharedFolderAccessRazorPages.Pages
{
  public class IndexModel : PageModel
  {
    private readonly ILogger<IndexModel> _logger;
    public string Message { get; set; } = "";

    public IndexModel(ILogger<IndexModel> logger)
    {
      _logger = logger;
    }

    public void OnPost()
    {
      try
      {
        Message = Util.ReadAndWrite($"プログラムからの書き込み ({DateTime.Now})");
      }
      catch (Exception ex)
      {
        Message = ex.ToString();
      }
    }
  }
}

Index.cshtml

@page
@model IndexModel
@{
  ViewData["Title"] = "Home page";
}

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@* ここから追加 *@
<form method="post">
  <button type="submit">サブミット</button>
</form>

<div>
  @Model.Message
</div>
@* ここまで追加 *@

MVC

Podobno je v primeru MVC-ja Index.cshtml vstavljen gumb in ob kliku pokliče preskusno kodo mape v skupni rabi.

Upravljavci/HomeController.cs

// 省略

namespace SharedFolderAccessMvc.Controllers
{
  public class HomeController : Controller
  {
    // 省略

    public IActionResult Index()
    {
      return View();
    }

    // ここから追加
    [HttpPost]
    public IActionResult Index(string dummy)
    {
      try
      {
        ViewData["Message"] = Util.ReadAndWrite($"プログラムからの書き込み ({DateTime.Now})");
      }
      catch (Exception ex)
      {
        ViewData["Message"] = ex.ToString();
      }
      return View();
    }
    // ここまで追加

    public IActionResult Privacy()
    {
      return View();
    }

    // 省略
  }
}

Index.cshtml

@{
  ViewData["Title"] = "Home Page";
}

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@* ここから追加 *@
<form method="post">
  <button type="submit">サブミット</button>
</form>

<div>
  @ViewData["Message"]
</div>
@* ここまで追加 *@

Potrditev delovanja

Odpravite napake in preverite, ali lahko uspešno dostopate do mape v skupni rabi.

Gradnja aplikacijskega strežnika

Ker smo potrdili, da je do mape v skupni rabi mogoče dostopati z zagonom programa, naslednji korak ni potreben. Če želite preveriti postopek v strežniku IIS, lahko to storite tako, da sledite spodnjim korakom.

Od tu je dodatek, zato ga ne bom preveč podrobno razložil, ampak bom predvsem razložil sliko.

Namestitev storitev IIS

Privzeto ga namestite iz upravitelja strežnika. Ne bom se spuščal v podrobnosti postopka.

Dodatne funkcije niso potrebne.

Trenutno niso potrebne nobene dodatne storitve IIS.

Namestitev paketa ASP.NET Core Runtime Hosting Bundle

Ker uporabljamo ASP.NET Core 8, moramo ustrezno namestiti izvajalnik. Prenesite ga z naslednjega URL-ja:

Če želite zagnati ASP.NET Core v storitvah IIS, potrebujete nekaj, kar se imenuje »Gostovanje paketa«. Prenesite "Hosting Bundle" iz izvajalnika ASP.NET Core.

Ko ga prenesete, ga zaženite na strežniku.

Namestite ga s čarovnikom.

Objava programa

Izpišite program, ki ga želite uvesti v storitve IIS, kot datoteko iz programa Visual Studio.

Spremenite ga za Windows.

Ko končate, objavite.

Če kliknete ciljno mesto, lahko odprete mapo, v kateri je objavljena datoteka.

Ni vam treba prinesti vseh, če pa niste prepričani, jih lahko za zdaj vzamete vse. Na tej točki se morate le prepričati, da datoteka obstaja.

Ustvarjanje in uvajanje spletnih aplikacij

V skrbniških orodjih sistema Windows odprite upravitelja storitev IIS (Internet Information Services).

Ustvarili bomo spletno stran, vendar bomo tokrat uporabili "Privzeto spletno stran", ki je tam od začetka.

Ko je izbrano Privzeto spletno mesto, kliknite Raziskovalec, da odprete mapo. Kopirajte objavljeni program tukaj. Izvirno datoteko lahko izbrišete.

Odprite stran s povezave IIS in preverite, ali se prikaže zaslon. Najprej lahko odprete spletni brskalnik in neposredno vnesete URL.

Potrditev delovanja

Kliknite gumb, da preverite, ali deluje brez težav. V zgoraj navedenem je dostopen iz spletnega strežnika, ker pa gre za spletni strežnik, bi ga moralo biti mogoče upravljati z drugih osebnih računalnikov.