Prieiga prie bendrinamų aplankų kituose serveriuose iš "ASP.NET Core" programos ("Network Connected Program" versija)

Puslapis atnaujintas :
Puslapio sukūrimo data :

Veikimo tikrinimo aplinka

Vizualinė studija
  • "Visual Studio 2022"
ASP.NET branduolys
  • 8 (skustuvo puslapiai, MVC)
"Windows" serveris
  • 2022 m. (ASP.NET pagrindiniai sistemos reikalavimai)
  • 2019 m. (bendro naudojimo aplanko diegimo serveris)
IIS
  • 10.0

Darbo aplinka

Mes ne visais atvejais jį išbandėme, tačiau jis paprastai turėtų veikti šiomis sąlygomis:

Vizualinė studija
  • Viskas, kas gali sukurti "ASP.NET Core" projektą
ASP.NET branduolys
  • Bet kuri versija (MVC, "Razor" puslapiai, API)
"Windows" serveris
  • "Windows Server 2008" arba naujesnė versija
IIS
  • 7.0 arba naujesnė versija

Prielaida

  • ASP.NET Pagrindinės programos skirtos veikti IIS.
  • Kadangi autentifikavimui naudojamos "Windows" API, jis neveikia ne "Windows".

Aplinkos

Jis tikrinamas šioje aplinkoje.

Kompiuterių ir serverių naudojimo tikslas
"Windows 11" (vietinis) Programų kūrimo aplinka.
SV2022Testas Aplinka, kurioje veikia IIS ir ASP.NET branduolys. Pasiekite SV2019Test bendrinamą aplanką iš čia
SV2019Testas Serveriai su bendrai naudojamais aplankais

Be to, įvairūs nustatymai yra tokie.

Parametro pavadinimo reikšmė
Pasiekite vartotojo vardą Bendrinamas naudotojas
Bendro naudojimo aplanko pavadinimas "SharedFolder"

Bendro naudojimo aplankų serverio kūrimas

Vartotojo kūrimas

Sukurkite vartotoją, kad galėtumėte pasiekti bendrą aplanką. Tokiu atveju sukursime vietinę paskyrą, bet jei turite reikalų su serveriais ir paskyromis tokiame domene kaip "Active Directory", galite naudoti ir tai.

Vartotojo kūrimo procesas nepatenka į šių patarimų taikymo sritį, todėl per daug nesigilinsime į detales.

SharedUser Tokiu atveju sukursime jį pavadinimu . Kadangi šis vartotojas neveikia ekrano ir nekeičia nustatymų, slaptažodžio pakeisti negalima.

Jei paliksite numatytąjį, galite prisijungti naudodami šį vartotoją naudodami nuotolinį darbalaukį ir kt., todėl pašalinkite iš grupės Users .

Bendro naudojimo aplanko kūrimas

Nesvarbu, kur jį sukursite. Taip yra todėl, kad kitiems serveriams nerūpi fizinio aplanko vieta. Tokiu atveju sukursime aplanką, pavadintą tiesiai po SharedFolder C disku, ir bendrinsime jį.

Atidarykite ypatybes ir sukonfigūruokite bendrinimo nustatymus.

Bendro naudojimo aplanko pavadinimas turėtų SharedFolder būti . Šis pavadinimas bus matomas kitiems serveriams. Pridėkite SharedUser leidimus.

Everyone Ištrinkite esamą .

Patvirtinkite leidimu "Keisti".

Kadangi pridėjome tik leidimus, kuriuos galima pasiekti iš išorės, nustatysime jį viduje SharedUser , kad jis galėtų veikti šiame aplanke.

Patvirtinkite leidimu "Keisti".

Sukurkite failą, kad patikrintumėte operaciją. Šioje programoje kodavimas apdorojamas UFT-8, todėl išsaugokite jį UTF-8.

Gerai, jei galite pasiekti "Explorer" iš \\<サーバー名>\ kito kompiuterio, prisijungtiSharedUser naudodami "" ir peržiūrėti failą.

Programos, skirtos failams skaityti ir rašyti iš bendrinamo aplanko, kūrimas iš "ASP.NET Core" programos

Mr./Ms. operacija yra mygtuko paspaudimas.

  • Įkelkite failus į bendrinamą aplanką ir rodykite juos ekrane
  • Naujo failo įrašymas į bendro naudojimo aplanką

procesas.

"Razor Pages" ir MVC kodas yra to pavyzdžiai, tačiau programa, kuri pasiekia bendrinamą aplanką, yra vienoda abiem. Tas pats pasakytina ir apie žiniatinklio API. Jei ką, tai turėtų veikti ir kliento programoje.

Procesas, kuris prisijungia prie tinklo konkretaus proceso metu

Sukurkite toliau nurodytą kodą bet kurioje projekto vietoje. Klasės pavadinimas yra SharedFolderAccessor , bet pavadinimas yra savavališkas. SharedFolderAccessor Galite pasiekti bendrinamą aplanką, kol sukursite Dispose . using leidžia nurodyti laikotarpį, per kurį galima gauti prieigą aiškiai apibrėžtoje taikymo srityje.

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,
  }
}

Kadangi jis naudoja Win32 API ir WNetAddConnection2 WNetCancelConnection2 , jis veikia tik Windows aplinkoje. Kol kas turiu komentarą, bet jei norite sužinoti daugiau, ieškokite jo internete. Be bendrinamų aplankų, taip pat galite atlikti operacijas, kad pasiektumėte tinklo išteklius.

Tai lengva naudoti, o jei rašote toliau pateiktą informaciją, using galite pasiekti bendrinamą aplanką taikymo srities metu.

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

Tačiau iš tikrųjų WNetCancelConnection2 , ryšys nėra iš karto atjungiamas skambinimo metu , todėl using galite pasiekti bendrinamą aplanką net ir po apimties.

Išbandykite kodą naudodami SharedFolderAccessor

Kadangi prieigos prie bendrinamo aplanko procesas nepriklauso nuo sistemos, sukuriame bendrą testavimo metodą, kuris skaito ir rašo failus. "Pazor Pages" ir "MVC" turėtų būti vadinami tuo pačiu.

Turinys yra procesas, kurio metu į argumentą perduotas tekstas įrašomas į bendrai naudojamą aplanką, nuskaitomas tekstinis failas, jau esantis bendrai naudojamame aplanke, ir grąžinamas tekstas.

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));
    }
  }
}

Skustuvo puslapiai

"Razor Pages" įdedame mygtuką į Index.cshtml, spustelėkite jį, paleiskite bandymo kodą ir ekrane parodykite rezultatus. Kai kuriais atvejais bendrinamas aplankas gali būti nepasiekiamas, todėl jis pridedamas prie bandomojo sugavimo.

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

Panašiai MVC Index.cshtml atveju įdedamas mygtukas , o spustelėjus jis iškviečia bendrinamo aplanko bandymo kodą.

Kontrolieriai / 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>
@* ここまで追加 *@

Operacijos patvirtinimas

Derinkite ir patikrinkite, ar galite sėkmingai pasiekti bendrinamą aplanką.

Taikomųjų programų serverio kūrimas

Kadangi patvirtinome, kad bendrinamą aplanką galima pasiekti paleidus programą, kitas žingsnis nereikalingas. Jei norite patikrinti operaciją IIS serveryje, galite tai padaryti atlikdami toliau nurodytus veiksmus.

Iš čia tai yra priedas, todėl per daug išsamiai nepaaiškinsiu, o daugiausia paaiškinsiu vaizdą.

IIS diegimas

Įdiekite jį pagal numatytuosius nustatymus iš serverio tvarkyklės. Nesigilinsiu į procedūros detales.

Nereikia jokių papildomų funkcijų.

Šiuo metu nereikia jokių papildomų IIS paslaugų.

ASP.NET "Core Runtime Hosting Bundle" diegimas

Kadangi naudojame ASP.NET Core 8, turime atitinkamai įdiegti vykdymo laiką. Atsisiųskite jį iš šio URL:

Norint paleisti ASP.NET Core IIS, jums reikia kažko, vadinamo "Hosting Bundle". Atsisiųskite "Hosting Bundle" iš "ASP.NET Core Runtime".

Atsisiuntę paleiskite jį serveryje.

Vykdykite vedlį, kad jį įdiegtumėte.

Programos publikavimas

Išveskite programą, kurią norite diegti IIS kaip failą iš "Visual Studio".

Pakeiskite jį "Windows".

Paskelbkite, kai baigsite.

Jei spustelėsite tikslinę vietą, galite atidaryti aplanką, kuriame yra paskelbtas failas.

Jums nereikia jų visų atsinešti, bet jei nesate tikri, kol kas galite pasiimti juos visus. Šiuo metu viskas, ką jums reikia padaryti, tai įsitikinti, kad failas yra.

Žiniatinklio taikomųjų programų kūrimas ir diegimas

Naudodami "Windows" administravimo įrankius atidarykite informacinių interneto tarnybų (IIS) tvarkytuvą.

Mes sukursime svetainę, tačiau šį kartą naudosime "Numatytąją svetainę", kuri yra nuo pat pradžių.

Pasirinkę Numatytoji svetainė, spustelėkite Naršyklė, kad atidarytumėte aplanką. Nukopijuokite paskelbtą programą čia. Galite ištrinti pradinį failą.

Atidarykite puslapį naudodami IIS nuorodą ir pažiūrėkite, ar rodomas ekranas. Pirmiausia galite atidaryti žiniatinklio naršyklę ir tiesiogiai įvesti URL.

Operacijos patvirtinimas

Spustelėkite mygtuką, kad patikrintumėte, ar jis veikia be jokių problemų. Aukščiau, jis pasiekiamas iš žiniatinklio serverio, tačiau kadangi tai yra žiniatinklio serveris, turėtų būti įmanoma jį valdyti iš kitų kompiuterių.