2017-11-17 10 views
0

私が作成した2つの独立した子モデルがあり、両方の子モデルを1つのビューで使用できるようにする親モデルを作成できます。両方のモデルを含む親ビューモデル

私が遭遇している問題は、親モデルが変数にアクセスしていないことを私に知らせる私のビューからエラーが出てくることです。 "MainPageModelに定義が含まれていません..."

これからの私の最終目標は、入力を使用して1つのモデルに画像をアップロードするフォームを持つことができるようにすることです。これにより、画像付きの簡単なプロファイルが作成されます。提出すると、プロフィールがどのように見えるかで、別のビューに移動します。

MODEL 1:

namespace Profile.Models 
{ 
    public class Profiler 
    { 
     public string FName { get; set; } 
     public string Address { get; set; } 
     public string BirthDate { get; set; } 
     public string PhoneNumber { get; set; } 
     public string Comments { get; set; } 
    } 
} 

モデル2:

namespace Profile.Models 
{ 
    public interface IFormFile 
    { 
     string ContentType { get; } 
     string ContentDisposition { get; } 
     IHeaderDictionary Headers { get; } 
     long Length { get; } 
     string Name { get; } 
     string FileName { get; } 
     Stream OpenReadStream(); 
     void CopyTo(Stream target); 
     Task CopyToAsync(Stream target, CancellationToken cancellationToken); 
    } 
} 

親モデル:

namespace Profile.Models 
{ 
    public class MainPageModel 
    { 
     public Profiler Profiler { get; set; } 
     public IFormFile IFormFile { get; set; } 

     public MainPageModel(Profiler Profiler) 
     { 
      Profiler = Profiler; 
     } 
    } 
} 

ビュー:

@model Profile.Models.MainPageModel 
@{ 
    ViewData["Title"] = "Profiler"; 
} 
<h2>Create your Profile using the form below</h2> 
<h3>On Submission, your profile will be created for you to see.</h3> 

<form asp-action="Profiler" > 
    <label asp-for="FName"></label> 
    <input asp-for="FName" /> <br /><br /> 
    <label asp-for="Address"></label> 
    <input asp-for="Address" /> <br /><br /> 
    <label asp-for="BirthDate"></label> 
    <input asp-for="BirthDate" /> <br /><br /> 
    <label asp-for="PhoneNumber"></label> 
    <input asp-for="PhoneNumber" /> <br /><br /> 
    <label asp-for="Comments"></label> 
    <input asp-for="Comments" /> <br /><br /> 
    <input type="submit" value="Submit" /> 
</form> 

<form method="post" enctype="multipart/form-data"> 
    <input type="file" name="files" multiple /> 
    <input type="submit" value="Upload" /> 
</form> 

にHomeController:

public IActionResult Profiler([Bind("FName,Address,BirthDate,PhoneNumber,Comments")] Profiler Profiles) 
    { 
     return View(new MainPageModel (Profiles)); 
    } 

答えて

1

、プロファイルの形式で名前を入力し、ファイルの入力名を変更するProfileプレフィックスを追加MainPageModel

namespace Profile.Models 
{ 
    public class MainPageModel 
    { 
     public MainPageModel() {} 

     public MainPageModel(Profiler profiler) 
     { 
      Profiler = profiler; 
     } 

     public Profiler Profiler { get; set; } 

     public IFormFile Image{ get; set; } 

    } 
} 

にパラメータのコンストラクタを追加します。 〜Image

@model Profile.Models.MainPageModel 
@{ 
    ViewData["Title"] = "Profiler"; 
} 
<h2>Create your Profile using the form below</h2> 
<h3>On Submission, your profile will be created for you to see.</h3> 

<form asp-action="Profiler" method="post"> 
    <label asp-for="Profile.FName"></label> 
    <input asp-for="Profile.FName" /> <br /><br /> 
    <label asp-for="Profile.Address"></label> 
    <input asp-for="Profile.Address" /> <br /><br /> 
    <label asp-for="Profile.BirthDate"></label> 
    <input asp-for="Profile.BirthDate" /> <br /><br /> 
    <label asp-for="Profile.PhoneNumber"></label> 
    <input asp-for="Profile.PhoneNumber" /> <br /><br /> 
    <label asp-for="Profile.Comments"></label> 
    <input asp-for="Profile.Comments" /> <br /><br /> 
    <input type="submit" value="Submit" /> 
</form> 

<form asp-action="Profiler" method="post" enctype="multipart/form-data"> 
    <input type="file" name="Image" /> 
    <input type="submit" value="Upload" /> 
</form> 

とコントローラ

[HttpGet] 
public IActionResult Profiler() 
{ 
    return View(new MainPageModel(profile)); 
} 

[HttpPost] 
public IActionResult Profiler(MainPageModel viewModel) 
{ 
    if(viewModel.Profile != null) 
    { 
     // Save profile 
    } 
    else if(viewModel.Image != null) 
    { 
     // Save image 
    } 
} 
1

まず、なぜあなたはIFormFileためのインタフェースを持っていますか? は既にのようなインターフェイスがASP.NETコアに組み込まれています。少なくとも、それは冗長で不必要なものであり、せいぜいあなたは紛争の原因となるでしょう。それを取り除き、組み込みのIFormFileを使用してください。

次に、アクションはProfilerインスタンスのみを受け入れます。あなたの行動は、あなたがビューに渡している同じビューモデルを受け入れる必要があります。そうしないと、すべての種類の問題が発生します。言い換えれば、このような結合ビューモデルが必要な場合は、同様に投稿する必要があります。

しかし、実際にこれを正しく設定しておくと、その必要はありません。まず、決してエンティティに直接バインドする必要があります。エンティティクラスは単純なDTOクラスである必要があります。その目的のために、データベースのニーズに目を配慮して設計する必要があります。ビューにはさまざまな懸念やニーズがありますが、エンティティクラスで処理するにはまったく不適切です。これはビューモデルの目的なので、ProfilerViewModelのようなものを持つ必要があります。あなたのProfilerエンティティは、アップロードされたファイルを見つけることができるURLまたはファイルパスを単に指す、プロパティまたは単純な文字列プロパティであるかどうかにかかわらず、ファイルアップロードを永続化する何らかの方法を持つべきです。あなたのビューモデルには、あなたのIFormFileプロパティがあります。ビューモデルからエンティティにマッピングするときは、アップロードしたファイルを保存し、エンティティの適切なプロパティを入力します。

これにより、実際には使用されるべきではない神のために残されたBind属性を取り除くこともできます。真剣にも、あらゆる面で恐ろしいことだ。実際に開発者がアプリケーションを正しく設計するように実際に奨励するのではなく、エンティティを直接使用することによるセキュリティ上の脆弱性を克服するためにのみ存在します。

正しいビューモデルを受け入れることで、ページに2つの別々のフォームがあるという問題を修正できます。これは、最初のフォームを送信してもアップロードされたファイルを投稿しないため、ユーザーを激しく怒らせます。 2番目のフォームを提出しても、プロフィールの変更は投稿されません。基本的には、いずれにせよ、あなたはユーザーの入力を捨てています。ファイル入力を最初のフォームに移動し、2番目のフォームを削除します。もちろん、enctype属性も持ち込むことができます。

最後に、複数のファイルをアップロードできるようにしていますが、すべてが1つのIFormFileを受け入れるプロパティです。 List<IFormFile>が必要です。

ロングとショート:

その後
public class ProfilerViewModel 
{ 
    public string FName { get; set; } 
    public string Address { get; set; } 
    public string BirthDate { get; set; } 
    public string PhoneNumber { get; set; } 
    public string Comments { get; set; } 

    public List<IFormFile> Files { get; set; } 
} 

public async Task<IActionResult> Profiler(ProfilerViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var profile = new Profiler 
     { 
      FName = model.FName, 
      Address = model.Address, 
      BirthDate = model.BirthDate, 
      PhoneNumber = model.PhoneNumber 
      Comments = model.Comments 
     }; 

     foreach (var file in model.Files) 
     { 
      // handle your file uploads 
     } 

     db.Profiles.Add(profile); 
     await db.SaveChangesAsync(); 

     return RedirectToAction("Somewhere"); 
    } 

    return View(model); 
} 

そして、あなたのビューで:

@model Profile.Models.ProfilerViewModel 
@{ 
    ViewData["Title"] = "Profiler"; 
} 
<h2>Create your Profile using the form below</h2> 
<h3>On Submission, your profile will be created for you to see.</h3> 

<form asp-action="Profiler" method="post" enctype="multipart/form-data"> 
    <label asp-for="FName"></label> 
    <input asp-for="FName" /> <br /><br /> 
    <label asp-for="Address"></label> 
    <input asp-for="Address" /> <br /><br /> 
    <label asp-for="BirthDate"></label> 
    <input asp-for="BirthDate" /> <br /><br /> 
    <label asp-for="PhoneNumber"></label> 
    <input asp-for="PhoneNumber" /> <br /><br /> 
    <label asp-for="Comments"></label> 
    <input asp-for="Comments" /> <br /><br /> 
    <input asp-for="Files" /> 
    <input type="submit" value="Submit" /> 
</form> 

その後、すべてがうまく動作するはずです。

関連する問題