ASP.NET Core 응용 프로그램에서 다른 서버의 공유 폴더에 액세스(네트워크 연결 프로그램 버전)
동작 검증 환경
- 비주얼 스튜디오
-
- 비주얼 스튜디오 2022
- ASP.NET 코어
-
- 8(Razor 페이지, MVC)8 (Razor Pages, MVC)
- 윈도우 서버
-
- 2022(ASP.NET 핵심 시스템 요구 사항)
- 2019년(공유 폴더 배포 서버)
- 증권 시세 표시기
-
- 10.0
운영 환경
모든 경우에 테스트하지는 않았지만 일반적으로 다음 조건에서 작동해야 합니다.
- 비주얼 스튜디오
-
- ASP.NET Core 프로젝트를 개발할 수 있는 모든 것
- ASP.NET 코어
-
- 모든 버전(MVC, Razor Pages, API)
- 윈도우 서버
-
- Windows Server 2008 이상
- 증권 시세 표시기
-
- 7.0 이상
전제 조건
- ASP.NET Core 애플리케이션은 IIS에서 실행하기 위한 것입니다.
- 인증에 Windows API를 사용하기 때문에 Windows가 아닌 경우에는 작동하지 않습니다.
환경
다음 환경에서 확인됩니다.
PC 및 서버의 | 사용 목적 |
---|---|
Windows 11(로컬) | 프로그램 개발을 위한 환경입니다. |
SV2022테스트 | IIS 및 ASP.NET Core를 실행하는 환경입니다. 여기에서 SV2019Test 공유 폴더에 액세스합니다. |
SV2019테스트 | 공유 폴더가 있는 서버 |
또한 다양한 설정은 다음과 같습니다.
매개 변수 이름 | 값 |
---|---|
액세스 사용자 이름 | 공유 사용자 |
공유 폴더 이름 | 공유 폴더 |
공유 폴더 서버 구축
사용자 만들기
common 폴더에 액세스할 사용자를 만듭니다. 이 경우 로컬 계정을 만들지만 Active Directory와 같은 도메인의 서버 및 계정을 처리하는 경우에도 사용할 수 있습니다.
사용자를 만드는 과정은 이 팁의 범위를 벗어나므로 너무 자세히 설명하지 않겠습니다.
SharedUser
이 경우 이름으로 만듭니다.
이 사용자는 화면을 조작하거나 설정을 변경하지 않으므로 암호를 변경할 수 없습니다.
기본값을 그대로 두면 Remote Desktop 등으로 이 사용자로 로그인할 수 있으므로 그룹 Users
에서 제거하십시오.
공유 폴더 만들기
어디서 만드는지는 중요하지 않습니다. 이는 다른 서버가 실제 폴더의 위치를 신경 쓰지 않기 때문입니다.
이 경우 C 드라이브 바로 아래에 SharedFolder
이름이 지정된 폴더를 만들어 공유합니다.
속성을 열고 공유 설정을 구성합니다.
공유 폴더의 이름은 이어야 합니다 SharedFolder
. 이 이름은 다른 서버에서 볼 수 있습니다.
권한을 추가합니다 SharedUser
.
Everyone
기존 .
"변경" 권한으로 확인합니다.
외부에서 접근할 수 있는 권한만 추가했기 때문에 이 폴더에서 동작할 수 있도록 내부적으로 SharedUser
설정하겠습니다.
"변경" 권한으로 확인합니다.
작업을 확인할 파일을 만듭니다. 이 프로그램에서는 인코딩이 UFT-8로 처리되므로 UTF-8로 저장하십시오.
다른 PC에서 \\<サーバー名>\
Explorer에 접속하여 로 로그인SharedUser
하여 파일을 볼 수 있으면 OK입니다.
ASP.NET Core 응용 프로그램에서 공유 폴더의 파일을 읽고 쓰는 프로그램 만들기
Mr./Ms. 조작은 버튼을 클릭하는 것입니다.
- 공유 폴더에 파일을 로드하고 화면에 표시
- 공유 폴더에 새 파일 쓰기
프로세스.
Razor Pages 및 MVC 코드가 이에 대한 예이지만 공유 폴더에 액세스하는 프로그램은 둘 다 동일합니다. 웹 API의 경우에도 마찬가지입니다. 어쨌든 클라이언트 프로그램에서도 작동해야 합니다.
특정 프로세스 기간 동안 네트워크에 연결하는 프로세스입니다
프로젝트의 아무 곳에서나 다음 코드를 만듭니다. 클래스 이름은 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">共有フォルダのあるサーバーを「\\<サーバー名>」形式で指定します。</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,
}
}
Win32 API를 WNetAddConnection2
WNetCancelConnection2
사용하고 Windows 환경에서만 작동합니다.
우선 코멘트가 있습니다만, 더 알고 싶은 분은 인터넷에서 찾아보세요.
공유 폴더 외에도 네트워크 리소스에 액세스하는 작업을 수행할 수 있습니다.
사용하기 쉽고, 다음과 using
같이 작성하면 범위 내에서 공유 폴더에 액세스 할 수 있습니다.
using (new SharedFolderAccessor($@"\\{serverName}", credentials))
{
// この間は共有フォルダにアクセスできる
}
그러나 실제로는 WNetCancelConnection2
호출 타이밍에 즉시 연결이 끊어지지 않기 때문에 using
범위 이후에도 공유 폴더에 액세스 할 수 있습니다.
SharedFolderAccessor를 사용하여 코드 테스트
공유 폴더에 액세스하는 프로세스는 프레임워크에 의존하지 않기 때문에 파일을 읽고 쓰는 일반적인 테스트 방법을 만듭니다. Pazor Pages와 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 페이지
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();
}
}
}
}
인덱스.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 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();
}
// 省略
}
}
인덱스.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>
@* ここまで追加 *@
작동 확인
디버그하고 공유 폴더에 성공적으로 액세스할 수 있는지 확인합니다.
응용 프로그램 서버 구축
프로그램을 실행하여 공유 폴더에 액세스할 수 있음을 확인했으므로 다음 단계는 필요하지 않습니다. IIS 서버에서 작업을 확인하려면 아래 단계에 따라 수행할 수 있습니다.
여기서부터는 보충이므로 너무 자세하게 설명하지 않고 주로 이미지를 설명합니다.
IIS 설치
Server Manager에서 기본적으로 설치합니다. 절차의 세부 사항은 다루지 않겠습니다.
추가 기능은 필요하지 않습니다.
현재로서는 추가 IIS 서비스가 필요하지 않습니다.
ASP.NET Core 런타임 호스팅 번들 설치
ASP.NET Core 8을 사용하고 있으므로 그에 따라 런타임을 설치해야 합니다. 다음 URL에서 다운로드하십시오.
IIS에서 ASP.NET Core를 실행하려면 "호스팅 번들"이라는 것이 필요합니다. ASP.NET Core 런타임에서 "호스팅 번들"을 다운로드합니다.
다운로드가 완료되면 서버에서 실행합니다.
마법사를 따라 설치합니다.
프로그램 게시
IIS에 배포할 프로그램을 Visual Studio에서 파일로 출력합니다.
Windows용으로 수정합니다.
완료되면 게시합니다.
대상 위치를 클릭하면 게시된 파일이 있는 폴더를 열 수 있습니다.
모두 가져갈 필요는 없지만 확실하지 않은 경우 지금은 모두 가져갈 수 있습니다. 이 시점에서 파일이 있는지 확인하기만 하면 됩니다.
웹 응용 프로그램 만들기 및 배포
Windows 관리 도구에서 IIS(인터넷 정보 서비스) 관리자를 엽니다.
사이트를 만들지만 이번에는 처음부터 거기에 있는 "기본 웹 사이트"를 사용합니다.
기본 웹 사이트를 선택한 상태에서 탐색기를 클릭하여 폴더를 엽니다. 여기에 게시된 프로그램을 복사합니다. 원본 파일을 삭제할 수 있습니다.
IIS 링크에서 페이지를 열고 화면이 나타나는지 확인합니다. 먼저 웹 브라우저를 열고 URL을 직접 입력할 수 있습니다.
작동 확인
버튼을 클릭하여 문제 없이 작동하는지 확인합니다. 위에서는 웹 서버 내에서 접속하지만, 웹 서버이기 때문에 다른 PC에서도 조작이 가능할 것입니다.