دسترسی به پوشه های مشترک در سرورهای دیگر از یک برنامه هسته ASP.NET (نسخه برنامه متصل به شبکه)

صفحه به روز شده :
تاریخ ایجاد صفحه :

محیط تایید عملیات

ویژوال استودیو
  • ویژوال استودیو 2022
ASP.NET هسته
  • 8 (Razor Pages، MVC)
ویندوز سرور
  • 2022 (ASP.NET هسته سیستم مورد نیاز)
  • 2019 (سرور استقرار پوشه مشترک)
مؤسسه
  • 10.0

محیط عملیاتی

ما ان را در همه موارد ازمایش نکرده ایم، اما باید به طور کلی تحت شرایط زیر کار کند:

ویژوال استودیو
  • هر چیزی که بتواند یک پروژه ASP.NET را توسعه دهد
ASP.NET هسته
  • هر نسخه (MVC، Razor Pages، API)
ویندوز سرور
  • ویندوز سرور 2008 یا بالاتر
مؤسسه
  • 7.0 یا بعد از ان

پیششرط

  • ASP.NET برنامه های Core برای اجرا بر روی IIS در نظر گرفته شده اند.
  • از انجا که از API های ویندوز برای احراز هویت استفاده می کند، در غیر ویندوز کار نمی کند.

محیط

این در محیط زیر تایید شده است.

هدف از استفاده از رایانه های شخصی و سرور
ویندوز 11 (محلی) محیطی برای توسعه برنامه ها
SV2022 تست محیطی که IIS و ASP.NET Core را اجرا می کند. دسترسی به پوشه به اشتراک گذاشته شده SV2019Test از اینجا
SV2019 تست کارگزارهایی با پوشههای مشترک

علاوه بر این، تنظیمات مختلف به شرح زیر است.

پارامتر نام مقدار
دسترسی به نام کاربری اشتراک کاربر
نام پوشه مشترک پوشه اشتراکی

ایجاد یک سرور پوشه مشترک

ایجاد یک کاربر

ایجاد یک کاربر برای دسترسی به پوشه مشترک. در این مورد، ما یک حساب محلی ایجاد خواهیم کرد، اما اگر شما با سرورها و حساب ها در یک دامنه مانند Active Directory برخورد می کنید، می توانید از ان نیز استفاده کنید.

فرایند ایجاد یک کاربر فراتر از محدوده این نکات است، بنابراین ما به جزئیات زیادی نخواهیم رفت.

SharedUser در این مورد، ما ان را با نام ایجاد خواهیم کرد. از انجا که این کاربر صفحه نمایش را اجرا نمی کند یا تنظیمات را تغییر نمی دهد، رمز عبور را نمی توان تغییر داد.

اگر به طور پیش فرض را ترک کنید، می توانید با این کاربر با Remote Desktop و غیره وارد شوید، بنابراین لطفا از گروه Users حذف کنید.

ایجاد یک پوشه به اشتراک گذاشته شده

مهم نیست که کجا ان را ایجاد می کنید. این به این دلیل است که سرورهای دیگر در مورد محل پوشه فیزیکی اهمیتی نمی دهند. در این مورد، ما یک پوشه به طور مستقیم در زیر SharedFolder درایو C ایجاد می کنیم و ان را به اشتراک می گذاریم.

ویژگی ها را باز کنید و تنظیمات اشتراک گذاری را پیکربندی کنید.

نام پوشه به اشتراک گذاشته شده باید SharedFolder باشد. این نام برای سرورهای دیگر قابل مشاهده خواهد بود. مجوزها را اضافه کنید SharedUser .

Everyone حذف موجود.

با اجازه "تغییر" تایید کنید.

از انجا که ما فقط مجوزهایی را اضافه کرده ایم که از خارج قابل دسترسی هستند، ما ان را در داخل تنظیم می کنیم تا SharedUser بتوانیم در این پوشه کار کنیم.

با اجازه "تغییر" تایید کنید.

یک فایل برای بررسی عملیات ایجاد کنید. در این برنامه، رمزگذاری در UFT-8 پردازش می شود، بنابراین لطفا ان را در UTF-8 ذخیره کنید.

خوب است اگر شما می توانید در اکسپلورر از \\<サーバー名>\ یک کامپیوتر دیگر دسترسی داشته باشید، با ان وارد شویدSharedUser و فایل را مشاهده کنید.

ایجاد یک برنامه برای خواندن و نوشتن فایل ها از یک پوشه مشترک از یک برنامه هسته ASP.NET

عملیات اقای / خانم این است که روی دکمه کلیک کنید.

  • بارگذاری پرونده ها در یک پوشه مشترک و نمایش انها بر روی صفحه نمایش
  • نوشتن یک پرونده جدید در یک پوشه مشترک

فرایند.

Razor Pages و کد MVC نمونه هایی از این هستند، اما برنامه ای که به پوشه مشترک دسترسی دارد برای هر دو یکسان است. همین امر در مورد WEB APIs نیز صادق است. اگر چیزی باشد، باید در برنامه مشتری نیز کار کند.

فرایندی که برای مدت زمان یک فرایند خاص به یک شبکه متصل می شود

کد زیر را در هر نقطه از پروژه خود ایجاد کنید. نام کلاس است SharedFolderAccessor ، اما نام خودسرانه است. SharedFolderAccessor شما می توانید به پوشه مشترک دسترسی داشته باشید تا زمانی که یک Dispose نمونه از . using اجازه می دهد تا شما را به مشخص مدت زمان که در طی ان دسترسی را می توان در یک محدوده صریح قابل دسترسی است.

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

از انجا که از API های Win32 استفاده می کند و WNetAddConnection2 WNetCancelConnection2 فقط در محیط ویندوز کار می کند. من یک نظر در حال حاضر، اما اگر شما می خواهید به دانستن بیشتر، لطفا ان را در اینترنت نگاه کنید. علاوه بر پوشه های مشترک، می توانید عملیات دسترسی به منابع شبکه را نیز انجام دهید.

استفاده از ان اسان است و اگر متن زیر را بنویسید، می توانید در طول دامنه به پوشه مشترک دسترسی داشته باشید using .

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

با این حال، در واقع WNetCancelConnection2 ، اتصال بلافاصله در زمان تماس قطع نمی شود، بنابراین using شما می توانید حتی پس از دامنه به پوشه مشترک دسترسی داشته باشید.

کد تست با استفاده از SharedFolderAccessor

از انجا که فرایند دسترسی به پوشه مشترک به چارچوب بستگی ندارد، ما یک روش مشترک برای ازمایش ایجاد می کنیم که فایل ها را می خواند و می نویسد. صفحات Pazor و MVC باید یکسان نامیده شوند.

محتوا فرایندی است که متن منتقل شده به استدلال را به پوشه مشترک می نویسد، فایل متنی را که قبلا در پوشه مشترک است می خواند و متن را باز می گرداند.

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

صفحه تیغ

در Razor Pages، ما یک دکمه را در Index.cshtml قرار می دهیم، روی ان کلیک می کنیم، کد تست را اجرا می کنیم و نتایج را بر روی صفحه نمایش می دهیم. در برخی موارد، پوشه مشترک ممکن است در دسترس نباشد، بنابراین در یک try-catch محصور شده است.

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

فارسی

@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

به طور مشابه، در مورد MVC، Index.cshtml یک دکمه در ان قرار می گیرد و هنگامی که کلیک می شود، کد ازمایشی پوشه مشترک را فراخوانی می کند.

کنترل کننده ها / 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();
    }

    // 省略
  }
}

فارسی

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

تایید عملیات

اشکال زدایی و تایید کنید که می توانید با موفقیت به پوشه مشترک دسترسی داشته باشید.

ایجاد یک Application Server

از انجا که ما تایید کرده ایم که پوشه مشترک با اجرای برنامه قابل دسترسی است، گام بعدی غیر ضروری است. اگر می خواهید عملیات را در سرور IIS بررسی کنید، می توانید این کار را با دنبال کردن مراحل زیر انجام دهید.

از اینجا، این یک مکمل است، بنابراین من ان را با جزئیات بیش از حد توضیح نمی دهم، اما عمدتا تصویر را توضیح می دهم.

نصب IIS

ان را به طور پیش فرض از مدیر سرور نصب کنید. من وارد جزئیات این عمل نمی شوم.

هیچ ویژگی اضافی مورد نیاز است.

در حال حاضر نیازی به خدمات IIS اضافی نیست.

ASP.NET هسته Runtime میزبانی بسته نرم افزاری نصب و راه اندازی

از انجا که ما از core 8 ASP.NET استفاده می کنیم، باید زمان اجرا را بر این اساس نصب کنیم. ان را از URL زیر دانلود کنید:

به منظور اجرای هسته ASP.NET در IIS، شما نیاز به چیزی به نام "بسته نرم افزاری میزبانی" دارید. "بسته نرم افزاری میزبانی" را از ASP.NET Core Runtime دانلود کنید.

پس از دانلود، ان را بر روی سرور اجرا کنید.

جادوگر را دنبال کنید تا ان را نصب کنید.

برنامه خود را منتشر کنید

برنامه ای را که می خواهید به عنوان یک فایل از ویژوال استودیو به IIS منتقل کنید، خروجی دهید.

ان را برای ویندوز تغییر دهید.

وقتی کارتان تمام شد منتشر کنید.

اگر روی مکان هدف کلیک کنید، می توانید پوشه ای را که فایل منتشر شده در ان قرار دارد باز کنید.

شما مجبور نیستید همه انها را بیاورید، اما اگر مطمئن نیستید، می توانید همه انها را در حال حاضر بگیرید. در این مرحله، تنها کاری که باید انجام دهید این است که مطمئن شوید که فایل وجود دارد.

ایجاد و استقرار برنامه های وب

از ابزارهای اداری ویندوز، مدیر خدمات اطلاعات اینترنت باز (IIS).

ما یک سایت ایجاد خواهیم کرد، اما این بار از "وب سایت پیش فرض" استفاده خواهیم کرد که از ابتدا وجود دارد.

با انتخاب وب سایت پیش فرض، روی Explorer کلیک کنید تا پوشه باز شود. برنامه منتشر شده را اینجا کپی کنید. شما می توانید فایل اصلی را حذف کنید.

صفحه را از لینک IIS باز کنید و ببینید ایا صفحه نمایش ظاهر می شود. شما می توانید ابتدا یک مرورگر وب را باز کنید و URL را مستقیما وارد کنید.

تایید عملیات

روی دکمه کلیک کنید تا مطمئن شوید که بدون هیچ مشکلی کار می کند. در بالا، از داخل وب سرور قابل دسترسی است، اما از انجا که یک وب سرور است، باید امکان اجرای ان از سایر رایانه های شخصی وجود داشته باشد.