2016-07-14 2 views
0

У меня есть 4 Models Сообщение, автомобиль, категория, подкатегория. Автомобиль имеет несколько дополнительных атрибутов, а также наследует все от Post, Post Model содержит атрибуты для CategoryID и SubCategoryID. Мне нужно создать один View, который может динамически изменяться, чтобы иметь возможность экономить автомобили. Сначала пользователь видит два списка dropdown для категорий и подкатегорий, после того как оба выбраны, он загружает право PartialView. Все это прекрасно, однако я не могу сохранить его в базе данных по нескольким причинам.Изменение MVC Формировать форму динамически в зависимости от выбранной опции и сохранять ее в базе данных

Во-первых, я не знаю, где объявить model на странице, она должна быть в создании View - означает, что он не может быть изменен, как я только хочу, чтобы поля ввода появляются и изменяются динамически, но страница не должна быть перезагружена. Это также означает, что Car Model имеет несколько дополнительных атрибутов: string и int, я не могу создать ViewModel, который имеет все возможные атрибуты, так как string не nullable. Если model объявлен в PartialView, это означает, что я могу создать отдельную ViewModel для автомобилей и почт, но форма тег будет в PartialView и dropdown списков для категорий и подкатегорий вне этой формы тега Создать View как это должно не изменить. Когда форма отправлена, я получаю сообщение об ошибке, как и раньше, я использовал Request.Form["..ID"];, чтобы получить CategoryID и SubCategoryID. Мне нужно как-то обойти это.

Я пробовал использовать Ajax, но при этом возникла ошибка, указав нулевую запись для Категории и 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; } 
} 

Создать 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.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 загружен в createNewPostdiv если подкатегория только требует сообщение-

@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

Как я понимаю, я могу прокомментировать это: сначала вам не нужен Partial View, чтобы делать Dropdown, просто вызывайте другие значения с помощью FK, Second: при правильной загрузке и заполнении выпадающего меню не нужно использовать Ajax для сохранения в базе данных , просто прочитайте об этом, у google есть вся информация, чтобы достичь этого легко! – Gerry

ответ

1

Я не хотел сбрасывать слишком много кода, и я узнал, что мой урок о том, что ..

Если кто-то борется с той же проблемой, ответ заключается в следующем.

Объявление model в PartialView с тегом @using (Html.BeginForm, поэтому вы можете создать форму согласно model. Создать форму можно динамически изменять с помощью Ajax, поэтому по существу одна форма создания может обрабатывать любые модели.

В качестве dropdown списков, содержащих значения для нужного идентификатора категории и подкатегории, находятся за пределами тега формы, он не будет передан контроллеру, и даже если он используется с Ajax, он только нарушит его.Сначала он вызывает ActionResult, но не передается значение для идентификаторов, возвращает ошибку и даже не вызывает функцию Ajax.

Чтобы обойти его, при создании PartialView в контроллере справа model, я передаю ему идентификационные значения.

Ajax вызов, чтобы получить сообщение 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 внутри контроллера, чтобы вернуть право PartialView. В этом случае это Post.

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

выше Создание ActionResult работает отлично, однако ViewModel называется PostViewModel должен иметь атрибуты для CategoryID и SubCategoryID, а также и должны bind атрибутов контроллера для создания ActionResult.

Смежные вопросы