Piekļuve koplietojamām mapēm citos serveros no lietojumprogrammas ASP.NET Core (tīkla savienotās programmas versija)

Lapa atjaunota :
Lapas izveides datums :

Darbības verifikācijas vide

Visual Studio
  • Visual Studio 2022
ASP.NET kodols
  • 8 (Skuvekļa lapas, MVC)
Windows Server
  • 2022. gads (ASP.NET sistēmas pamatprasības)
  • 2019. gads (koplietojamo mapju izvietošanas serveris)
IIS
  • 10.0

Darbības vide

Mēs to neesam pārbaudījuši visos gadījumos, taču tam parasti vajadzētu darboties šādos apstākļos:

Visual Studio
  • Jebkas, kas var izstrādāt ASP.NET Core projektu
ASP.NET kodols
  • Jebkura versija (MVC, Razor Pages, API)
Windows Server
  • Windows Server 2008 vai jaunāka versija
IIS
  • 7.0 vai jaunāka versija

Priekšnosacījumu

  • ASP.NET Galvenās lietojumprogrammas ir paredzētas darbībai IIS.
  • Tā kā autentifikācijai tā izmanto Windows API, tā nedarbojas ar ne-Windows.

vide

Tas tiek pārbaudīts šādā vidē.

Personālo datoru un serveru izmantošanas mērķis
Windows 11 (vietējais) Vide programmu izstrādei.
SV2022Tests Vide, kurā darbojas IIS un ASP.NET Core. Piekļuve SV2019Test koplietojamai mapei no šejienes
SV2019Tests Serveri ar koplietojamām mapēm

Turklāt dažādie iestatījumi ir šādi.

Parametra nosaukuma vērtība
Piekļuves lietotājvārds SharedUser
Koplietojamās mapes nosaukums SharedFolder

Koplietojamu mapju servera izveide

Lietotāja izveide

Izveidojiet lietotāju, lai piekļūtu kopējai mapei. Šajā gadījumā mēs izveidosim vietējo kontu, bet, ja jums ir darīšana ar serveriem un kontiem domēnā, piemēram, Active Directory, varat to arī izmantot.

Lietotāja izveides process ir ārpus šo padomu darbības jomas, tāpēc mēs neiedziļināsimies pārāk daudz detaļās.

SharedUser Šajā gadījumā mēs to izveidosim ar nosaukumu . Tā kā šis lietotājs nedarbojas ekrānā vai nemaina iestatījumus, paroli nevar mainīt.

Ja atstājat noklusējumu, varat pieteikties ar šo lietotāju ar Remote Desktop utt., Tāpēc, lūdzu, noņemiet no grupas Users .

Koplietojamas mapes izveide

Nav svarīgi, kur jūs to izveidojat. Tas ir tāpēc, ka citiem serveriem nerūp fiziskās mapes atrašanās vieta. Šajā gadījumā mēs izveidosim mapi, kas nosaukta tieši zem SharedFolder C diska, un kopīgosim to.

Atveriet rekvizītus un konfigurējiet koplietošanas iestatījumus.

Koplietojamās mapes nosaukumam jābūt SharedFolder . Šis nosaukums būs redzams citiem serveriem. Pievienojiet SharedUser atļaujas.

Everyone Dzēst esošo .

Apstipriniet ar atļauju "Mainīt".

Tā kā mums ir tikai pievienotas atļaujas, kurām var piekļūt no ārpuses, mēs to iestatīsim iekšēji SharedUser , lai varētu darboties šajā mapē.

Apstipriniet ar atļauju "Mainīt".

Izveidojiet failu, lai pārbaudītu darbību. Šajā programmā kodējums tiek apstrādāts UFT-8, tāpēc, lūdzu, saglabājiet to UTF-8.

Tas ir labi, ja varat piekļūt pārlūkprogrammā Explorer no \\<サーバー名>\ cita datora, pieteiktiesSharedUser ar , un skatīt failu.

Programmas izveide failu lasīšanai un rakstīšanai no koplietojamas mapes no ASP.NET Core lietojumprogrammas

Mr./Ms. darbība ir noklikšķināt uz pogas.

  • Failu ielāde koplietojamā mapē un to parādīšana ekrānā
  • Jauna faila rakstīšana koplietojamā mapē

process.

Razor Pages un MVC kods ir piemēri tam, bet programma, kas piekļūst koplietotajai mapei, abiem ir vienāda. Tas pats attiecas uz tīmekļa API. Ja kas, tam vajadzētu darboties arī klienta programmā.

Process, kas izveido savienojumu ar tīklu noteikta procesa laikā

Izveidojiet tālāk norādīto kodu jebkurā sava projekta vietā. Klases nosaukums ir SharedFolderAccessor , bet nosaukums ir patvaļīgs. SharedFolderAccessor Koplietojamai mapei var piekļūt, līdz izveidojat Dispose instanci. using ļauj norādīt laikposmu, kurā piekļuvei var piekļūt skaidrā tvērumā.

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

Tā kā tas izmanto Win32 API un WNetAddConnection2 WNetCancelConnection2 , tas darbojas tikai Windows vidē. Man pagaidām ir komentārs, bet, ja vēlaties uzzināt vairāk, lūdzu, meklējiet to internetā. Papildus koplietojamām mapēm varat veikt arī darbības, lai piekļūtu tīkla resursiem.

Tas ir viegli lietojams, un, ja rakstāt sekojošo, using tvēruma laikā varat piekļūt koplietotajai mapei.

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

Tomēr patiesībā WNetCancelConnection2 savienojums netiek nekavējoties atvienots zvanīšanas laikā , tāpēc using jūs varat piekļūt koplietotajai mapei pat pēc tvēruma.

Pārbaudiet kodu, izmantojot SharedFolderAccessor

Tā kā piekļuves process koplietojamai mapei nav atkarīgs no sistēmas, mēs izveidojam kopīgu testēšanas metodi, kas lasa un raksta failus. Pazor Pages un MVC būtu jāsauc par vienu un to pašu.

Saturs ir process, kurā tiek rakstīts teksts, kas nodots argumentam koplietojamā mapē, tiek nolasīts koplietojamajā mapē jau esošais teksta fails un atgriezts teksts.

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

Skuvekļa lapas

Razor lapās mēs ievietojam pogu Index.cshtml, noklikšķiniet uz tā, palaižam testa kodu un parādām rezultātus ekrānā. Dažos gadījumos koplietojamā mape var nebūt pieejama, tāpēc tā ir iekļauta izmēģināšanas procesā.

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

Līdzīgi MVC Index.cshtml gadījumā tiek ievietota poga , un, noklikšķinot uz tās, tā izsauc koplietojamās mapes testa kodu.

Pārziņi/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>
@* ここまで追加 *@

Darbības apstiprinājums

Atkļūdojiet un pārbaudiet, vai varat veiksmīgi piekļūt koplietojamai mapei.

Lietojumprogrammu servera izveide

Tā kā mēs esam apstiprinājuši, ka koplietotajai mapei var piekļūt, palaižot programmu, nākamais solis nav nepieciešams. Ja vēlaties pārbaudīt operāciju IIS serverī, varat to izdarīt, veicot tālāk norādītās darbības.

No šejienes tas ir papildinājums, tāpēc es to nepaskaidrošu pārāk detalizēti, bet galvenokārt izskaidrošu attēlu.

IIS instalēšana

Instalējiet to pēc noklusējuma no servera pārvaldnieka. Es neiedziļināšos procedūras detaļās.

Papildu funkcijas nav nepieciešamas.

Šobrīd nav nepieciešami papildu IIS pakalpojumi.

ASP.NET Core Runtime hostinga paketes instalēšana

Tā kā mēs izmantojam ASP.NET Core 8, mums attiecīgi jāinstalē izpildlaiks. Lejupielādējiet to no šī URL:

Lai palaistu ASP.NET Core IIS, jums ir nepieciešams kaut kas, ko sauc par "Hostinga paketi". Lejupielādējiet "Hostinga paketi" no ASP.NET Core Runtime.

Pēc lejupielādes palaidiet to serverī.

Izpildiet vedni, lai to instalētu.

Programmas publicēšana

Izvadiet programmu, kuru vēlaties izvietot IIS kā failu no Visual Studio.

Modificējiet to operētājsistēmai Windows.

Publicējiet, kad esat pabeidzis.

Noklikšķinot uz mērķa atrašanās vietas, varat atvērt mapi, kurā atrodas publicētais fails.

Jums tie visi nav jāņem līdzi, bet, ja neesat pārliecināts, varat tos visus paņemt pagaidām. Šajā brīdī viss, kas jums jādara, ir pārliecināties, vai fails pastāv.

Tīmekļa lietojumprogrammu izveide un izvietošana

Programmā Windows Administratīvie rīki atveriet interneta informācijas pakalpojumu (IIS) pārvaldnieku.

Mēs izveidosim vietni, bet šoreiz mēs izmantosim "Noklusējuma vietni", kas tur ir no paša sākuma.

Kad ir atlasīta opcija Noklusējuma vietne, noklikšķiniet uz Explorer, lai atvērtu mapi. Nokopējiet publicēto programmu šeit. Sākotnējo failu var izdzēst.

Atveriet lapu no IIS saites un pārbaudiet, vai tiek parādīts ekrāns. Vispirms varat atvērt tīmekļa pārlūkprogrammu un tieši ievadīt vietrādi URL.

Darbības apstiprinājums

Noklikšķiniet uz pogas, lai pārbaudītu, vai tā darbojas bez problēmām. Iepriekš minētajā gadījumā tam var piekļūt no tīmekļa servera, bet, tā kā tas ir tīmekļa serveris, vajadzētu būt iespējai to darbināt no citiem datoriem.