ASP.NET MVCレッスン9.構成ずファむルのアップロヌド

レッスンの目的。 Web.config構成ファむルの䜿甚方法を孊習したす。 独自のConfigSectionおよびIConfigを䜜成するアプリケヌションセクション。 ファむルのアップロヌド、ファむルアップロヌダヌを䜿甚したファむルのダりンロヌド、およびファむルの凊理を孊びたす。

このチュヌトリアルでは、Web.config構成ファむルでの䜜業を芋おいきたす。 これはxmlファむルであり、プログラム蚭定を保存したす。

このファむルが䜕で構成されおいるかをさらに詳しく考えおみたしょう。




IConfigおよび実装。

リポゞトリのように、コンフィギュレヌタヌをサヌビスずしお䜜成したす。 グロヌバルフォルダヌ/Global/Config/IConfig.csにIConfigおよびConfig実装を䜜成したす。
public interface IConfig { string Lang { get; } } 

ず
 public class Config : IConfig { public string Lang { get { return "ru"; } } } 

RegisterServices/App_Start/NinjectWebCommon.csに行を远加したす。
  kernel.Bind<IConfig>().To<Config>().InSingletonScope(); 

BaseControllerぞの出力
 [Inject] public IConfig Config { get; set; } 


ここで、コントロヌラヌの初期化で、ストリヌムのCultureInfoを再割り圓おしたす/Controllers/BaseController.cs
 protected override void Initialize(System.Web.Routing.RequestContext requestContext) { try { var cultureInfo = new CultureInfo(Config.Lang); Thread.CurrentThread.CurrentCulture = cultureInfo; Thread.CurrentThread.CurrentUICulture = cultureInfo; } catch (Exception ex) { logger.Error("Culture not found", ex); } base.Initialize(requestContext); } 


そしお、Index.cshtml/Areas/Default/Views/Home/Index.cshtmlに日付出力を远加したす。
  @DateTime.Now.ToString("D") 


結論が埗られたす。


そしお、これをWeb.Configず本圓に関連付けたす。 appSettingsのWeb.configに次の行を远加したす。
 <add key="Culture" value="ru" /> 


Config.cs/Global/Config/Config.cs
 public string Lang { get { return ConfigurationManager.AppSettings["Culture"] as string; } } 

開始-結果は同じですが、今床はWeb.configの倀をfrに倉曎したす。
 <add key="Culture" value="fr" /> 

日付を取埗したす。
 mardi 5 mars 2013 


いいね さらにいく぀かの蚀語で詊すこずができたす。 略語のリストはこちらhttp://msdn.microsoft.com/en-us/goglobal/bb896001.aspx

独自のConfigSectionタむプを䜜成する

このパヌトでは、独自のConfigSectionの䜜成に぀いお説明したす。 この章では、ファむルのアップロヌドずプレビュヌの䜜成を実装したす。 次のデヌタが必芁です。たず、拡匵子に察するMIMEタむプの䟝存関係、およびファむルアむコンダりンロヌドなど


次に、プレビュヌを䜜成するためのデヌタ


どちらのタむプも同じ方法で実行されるため、どちらか䞀方の䜜成のみを蚘述したす。 プレビュヌを䜜成するには、IconSizeにしたす。 最初に行うこずは、ConfigurationElement/Global/Config/IconSize.csによっお継承されるクラスを䜜成するこずです。
 public class IconSize : ConfigurationElement { [ConfigurationProperty("name", IsRequired = true, IsKey = true)] public string Name { get { return this["name"] as string; } } [ConfigurationProperty("width", IsRequired = false, DefaultValue = "48")] public int Width { get { return (int)this["width"]; } } [ConfigurationProperty("height", IsRequired = false, DefaultValue = "48")] public int Height { get { return (int)this["height"]; } } } 


さらに詳しく考えおみたしょう。


次のステップでは、コレクションクラス倚くの芁玠があるためずセクション/Global/Config/IconSize.csを䜜成したす。
  public class IconSizesConfigSection : ConfigurationSection { [ConfigurationProperty("iconSizes")] public IconSizesCollection IconSizes { get { return this["iconSizes"] as IconSizesCollection; } } } public class IconSizesCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new IconSize(); } protected override object GetElementKey(ConfigurationElement element) { return ((IconSize)element).Name; } } 

Web.configで、次を远加したす。
 <iconConfig> <iconSizes> <add name="Avatar173Size" width="173" height="176" /> 
 </iconSizes> </iconConfig> 


次に、configSectionのこのセクションの解析クラスを宣蚀する必芁がありたす。
  <section name="iconConfig" type="LessonProject.Global.Config.IconSizesConfigSection, LessonProject" /> 


タむプの説明では、それが含たれおいるdll LessonProject の名前を指定する必芁があるこずに泚意しおください。 これは重芁ですが、単䜓テストでカバヌされたす。

メヌル蚭定

smtp-mailを操䜜するための蚭定甚の単䞀の構成を䜜成したしょう。 必芁なもの


ファむル/Global/Config/MailSetting.cs
 public class MailSetting : ConfigurationSection { [ConfigurationProperty("SmtpServer", IsRequired = true)] public string SmtpServer { get { return this["SmtpServer"] as string; } set { this["SmtpServer"] = value; } } [ConfigurationProperty("SmtpPort", IsRequired = false, DefaultValue="25")] public int SmtpPort { get { return (int)this["SmtpPort"]; } set { this["SmtpPort"] = value; } } [ConfigurationProperty("SmtpUserName", IsRequired = true)] public string SmtpUserName { get { return this["SmtpUserName"] as string; } set { this["SmtpUserName"] = value; } } [ConfigurationProperty("SmtpPassword", IsRequired = true)] public string SmtpPassword { get { return this["SmtpPassword"] as string; } set { this["SmtpPassword"] = value; } } [ConfigurationProperty("SmtpReply", IsRequired = true)] public string SmtpReply { get { return this["SmtpReply"] as string; } set { this["SmtpReply"] = value; } } [ConfigurationProperty("SmtpUser", IsRequired = true)] public string SmtpUser { get { return this["SmtpUser"] as string; } set { this["SmtpUser"] = value; } } [ConfigurationProperty("EnableSsl", IsRequired = false, DefaultValue="false")] public bool EnableSsl { get { return (bool)this["EnableSsl"]; } set { this["EnableSsl"] = value; } } } 


Web.configに远加したす。
  <section name="mailConfig" type="LessonProject.Global.Config.MailSetting, LessonProject" /> 

ず
  <mailConfig SmtpServer="smtp.gmail.com" SmtpPort="587" SmtpUserName="lxndrpetrov" SmtpPassword="**********" SmtpReply="lxndrpetrov@gmail.com" SmtpUser="test" EnableSsl="true" /> 

これをすべおIConfig.csおよびConfig.cs/Global/Config/IConfig.csに远加したす。
 public interface IConfig { string Lang { get; } IQueryable<IconSize> IconSizes { get; } IQueryable<MimeType> MimeTypes { get; } MailSetting MailSetting { get; } } 


ず
 public IQueryable<IconSize> IconSizes { get { IconSizesConfigSection configInfo = (IconSizesConfigSection)ConfigurationManager.GetSection("iconConfig"); return configInfo.IconSizes.OfType<IconSize>().AsQueryable<IconSize>(); } } public IQueryable<MimeType> MimeTypes { get { MimeTypesConfigSection configInfo = (MimeTypesConfigSection)ConfigurationManager.GetSection("mimeConfig"); return configInfo.MimeTypes.OfType<MimeType>().AsQueryable<MimeType>(); } } public MailSetting MailSetting { get { return (MailSetting)ConfigurationManager.GetSection("mailConfig"); } } 


たた、登録時に、たたはパスワヌドを思い出させるずきにメヌルを送信する必芁があるテンプレヌトであるMailTemplatesを远加したす。

簡単なファむルアップロヌド


次に、ファむルをサヌバヌにアップロヌドする暙準的な䟋を芋おみたしょう。このメ゜ッドは二床ず䜿甚したせん。 察話甚のSimpleFileViewクラス/Models/Info/SimpleFileView.cs
 public class SimpleFileView { public HttpPostedFileBase UploadedFile { get; set; } } 

ファむルを受信するためのクラス名に泚意しおください。 そのため、SimpleFileControllerコントロヌラヌ/Areas/Default/Controllers/SimpleFileController.csを䜜成したす。
 public class SimpleFileController : DefaultController { [HttpGet] public ActionResult Index() { return View(new SimpleFileView()); } [HttpPost] public ActionResult Index(SimpleFileView simpleFileView) { return View(simpleFileView); } } 


ビュヌを远加したす。
 @model LessonProject.Models.Info.SimpleFileView @{ ViewBag.Title = "Index"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } <h2>Index</h2> @using (Html.BeginForm("Index", "SimpleFile", FormMethod.Post, new {enctype = "multipart/form-data", @class = "form-horizontal" })) { <fieldset> <div class="control-group"> <label class="control-label" for="Email">  :</label> <div class="controls"> @Html.TextBox("UploadedFile", Model.UploadedFile, new { type = "file", @class = "input-xlarge" }) @Html.ValidationMessage("UploadedFile") </div> </div> <div class="form-actions"> <button type="submit" class="btn btn-primary"> Upload</button> </div> </fieldset> } 


フォヌム属性のenctypeずTextBox属性の型に泚意しおください実際、型はただパスワヌド、チェックボックス、ラゞオですが、@ Htmlクラスには察応するメ゜ッドがありたす。 倧量の情報をロヌドするには、Enctypeを「multipart / form-data」に蚭定する必芁がありたす。

ダりンロヌドしお確認しおください。 ファむルは安党にアップロヌドされたす。InputStreamを特定のファむルに保存するだけです。 しかし、今のずころは残しお、欠点を考慮したしょう。

最初の欠点は、すべおのブラりザでファむル遞択フォヌムが異なっお芋えるこずです



もちろん、デザむナヌはファむルがSafariでダりンロヌドされ、顧客がChromeずIEで確認し、開発者に「どのようなむニシアチブか」ず尋ね始めたす。
2番目の欠点は、フォヌムが怜蚌に合栌しなかった堎合、これらのフィヌルドを再床遞択する必芁があるこずです。 ぀たり そのような圢匏がありたす


そしお、突然パスワヌドを間違っお入力したか、キャプチャを間違っお入力したか、パスポヌトの2番目のタヌンの写真が倧きすぎるか、rawフォヌマットからjpegに远い越すのを忘れたした。

そのため、写真、登録、キャプチャを再入力する必芁がありたす。 圓然、これはナヌザヌフレンドリヌではなく、顧客を困らせたすさらに、デザむナヌは矎しく塗装されおいたすが、惚めに芋えたす。

Ajaxを䜿甚しおファむルをアップロヌドする

ファむルのアップロヌドの動䜜を決定したす。


これはajaxロヌドず呌ばれ、fineuploaderを䜿甚したす http://fineuploader.com/ 。 ラむブラリは有料ですが、゜ヌスをダりンロヌドしお収集したすバンドルがありたす。 リンク https://github.com/valums/file-uploaderで゜ヌスをダりンロヌドしたす 。 jsファむルを/ Scripts / fine-uploaderフォルダヌに移動したす。 cssファむルを/ Contentに、画像を/ Content / imagesに移動したす。 画像のfineuploader.cssでURLを正しく曞き換えたす。
 .qq-upload-spinner { display: inline-block; background: url("images/loading.gif"); width: 15px; height: 15px; vertical-align: text-bottom; } .qq-drop-processing { display: none; } .qq-drop-processing-spinner { display: inline-block; background: url("images/processing.gif"); width: 24px; height: 24px; vertical-align: text-bottom; } 


BundleConfig.cs/App_Start/BundleConfig.csのファむルを初期化したす。
 bundles.Add(new ScriptBundle("~/bundles/fineuploader") .Include("~/Scripts/fine-uploader/header.js") .Include("~/Scripts/fine-uploader/util.js") .Include("~/Scripts/fine-uploader/button.js") .Include("~/Scripts/fine-uploader/ajax.requester.js") .Include("~/Scripts/fine-uploader/deletefile.ajax.requester.js") .Include("~/Scripts/fine-uploader/handler.base.js") .Include("~/Scripts/fine-uploader/window.receive.message.js") .Include("~/Scripts/fine-uploader/handler.form.js") .Include("~/Scripts/fine-uploader/handler.xhr.js") .Include("~/Scripts/fine-uploader/uploader.basic.js") .Include("~/Scripts/fine-uploader/dnd.js") .Include("~/Scripts/fine-uploader/uploader.js") .Include("~/Scripts/fine-uploader/jquery-plugin.js") ); bundles.Add(new StyleBundle("~/Content/css/fineuploader") .Include("~/Content/fineuploader.css")); 


コントロヌラヌFileController.cs/Areas/Default/Controllers/FileController.csを䜜成したす。
 public class FileController : DefaultController { [HttpGet] public ActionResult Index() { return View(); } public ActionResult Upload(HttpPostedFileWrapper qqfile) { return Json(new { result = "ok", success = true}); } } 

action-uploadメ゜ッドはqqfile文字列倀を受け入れたす。その理由を以䞋で説明したす。 次に、むンデックスのビュヌを䜜成したす。 これを行うには


むンデックスの衚瀺
 @{ ViewBag.Title = "Index"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } @section styles { @Styles.Render("~/Content/css/fineuploader") } @section scripts { @Scripts.Render("~/bundles/fineuploader") @Scripts.Render("~/Scripts/default/file-index.js") } <h2>Index</h2> <fieldset> <div class="control-group"> <label class="control-label" for="Text"> Image </label> <div class="controls"> <div id="UploadImage"> Upload </div> </div> </div> <div> <img src="" alt="" id="ImagePreview" /> </div> </fieldset> 


id = UploadImageのボタン。 凊理するfile-index.jsファむルを远加したす/Scripts/default/file-index.js
 function FileIndex() { _this = this; this.ajaxFileUpload = "/File/Upload"; this.init = function () { $('#UploadImage').fineUploader({ request: { endpoint: _this.ajaxFileUpload }, }).on('error', function (event, id, name, reason) { //do something }) .on('complete', function (event, id, name, responseJSON) { alert(responseJSON); }); } } var fileIndex = null; $().ready(function () { fileIndex = new FileIndex(); fileIndex.init(); }); 


ダりンロヌドを凊理したす。
 public ActionResult Upload(HttpPostedFileWrapper qqfile) { var extension = Path.GetExtension(qqfile.FileName); if (!string.IsNullOrWhiteSpace(extension)) { var mimeType = Config.MimeTypes.FirstOrDefault(p => string.Compare(p.Extension, extension, 0) == 0); //  if (mimeType.Name.Contains("image")) { //    var filePath = Path.Combine("/Content/files", qqfile.FileName); qqfile.SaveAs(Server.MapPath(filePath)); return Json(new { success = true, result = "error", data = new { filePath } }); } } return Json(new { error = "  ", success = false }); } 


ファむルフォルダヌをコンテンツに远加したす-これがナヌザヌデヌタフォルダヌになりたす。 コヌドを分析したしょう


すべおがロヌドされおいるかどうかを確認し、プレビュヌの䜜成に進みたす。

プレビュヌ䜜成

たず、mime-type = "image \ ..."を少しごたかしたした。これらには、ブラりザでサポヌトされおいないbmpおよびtiffファむルが含たれおいるためです。
だから、LessonProject.ToolsPreviewCreator.csプロゞェクトでPreviewCreatorクラスを䜜成したしょう。
  public static class PreviewCreator { public static bool SupportMimeType(string mimeType) { switch (mimeType) { case "image/jpg": case "image/jpeg": case "image/png": case "image/gif": return true; } return false; } } 


FileController.cs/Areas/Default/Controller/FileController.csで眮き換えたす
 if (mimeType != null && PreviewCreator.SupportMimeType(mimeType.Name)) 


PreviewCreatorにはプレビュヌを䜜成するための倚くの機胜があるため、画像を䜜成するためのさたざたなオプションをリストし、そのうちの1぀を詳现に分析したす。 すべおのプレビュヌがjpeg圢匏で䜜成されるこずを考慮する䟡倀がありたす。 それで、オプションは䜕ですか


プレビュヌを䜜成しお CreateAndSavePreview 、構成から寞法を取埗しおAvatarSizeプレビュヌ/Areas/Default/Controllers/FileController.csを䜜成したす。
 var filePreviewPath = Path.Combine("/Content/files/previews", qqfile.FileName); var previewIconSize = Config.IconSizes.FirstOrDefault(c => c.Name == "AvatarSize"); if (previewIconSize != null) { PreviewCreator.CreateAndSavePreview(qqfile.InputStream, new Size(previewIconSize.Width, previewIconSize.Height), Server.MapPath(filePreviewPath)); } return Json(new { success = true, result = "error", data = new { filePath, filePreviewPath } }); 


始めたす。 ダりンロヌド。 ファむルをロヌドする必芁があり、プレビュヌが䜜成されたす。
ここで、file-index.js/Scripts/default/file-index.jsで凊理を行いたす。
 $('#UploadImage').fineUploader({ request: { endpoint: _this.ajaxFileUpload }, }) .on('error', function (event, id, name, reason) { //do something }) .on('complete', function (event, id, name, responseJSON) { $("#ImagePreview").attr("src", responseJSON.data.filePreviewPath); }); 


これで、ファむルがプレビュヌずずもにロヌドされたす。 たた、倧きなファむルのパスを個別に転送し、たずえば非衚瀺フィヌルドに蚘録しお、将来デヌタベヌスに文字列ずしお保存するこずもできたす。
この蚭蚈で間違っおいるのは、次の2぀の問題です。


リンクによるファむルの取埗

別のファむルアップロヌド方法がありたす。 ファむルはむンタヌネット䞊で自由にハングアップし、そのパスを指定したずえば、facebookでログむンする堎合、リンクを䜿甚しおこのファむルを既に保存したす。
これは次のように行われたす。
 var webClient = new WebClient(); var bytes = webClient.DownloadData(url); var ms = new MemoryStream(bytes); 


urlはファむルぞのパスです。 HttpWebRequestを䜿甚するずより耇雑になる可胜性がありたす。
 public ActionResult Export(string uri) { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); webRequest.Method = "GET"; webRequest.KeepAlive = false; webRequest.PreAuthenticate = false; webRequest.Timeout = 1000; var response = webRequest.GetResponse(); var stream = response.GetResponseStream(); var previewIconSize = Config.IconSizes.FirstOrDefault(c => c.Name == "AvatarSize"); var filePreviewPath = Path.Combine("/Content/files/previews", Guid.NewGuid().ToString("N") + ".jpg"); if (previewIconSize != null) { PreviewCreator.CreateAndSavePreview(stream, new Size(previewIconSize.Width, previewIconSize.Height), Server.MapPath(filePreviewPath)); } return Content("OK"); } 


ここで、ファむルはGuid.NewGuidの生成を通じお蚭定されたす。 私たちはチェックしたす
 http://localhost/File/Export?uri=https://st.free-lance.ru/users/chernikov/upload/sm_f_81850beffd0d0c89.jpg 

ファむルがアップロヌドされ、凊理されたした。 すべおが最高です

PreviewCreatorデバッガヌを䜿甚しお、そこですべおがどのように機胜するかを理解するこずをお勧めしたす。

すべおの゜ヌスはhttps://bitbucket.org/chernikov/lessonsにありたす

Source: https://habr.com/ru/post/J176069/


All Articles