I'm trying to save multiple models but have problem with the dropdownlist of the model.
I got the following error: No information ViewData type 'IEnumerable ' with key '[0]. TypeBienId'.
Here are some files:
Controller GET:
public ActionResult RDummy()
{
List<BI> bis = new List<BI>();
BI bi1 = new BI();
ViewBag.TypeBienId = new SelectList(db.TypeBiens, "TypeBienId", "cnom");
bis.Add(bi1);
return View(bis);
}
My View:
#model IEnumerable<SIBI.Models.BI>
#using (Html.BeginForm()) {
#Html.EditorForModel()
<p>
<input type="submit" value="Crear" />
</p>
}
My Template in the EditorTemplates Folder:
#model SIBI.Models.BI
#Html.DropDownList("TypeBienId", String.Empty)<br />
#Html.ValidationMessageFor(model => model.TypeBienId)
Any ideas of what the problem is and how to resolved?
Try using this in your EditorTemplate:
#Html.DropDownList("TypeBienId", ViewBag.TypeBienId);
Related
The Ajax form does update selected div, but instead of just reloading a partial view in that div it inserts the whole page content into that div.
.cshtml file
<fieldset>
<legend>File(s)</legend>
<div id="filesBody">
#Html.Action("Action", "Controller", new {id=Model.Id})
</div>
<br />
#using (Ajax.BeginForm("UploadFile", "Controller", null, new AjaxOptions { UpdateTargetId="filesBody"}, new { enctype = "multipart/form-data", #id = "myForm" }))
{
#Html.HiddenFor(model => model.ComplaintId)
<div>
<label for="File">Add File:</label>
<input type="file" name="FileAttachment" />
<input type="submit" value="Upload" />
#Html.ValidationMessage("FileAttachment")
</div>
}
</fieldset>
Controller
public PartialViewResult GetFilesData(long? Id)
{
Model Model = new Model(Id);
TryUpdateModel(Model);
return PartialView(Model);
}
Partial view
#model Models
<div id="reloadField">
#foreach (var ph in Model.docs)
{
///code
}
</div>
In your partial view set the Layout equal to null.
#model Models
#{
Layout = null;
}
UPDATE
Change your Ajax.BeginForm to call the GetFilesData action.
I am using MVC4.
Validation is failing but validation error messages are not getting displayed.
This is my model.
public class Configuration
{
public int Id { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Site name is required.")]
[MinLength(6, ErrorMessage = "Name should be at least 6 characters.")]
public string SiteName { get; set; }
}
Controller.
[HttpPost]
public ActionResult Create(Configuration configItem)
{
if (ModelState.IsValid)
{
// do something.
}
return View("Index", configItem);
}
View is
#model Models.SitesConfig.Configuration
#{
ViewBag.Title = "Sites Configurations";
}
<div>
#Html.ActionLink("Sites List", "List", "SiteConfig")
</div>
#using (Html.BeginForm("Create", "SiteConfig", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<fieldset>
<legend>New Satellitesite</legend>
<div>
#Html.LabelFor(m => m.SiteName, "Name")
#Html.TextBoxFor(m => m.SiteName)
#Html.ValidationMessageFor(m=>m.SiteName)
</div>
<br />
<input type="submit" value="Save" />
</fieldset>
}
Please also suggest me if there is any better way of doing the validations.
I don't know what was the problem. After clean and build the application, I am able to see the error message.
Thanks,
Naresh
There should be #Html.ValidationSummary("Please correct the errors") in the View
#using (Html.BeginForm("Create", "SiteConfig", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary()
<fieldset>
<legend>New Satellitesite</legend>
<div>
#Html.LabelFor(m => m.SiteName, "Name")
#Html.TextBoxFor(m => m.SiteName)
#Html.ValidationMessageFor(m=>m.SiteName)
</div>
<br />
<input type="submit" value="Save" />
</fieldset>
}
Try this one .. #Html.ValidationSummary() helps in displaying the error messages.
If you try the above solutions and still didn't work, then maybe you need to format your View file. Go to Edit-Advanced-Format Document. Remember not to be in the debug mode when trying to format your file because you wouldn't see the above listed procedures if you are debugging your project.
Make sure your View is referencing the jQuery validations in the Scripts tag -
#section Scripts
{
#Scripts.Render("~/bundles/jqueryval")
}
As I am newbie to asp.net mvc 3, I have no good knowledge of it's internal process. I have two action to create new category as Get and Post method:
public ActionResult Create()
{
List<Category> cat = this.display_children(null, 0);
List<SelectListItem> items = new SelectList(cat, "ID", "CategoryName").ToList();
items.Insert(0, (new SelectListItem { Text = "root", Value = "" }));
ViewBag.ParentCategoryID = items;
return View();
}
[HttpPost]
public ActionResult Create(Category category)
{
if (ModelState.IsValid)
{
db.Categories.AddObject(category);
db.SaveChanges();
return RedirectToAction("Index");
}
List<Category> cat = this.display_children(null, 0);
List<SelectListItem> items = new SelectList(cat, "ID", "CategoryName").ToList();
items.Insert(0, (new SelectListItem { Text = "root", Value = "" }));
ViewBag.ParentCategoryID = items;
return View(category);
}
Below is View:
#model IVRControlPanel.Models.Category
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Category</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CategoryName)
#Html.ValidationMessageFor(model => model.CategoryName)
</div>
<div class="editor-label">
#Html.Label("Select Category")
</div>
<div>
#*#Html.DropDownList("CategoryList",new SelectList(ViewBag.Categories))*#
#Html.DropDownList("ParentCategoryID", ViewBag.ParentCategoryID as SelectList)
#Html.ValidationMessageFor(model => model.ParentCategoryID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Problem:
When I click the create button without filling up the category-name field following exception is thrown:
This property cannot be set to a null value.
The exception is thrown only when visual studio is debugging mode and when I continue debugging then only error is shown in validation message. Here, What actually have to be is that Error should be shown without throwing exception which is alright while not in debugging mode. I have following category table column in database and use model first approach Entity framework:
ID -> primary key and identity , integer
CategoryName -> Non nullable, varchar(50)
ParentCategoryID -> Nullable
I have not good at asp.net mvc 3 and can not figured what might be the problems.
In your actions replace:
ViewBag.ParentCategoryID = items;
with:
ViewBag.Categories = items;
and in your view:
#Html.DropDownListFor(x => x.ParentCategoryID, ViewBag.Categories as SelectList)
The DropDownList helper needs 2 arguments: the first one represents a scalar property that will hold the selected value and the second argument a collection with the available items. They should be different.
Luckily I found solution for this. Actually, Problem was due to PreBinding validation. I was searching and found same issue at this link explained nicely.
I have made partial class for Category as below:
public partial class Category{
}
public class TestEntityValidation{
[Required]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public String CategoryName { get; set; }
}
Here, Converting empty string to null is set to false which have solved my problem at DisplayFormat attributes.
I'm new to MCV and I'm learning MVC3. I created a model and a controller and view was generated for me. The generated code makes perfect sense to me. I wanted to modify the generated view and controller so that I could upload a file when I "create" a new record. There is a lot of good information out there about how to do this. Specifically I tried this: http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx
The problem is that even when I select a file (not large) and submit, there are no files in the request. That is, Request.Files.Count is 0.
If I create the controller and and view from scratch, in the same project (no model), the example works just fine. I just can't add that functionality to the generated page. Basically, I'm trying get the Create action to also send the file. For example, create a new product entry and send the picture with it.
Example Create view:
#model Product.Models.Find
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Create", "Find", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Find</legend>
<input type="file" id="file" />
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Example Controller:
[HttpPost]
public ActionResult Create(Product product)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0 && Request.Files[0] != null)
{
//Not getting here
}
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(find);
}
This will create the record just fine but there are not files associated with the Request.
I've also tried a controller action like this:
[HttpPost]
public ActionResult Create(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
//Not getting here
}
return RedirectToAction("Index");
}
I'm wondering if maybe you can't post a file at the same time as posting form fields? If that is the case, what are some patterns for creating a new record and associating a picture (or other file) with it?
Thanks
Create a ViewModel which has properties to handle your image and Product deatils
public class ProductViewModel
{
public string ImageURL { set;get;}
public string Title { set;get;}
public string Description { set;get;}
}
And in your HTTPGET Action method, return this ViewModel object to your strongly typed view
public ActionResult Create()
{
ProductViewModel objVM = new ProductViewModel();
return View(objVM);
}
And in your View
#model ProductViewModel
<h2>Add Product</h2>
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBoxFor(m => m.Title) <br/>
#Html.TextBoxFor(m => m.Description ) <br/>
<input type="file" name="file" />
<input type="submit" value="Upload" />
#Html.HiddenFor(m => m.ImageURL )
}
Now in your HttpPost action method, accept this ViewModel and File
[HttpPost]
public ActionResult Create(HttpPostedFileBase file, ProductViewModel objVM)
{
if(file==null)
{
return View("Create",objVM);
}
else
{
//You can check ModeState.IsValid if you have to check any model validations and do further processing with the data here.
//Now you have everything here in your parameters, you can access those and save
}
}
You will have to create a ViewModel for Product (maybe ProductViewModel) and add a HttpPostedFileBase field with the same name as the field of the form and use that instead of the Product in the action of the controller.
A ViewModel is nothing but a model used for specific views. Most of the times, with extra data to generate the view or to decompose and form the model on the controller action.
public ProductViewModel
{
public string Cod { get; set; }
// All needed fields goes here
public HttpPostedFileBase File{ get; set; }
/// Empty constructor and so on ...
}
i have a create view to add answers to a question, currently the user can only add one answer at the same time when he clicks on the submit button, instead of this i want the user to be able to insert multiple answers objects into the same view and then the system to add all these new answer objects to the database after the user click on the submit button, my current view looks as the follow:-
#model Elearning.Models.Answer
#{
ViewBag.Title = "Create";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id = "remove">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "remove"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
and the action methods look as the follow:-
public ActionResult Create(int questionid)//, int assessmentid)
{
ViewBag.questionid = questionid;
Answer answer = new Answer();
return PartialView("_answer",answer);
}
//
// POST: /Answer/Create
[HttpPost]
public ActionResult Create(int questionid, Answer a)
{
if (ModelState.IsValid)
{
repository.AddAnswer(a);
repository.Save();
return PartialView("_details",a);
}
return View(a);}
so how i can modify the above code to be able to insert multiple answer objects at the same view and then submit these answers objects at the same time when the user click on the submit button?
Try Post a List
Add input by javascript when user click "Add Answer".
And when submit the form ,it will post all answer data to binding to List
<script>
$(document).ready(function () {
var anwserCount = 1;
$("#addbutton").click(function () {
$("#AnwsersDiv")
.append("<input type='text' name='Anwsers[" + anwserCount + "]'/>");
anwserCount += 1;
});
});
</script>
#using (Html.BeginForm())
{
<div id="AnwsersDiv">
<input type="text" name="Anwsers[0]" />
</div>
<input id="addbutton" type="button" value="Add answer" />
<input type="submit" value="submit" />
}
Model
public class Answer
{
public List<String> Anwsers { get; set; }
}
When submit the form
I think this is what you are looking for
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Conclusion: you should make the post action with ICollection<Answer> Parameter, then it will be easy to get them when you post your main form, and create the appropriate QUESTION object, then save them all with only one submit.