2016-07-14 11 views
0

私は4 Modelsです。投稿、車、カテゴリ、サブカテゴリ。 Carにはいくつかの余分な属性があり、Post、Postからすべてを継承します。ModelにはCategoryIDとSubCategoryIDの属性が含まれています。私は車を保存することができるように動的に変更することができるViewを作成する必要があります。ユーザーは最初にカテゴリとサブカテゴリの2つのdropdownリストを表示し、両方を選択した後、右側にPartialViewをロードします。しかし、私はいくつかの理由でデータベースに保存することはできません。MVC変更選択したオプションに応じてフォームを動的に作成し、データベースに保存します

最初に、modelをページのどこに宣言するかわかりませんが、それは作成Viewにあるはずです。つまり、入力フィールドを動的に表示して変更するだけで、ページをリロードしないように変更することはできません。また、Car Modelには余分な属性がいくつかあります。stringintは、stringnullableではないため、すべての属性を持つViewModelを作成できません。 modelPartialViewに宣言されている場合 、それは私が車やポストに別々のViewModelを作成できることを意味しますが、formタグはPartialViewになり、カテゴリとサブカテゴリのためのdropdownリストは、それが必要として作成Viewにこのフォームタグの外側にあります変化しない。フォームが投稿されたとき、私はRequest.Form["..ID"];を使用してCategoryIDとSubCategoryIDを取得する前にエラーが発生しました。私は何とかこれを回避する必要があります。

Ajaxを使ってみましたが、これはCategoryIDとSubCategoryIDのヌルエントリであり、フォームタグ内の値のみを渡すというエラーがありました。

Models

public class Category 
{ 
    public int CategoryID { get; set; } 
    public string Name { get; set; }   

} 
public class SubCategory 
{   
    public int SubCategoryID { get; set; } 
    [Required] 
    public string Name { get; set; } 
    [ForeignKey("CategoryID")] 
    public virtual Category Category { get; set; } 
    public int? CategoryID { get; set; }   
} 
public class Post 
{ 
    public int PostID { get; set; } 
    public string Title { get; set; } 
    public string Msg { get; set; } 
    [DataType(DataType.Currency)] 
    public decimal Price { get; set; } 
    public string PostCode { get; set; } 
    [DataType(DataType.ImageUrl)] 
    public string MainPhotoPath { get; set; } 
    public DateTime PostedAt { get; set; } 
    public bool Active { get; set; }   
    public string ApplicationUserId { get; set; } 
    [ForeignKey("SubCategoryID")] 
    public virtual SubCategory SubCategory { get; set; } 
    public int SubCategoryID { get; set; }   
    public int CategoryID { get; set; } 
    public string CityName { get; set; } 

} 
public class Car : Post 
{ 
    public string Make { get; set; } 
    public int Year { get; set; } 
    public int EngineSize { get; set; } 
    public int Mileage { get; set; } 
    public string FuelType { get; set; } 
    public string Transmission { get; set; } 
} 

サブカテゴリのみポスト0を必要とする場合、カテゴリとサブカテゴリ

createNewPost div内にロード
@model PostIt.Models.DropDown 

<h4> 
Please choose a category first 
</h4> 
@using (Html.BeginForm()) 
{ 
    @Html.DropDownListFor(m => m.CategoryModel, new SelectList(Model.CategoryModel, "CategoryID", "Name"), new { @id = "CategoryID", @class = "form-control col-md-offset-2 margin-bottom" }) 
<select id="SubCategoryID" name="SubCategoryID" class="form-control col-md-offset-2 margin-bottom"></select> 

} 
<script language="javascript" type="text/javascript"> 
$(window).load(function() { 
    $("#CategoryID").click(function() { 
     var _categoryId = $("#CategoryID").val(); 
     var procemessage = "<option value='0'> Please wait...</option>"; 
     $("#SubCategoryID").html(procemessage).show(); 
     var url = "/Posts/GetSubCategoryById/"; 

     $.ajax({ 
      url: url, 
      data: { categoryid: _categoryId }, 
      cache: false, 
      type: "POST", 
      success: function (data) { 
       var markup = "<option value='0'>Select a subcategory</option>"; 
       for (var x = 0; x < data.length; x++) { 
        markup += "<option class='selectedSubCategory' value=" + data[x].Value + ">" + data[x].Text + "</option>"; 
       } 
       $("#CategoryID").val(_categoryId); 
       $("#SubCategoryID").html(markup).show(); 
      }, 
      error: function (reponse) { 
       alert("error : " + reponse); 
      } 
     }); 
    }); 
}); 
</script> 

PartialViewを選択するためにView

@using Mvc.CascadeDropDown 

@{ 
    ViewBag.Title = "Create"; 
} 
<div class="row"> 
<div class="col-lg-12"> 
    <div class="text-center"> 
     <h2>Add a new Post</h2> 
     <h3 id="CityDiv">City: @ViewBag.Location</h3> 
    </div> 
    <div class="col-lg-12"> 
     @Html.Action("Menu") 
     <div id="createNewPost"> 

     </div> 
    </div>   
</div> 
</div> 
<script type="text/javascript"> 
$("#SubCategoryID").click(function() { 
    var selectedSubCategory = $("#SubCategoryID").val(); 
    if (selectedSubCategory == 4) { 
     var url = "/Posts/CarPartial/"; 

     $.ajax({ 
      url: url, 
      cache: false, 
      type: "POST", 
      success: function (data) { 
       $("#createNewPost").html(data); 
      }, 
      error: function (reponse) { 
       alert("error : " + reponse); 
      } 
     }); 
    }   
    else { 
     var url = "/Posts/PostPartial/"; 

     $.ajax({ 
      url: url, 
      cache: false, 
      type: "POST", 
      success: function (data) { 
       $("#createNewPost").html(data); 
      }, 
      error: function (reponse) { 
       alert("error : " + reponse); 
      } 
     }); 
    } 
}); 
$("#CreatePostFormID").submit(function() { 
    var _categoryId = $("#CategoryID").val(); 
    var _subcategoryId = $("#SubCategoryID").val(); 
    var url = "/Posts/Create/"; 

    $.ajax({ 
     url: url, 
     data: { cId: _categoryId, subId: _subcategoryId }, 
     cache: false, 
     type: "POST", 
     success: function (data) { 
      alert("ok"); 
     }, 
     error: function (reponse) { 
      alert("error : " + reponse); 
     } 
    }); 
}); 
</script> 
@section Scripts { 
@Scripts.Render("~/bundles/jqueryval") 
} 

メニューを作成します。

@model PostIt.Models.PostViewModel 
@using (Html.BeginForm("Create", "Posts", FormMethod.Post, new { enctype = "multipart/form-data", id = "CreatePostFormID" })) 
     { 
@Html.AntiForgeryToken() 

<div class="form-horizontal"> 
     <div class="form-group"> 
      @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Msg, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Msg, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Msg, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.PostCode, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.PostCode, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.PostCode, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.MainPhotoPath, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.TextBoxFor(model => model.MainPhotoPath, new { type = "file" }) 
       @Html.ValidationMessageFor(model => model.MainPhotoPath, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" id="SubmitID" /> | @Html.ActionLink("Cancel", "Index") 
      </div> 
     </div> 
</div> 
} 

ActionMethodポストを作成します。

public ActionResult Create([Bind(Include = "Title,Msg,Price,PostCode,MainPhotoPath")] PostViewModel post, HttpPostedFileBase image, int cId, int subId) 
    { 
     Post newPost = new Post(); 
     //var cId = Request.Form["CategoryModel"]; 
     //var subId = Request.Form["SubCategoryID"]; 
     newPost.CategoryID = Convert.ToInt32(cId); 
     newPost.SubCategoryID = Convert.ToInt32(subId); 
     newPost.Title = post.Title; 
     newPost.Msg = post.Msg; 
     newPost.Price = post.Price; 
     newPost.PostCode = post.PostCode; 
     newPost.PostedAt = DateTime.Now; 
     newPost.Active = false; 
     newPost.ApplicationUserId = User.Identity.GetUserId(); 
     newPost.CityName = Server.HtmlEncode(Request.Cookies["location"].Value); 
     Debug.WriteLine(Request.Files.Count); 

     HttpPostedFileBase file = Request.Files[0]; 
     string fileName = file.FileName; 
     int fileSize = file.ContentLength; 
     if (fileSize >= 10) 
     { 
      string path = Server.MapPath("~/Upload_Files/images/"); 
      newPost.MainPhotoPath = "~/Upload_Files/images/" + fileName; 

      if (!Directory.Exists(path)) 
      { 
       Debug.WriteLine("Creating new directory"); 
       Directory.CreateDirectory(path); 
      } 
      file.SaveAs(Server.MapPath("~/Upload_Files/images/" + fileName)); 
     } 
     else 
     { 
      newPost.MainPhotoPath = "~/Images/no_image.png"; 
     } 



     if (ModelState.IsValid) 
     { 
      db.Posts.Add(newPost); 
      db.SaveChanges(); 
      return RedirectToAction("Index", "Home"); 
     } 

     return View("Create", post); 
    } 
+2

アドバイスが必要な場合は、質問の簡略化された表現を作成し、簡潔かつ凝縮した方法でそれを尋ねる必要があります。人々はあなたのためにあなたのプログラミングをすることにあまり熱心ではありません。それは、あなたのコードをすべて質問に投げ捨てるときのようです。そのような人々は、このような形式の質問から本当に恩恵を受けることはありません。 – Slight

+0

私はそれをコメントすることができます:最初に、ドロップダウンを行うにはパーシャルビューが必要ではなく、FKを使って他の値を呼び出すこと、2番目:正しくロードしてドロップダウンを設定するとき、Ajaxを使用してデータベース、ちょうどそれについて読んで、Googleは簡単に達成するためにすべての情報を持っている! – Gerry

答えて

1

私はあまりにも多くのコードをダンプするという意味ではありませんでしたし、私はその上で、私の教訓を学んできました。..

誰もが同じ問題で苦労されている場合は、答えは次の通りです。

@using (Html.BeginFormタグを使用してPartialViewmodelを宣言し、modelに応じてフォームを作成できます。作成フォームはAjaxを介して動的に変更できるので、基本的に1つの作成フォームがどのモデルにも対応できます。

dropdownのように、必要なCategoryIDとSubCategoryIDの値を含むリストはフォームタグの外にあり、コントローラーに渡されず、Ajaxを使用しても、それは中断されます。最初にActionResultを呼び出しますが、IDに渡される値はありません。エラーが返され、Ajax関数を呼び出すことさえありません。

modelのコントローラーにPartialViewを作成するときに、ID値を渡します。

Ajaxコールは、右PartialViewを返すために、コントローラ内部でポストPartialView

var url = "/Posts/PostPartial/"; 

     $.ajax({ 
      url: url, 
      data: { cid : selectedCategory, sid : selectedSubCategory }, 
      cache: false, 
      type: "POST", 
      success: function (data) { 
       $("#createNewPost").html(data); 
      }, 
      error: function (reponse) { 
       alert("error : " + reponse); 
      } 
     }); 

ActionResultを取得します。この場合、それはポストです。

public ActionResult PostPartial(int cid, int sid) 
    { 
     PostViewModel viewmodel = new PostViewModel(); 
     viewmodel.CategoryID = cid; 
     viewmodel.SubCategoryID = sid; 
     return PartialView("CreatePost", viewmodel); 
    } 

上記しかしPostViewModel呼ば ViewModelが同様に区分し、SubCategoryIDの属性を持っている必要があり、 ActionResultが正常に動作作成し、コントローラで bind属性が ActionResultを作成する必要があります。

関連する問題