I am trying to upload image files from my form along with other fields in my model. My HttpPostedFileBase collection is always empty and the count is 0.
I have referred many other questions relating to this in SO but somehow I am unable to find the solution.
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Id, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Id)
#Html.ValidationMessageFor(model => model.Id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProfileId, "ProfileId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProfileId", String.Empty)
#Html.ValidationMessageFor(model => model.ProfileId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage1" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage2" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image3, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage3" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image4, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage4" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image5, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage5" type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,ProfileId,fileuploadImage1,fileuploadImage2,fileuploadImage3,fileuploadImage4,fileuploadImage5,Files")] HomepageSetting homepagesetting)
{
if (ModelState.IsValid)
{
try
{
List<String> imagesFilenames = new List<String>();
/*Lopp for multiple files*/
foreach (HttpPostedFileBase file in homepagesetting.Files)
{
/*Geting the file name*/
string filename = System.IO.Path.GetFileName(file.FileName);
/*Saving the file in server folder*/
file.SaveAs(Server.MapPath("~/Images/" + filename));
string filepathtosave = "Images/" + filename;
imagesFilenames.Add(filepathtosave);
}
if(imagesFilenames.Count == 1)
{
homepagesetting.Image1 = imagesFilenames[0];
}
else if (imagesFilenames.Count == 2)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
}
else if (imagesFilenames.Count == 3)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
}
else if (imagesFilenames.Count == 4)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
homepagesetting.Image4 = imagesFilenames[3];
}
else if (imagesFilenames.Count == 5)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
homepagesetting.Image4 = imagesFilenames[3];
homepagesetting.Image5 = imagesFilenames[4];
}
ViewBag.Message = "File Uploaded successfully.";
}
catch
{
ViewBag.Message = "Error while uploading the files.";
}
db.HomepageSettings.Add(homepagesetting);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ProfileId = new SelectList(db.Profiles, "Id", "name", homepagesetting.ProfileId);
return View(homepagesetting);
}
Model:
public partial class HomepageSetting
{
public int Id { get; set; }
//other model properties
public string Image1 { get; set; }
public string Image2 { get; set; }
public string Image3 { get; set; }
public string Image4 { get; set; }
public string Image5 { get; set; }
public virtual Profile Profile { get; set; }
public List<HttpPostedFileBase> Files { get; set; }
public HomepageSetting()
{
Files = new List<HttpPostedFileBase>();
}
}
Can any one point me to what I am doing wrong here?
Instead of foreach loop do it this way, it happens with foreach as i also faced this issue:
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase myFile = Request.Files[i];
}
In MVC you always have to proper name of html element in order to work its default binding. In your case
fileupload control has name like fileuploadImage1 , fileuploadImage2 and that not present in your model so it is not binding.
I suggest that you should name all your file upload element name.
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Id, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Id)
#Html.ValidationMessageFor(model => model.Id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProfileId, "ProfileId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProfileId", String.Empty)
#Html.ValidationMessageFor(model => model.ProfileId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image3, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image4, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image5, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Your action you have to do .
[HttpPost]
public ActionResult View1([Bind(Include = "Id,ProfileId,fileuploadImage1,fileuploadImage2,fileuploadImage3,fileuploadImage4,fileuploadImage5,Files")] HomepageSetting homepagesetting)
{
for (int i = 0; i < homepagesetting.Files.Count; i++)
{
if (homepagesetting.Files[i] != null)
{
}
}
return View();
}
Related
I have a form for adding Books in a database,
I Have a modal window in my form to create a Publisher, if the specified format doesn't exist in Publisher Dropdown, I Create my Modal in a partial view for add Publisher,
this is my view:
#model WebApplication3.Models.BookModel
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="CustomerList"></div>
<h2>Create New Book</h2>
<label class="text-#ViewBag.ClassName">
#ViewBag.Message
</label>
#using (Html.BeginForm("CreateBook", "Book", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TitleID, "TitleID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("TitleID", null, "Select a Title", htmlAttributes: new { #class = "form-control" })
#Html.ActionLink("Add New", "Create", "Title")
#Html.ValidationMessageFor(model => model.TitleID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FormatID, "FormatID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("FormatID", null, "Select a Format", htmlAttributes: new { #class = "form-control" })
<a href="" class="" data-toggle="modal" data-target="#FormatModal">
Add New
</a>
#Html.ValidationMessageFor(model => model.FormatID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ISBN, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ISBN, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ISBN, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Quantity, "", 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-primary" />
</div>
</div>
</div>
}
<div class="modal fade" id="PublisherModal" tabindex="-1" role="dialog" aria-labelledby="publisherModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
#Html.Partial("_Publisher")
</div>
</div>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/jqueryajax")
}
and this is my Publisher partial view:
#model WebApplication3.Models.PublisherModel
#using (Ajax.BeginForm("CreatePublisher", "Book", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "publisherForm", InsertionMode = InsertionMode.ReplaceWith }))
{
<div id="publisherForm">
<div class="modal-header">
<h5 class="modal-title" id="publisherModalLongTitle">Create New Publisher</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
<span class="text-#ViewBag.ClassName">
#ViewBag.Message
</span>
</div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Value, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Value, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Value, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
#Html.ActionLink("Manage", "Index", "Publisher", new { area = "" }, new { #class = "btn btn-link" })
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</div>
}
and this is my controller
[HttpPost]
[ValidateAntiForgeryToken]
public PartialViewResult CreatePublisher([Bind(Include = "ID,Value,Description")] PublisherModel publisherModel)
{
ViewBag.TitleID = new SelectList(repoTitle.GetModels(), "ID", "Title");
ViewBag.FormatID = new SelectList(repoFormat.GetModels(), "ID", "Value");
PublisherModel publisher = repoPublisher.GetModels().FirstOrDefault(x => x.Value == publisherModel.Value);
if (publisher == null)
{
if (ModelState.IsValid)
{
repoPublisher.Insert(publisherModel);
ViewBag.PublisherID = new SelectList(repoPublisher.GetModels(), "ID", "Value", publisherModel.ID);
ViewBag.Message = $"Publisher \"{publisherModel.Value}\" Added Successfully";
ViewBag.ClassName = "success";
return PartialView("_Publisher");
}
}
else
{
ViewBag.Message = $"Publisher \"{publisherModel.Value}\" Already Exsisted";
ViewBag.ClassName = "danger";
}
ViewBag.PublisherID = new SelectList(repoPublisher.GetModels(), "ID", "Value");
return PartialView("_Publisher",publisherModel);
}
How Can change to my code that if a new Publisher inserted to Database, the Publisher dropdown refresh and select newly inserted data as a selected item?
About question
I can't run your code locally.
These operations can be implemented through JS.
I can show my tools.
This is the function gif:
Solution:
Select and add options as a whole.
// index.cshtml
<div>
#await Component.InvokeAsync("AutoAddListValue")
</div>
//Component
#model List<string>
<h3>Default page</h3>
<div>
<div>
<p>Lists</p>
<select name="select" class="" id="ComponentSelectId" onclick="ComponentSelectClick()">
<option id="ComponentOptionId" style="width:auto">ComponentTest</option>
#if (Model.Count != 0)
{
int count = Model.Count();
for (int item = 0; item < count; item++)
{
<option id="option">#Model[item].ToString()</option>
}
}
</select>
</div>
<div>
<input id="ComponentTestJsInput" class="d-none" value="132323" type="text" />
<input id="ComponentBtnDisplay" value="Add" type="button" class="btn btn-primary" onclick="ComponentBtnDisplayClick()">
<input id="ComponentBtnAdd" value="Add" type="button" class="btn btn-primary d-none" onclick="ComponentBtnAddClick()">
</div>
</div>
Bind data for components.
public class AutoAddListValueViewComponent : ViewComponent
{
private readonly SchoolContext _context;
public AutoAddListValueViewComponent(SchoolContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync(
int maxPriority, bool isDone)
{
string MyView = "Default";
var items = await GetListAsync();
return View(MyView, items);
}
public async Task<List<string>> GetListAsync()
{
return await _context.Test.Select(o => o.Name).ToListAsync();
}
}
Using JS code to realize page interaction.
var ComponentBtnDisplayClick = function () {
$('#ComponentBtnAdd').removeClass("d-none");
$('#ComponentTestJsInput').removeClass("d-none");
$('#ComponentBtnDisplay').addClass("d-none");
}
var ComponentBtnAddClick = function () {
//alert("666666");
$('#ComponentBtnAdd').addClass("d-none");
$('#ComponentTestJsInput').addClass("d-none");
$('#ComponentBtnDisplay').removeClass("d-none");
inputVal = $('#ComponentTestJsInput').val();
//alert(inputVal);
$.ajax({
url: '/Test/SaveInputValue',
data: {
name: inputVal
},
type: 'post',
async: true,
cache: false,
success: function (data) {
//alert(data.code);
var option = "<option id='ComponentOptionId'>";
option += inputVal;
option += "</option>";
$("#ComponentSelectId").append(option);
var obj = document.getElementById("ComponentSelectId");
obj[obj.length - 1].selected = true;
},
error: function () {
alert('fail');
}
});
}
Other code
Source Code
My View Model is:
public class CompanyAccountViewModel
{
public string Name { get; set; }
public float Interval { get; set; }
public List<string> MobileNo { get; set; }
}
and My view is:
#model PowerSupply.Models.CompanyAccountViewModel
#{
ViewBag.Title = "Register";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>Register</h3> <br />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group row">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "col-sm-2 col-md-1 col-form-label" })
<div class="col-sm-10 col-md-3">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row">
#Html.LabelFor(model => model.Interval, htmlAttributes: new { #class = "col-sm-2 col-md-1 col-form-label" })
<div class="col-sm-10 col-md-3 positioned_relative">
#Html.EditorFor(model => model.Interval, new { htmlAttributes = new { #class = "form-control" } })
<span class="help-text">Hour</span>
#Html.ValidationMessageFor(model => model.Interval, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row">
#Html.LabelFor(model => model.MobileNo, htmlAttributes: new { #class = "col-sm-2 col-md-1 col-form-label" })
<div class="col-sm-10 col-md-3">
<span class="add-new-icon glyphicon glyphicon-plus-sign" id="add_mobile"> </span>
#Html.EditorFor(model => model.MobileNo, new { htmlAttributes = new { #class = "form-control",#id= "add_mobile" } })
#Html.ValidationMessageFor(model => model.MobileNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group row new_mobile_wrapper">
<div class="col-md-offset-3">
<div class="new_mobile_container">
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-offset-2 col-sm-10 col-md-2">
<input type="submit" value="Register" class="btn btn-primary col-sm-offset-1" />
</div>
</div>
}
Here I all field is being rendered properly but:
#Html.EditorFor(model => model.MobileNo, new { htmlAttributes = new { #class = "form-control",#id= "add_mobile" } })
This does not generate any markup. I point out the reason and it due to the Entity Type. Entity Type of MobileNo is List. How to modify this #Html.EditorFor? Any idea? It kills my whole day.
The problem lies in this property:
public List<string> MobileNo { get; set; }
Since a user may have multiple mobile phone numbers, you cannot bind this collection to a single #Html.EditorFor() helper (binding like current state doesn't generate any HTML markup). You need to generate the EditorFor helper for each string value by using a loop:
#for (var i = 0; i < Model.MobileNo.Count; i++)
{
#Html.EditorFor(m => m.MobileNo[i], new { htmlAttributes = new { #class = "col-sm-2 col-md-1 col-form-label" } })
}
Or use TextBoxFor as alternative, also inside the loop:
#for (var i = 0; i < Model.MobileNo.Count; i++)
{
#Html.TextBoxFor(m => m.MobileNo[i], new { #class = "col-sm-2 col-md-1 col-form-label" })
}
If you want to create mobile number inputs dynamically from List<string> property, see this article to get started.
That's probably because your MobileNo list has no data values when CompanyAccountViewModel was returned to the view.
#model CommonLayer.ORDER
#{
ViewBag.Title = "Update";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h4>Update Order Status</h4>
<br />
#if (Model.OrderStatus != "Shipped")
{
using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.UserId)
<div class="form-group">
#Html.LabelFor(model => model.OrderId, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderId, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderStatus, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" name="OrderStatus">
<option value="Pending" id="pending">Pending</option>
<option value="Shipped" id="shipped">Shipped</option>
</select>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderDate, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderDate, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderNumber, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderNumber, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<form action="/order/update/#Model.OrderId" method="post" enctype="multipart/form-data">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Update" class="btn btn-primary" />
</div>
</div>
</form>
</div>
}
}
else
{
<h4>Order Has Been Shipped!</h4>
}
My submit button isn't working regardless of the correct syntax being used. When I press the button nothing happens, as if I haven't clicked it, no redirecting whatsoever.
Was working until yesterday. Did not change any code whatsoever regarding the form or corresponding controller.
This is the controller corresponding to the form.
[HttpGet]
[Authorize(Roles = "ADM")]
public ActionResult Update(Guid Id)
{
BusinessLayer.Orders order = new BusinessLayer.Orders();
return View(order.GetOrder(Id));
}
[HttpPost]
[Authorize(Roles = "ADM")]
public ActionResult Update(CommonLayer.ORDER order, Guid id)
{
BusinessLayer.Orders blorder = new BusinessLayer.Orders();
blorder.UpdateOrder(order);
return RedirectToAction("UpdateDetails", new {id=id});
}
Use below code, let us know if doesn't work
Added below line to pass the orderid
#Html.HiddenFor(model => model.OrderId)
Updated below line to call action of a controller
Html.BeginForm("update","order",FormMethod.Post)
Finally removed the unnecessary form tag
Removed antiforgerytoken from view as you are not checking in you action method.
If you want to add that then you need to add [ValidateAntiForgeryToken] after [httppost] of Update Action method
#model CommonLayer.ORDER
#{
ViewBag.Title = "Update";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h4>Update Order Status</h4>
<br />
#if (Model.OrderStatus != "Shipped")
{
using (Html.BeginForm("Update","Order",FormMethod.Post))
{
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.UserId)
#Html.HiddenFor(model => model.OrderId)
<div class="form-group">
#Html.LabelFor(model => model.OrderId, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderId, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderStatus, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" name="OrderStatus">
<option value="Pending" id="pending">Pending</option>
<option value="Shipped" id="shipped">Shipped</option>
</select>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderDate, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderDate, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderNumber, htmlAttributes: new { #style = "font-size:medium", #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderNumber, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Update" class="btn btn-primary" />
</div>
</div>
</div>
}
}
else
{
<h4>Order Has Been Shipped!</h4>
}
My problem is with file upload and Ajax. I have one form with form fields and upload function. I want user to select image from disc, click upload without redirect, display image below, fill in the forms, click create to save form into one table and image into another. The problem is that both upload and create buttons are submiting and I want upload to wait for the rest of the form. Is Ajax the best solution for this?
Here is my code:
View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>sticenikSlika</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.sticenikId, "sticenikId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("sticenikId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.sticenikId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.vrijeme, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.vrijeme, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.vrijeme, "", 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" />
</div>
</div>
</div>
}
<div class="form-horizontal">
<div class="form-group">
#using (Html.BeginForm("FileUpload", "UploadImage", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file" class="control-label col-md-2">Upload Image:</label>
<div class="col-md-10">
<span class="btn btn-default btn-file">
<input type="file" name="file" id="file" />
</span>
<input type="submit" value="Upload" class="submit btn btn-default" id="upload" />
</div>
}
</div>
</div>
Controller that posts to the database is default Entity framework stuff.
Controller UploadImage:
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string pic = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(
Server.MapPath("~/Content/images/profile"), pic);
file.SaveAs(path);
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
JavaScript:
<script>
$('#upload').click(function (e) {
e.preventDefault();
$.ajax({
url: '/UploadImage/FileUpload',
// not sure what to do
error: function () {
alert('Error');
}
});
});
</script>
When I click 'upload' it saves the image but not the form and when I click 'create' it saves the form but not the image. How to combine those two?
i cant help you in ajax, but if you would to use c#,
in your razor page put just one form which contains the data and the image, your form of course should like this
#using (Html.BeginForm("--", "--", FormMethod.Post,
new { enctype = "multipart/form-data" }))
and your controller:
public ActionResult FileUpload(HttpPostedFileBase file, YourModel model)
{
//here save your model
if (file != null)
{
//save file
}
}
#using (Html.BeginForm("FileUploadAndSaveData", "UploadImage", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>sticenikSlika</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.sticenikId, "sticenikId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("sticenikId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.sticenikId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.vrijeme, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.vrijeme, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.vrijeme, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.vrijeme, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.vrijeme, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.vrijeme, "", new { #class = "text-danger" })
</div>
</div>
</div>
<label for="file" class="control-label col-md-2">Upload Image:</label>
<div class="col-md-10">
<span class="btn btn-default btn-file">
<input type="file" name="file" id="file" />
</span>
<input type="submit" value="Save" class="submit btn btn-default" id="upload" />
</div>
}
</div>
Create new Action in UploadImage Controller
public ActionResult FileUploadAndSaveData(HttpPostedFileBase file,Model obj) {
FileUpload(HttpPostedFileBase file);/// function Call for Save Image
SaveData(obj); //Function Call for Save Data
}
Im using the following code which is created via MVC5 application and I've field called Type which is drop down list,what I need is that user and password box will be grayed out when you change to Prod currently by defult its Dev(the drop down list field - Type ) the user and passowrd field change to enabled ,how should I do that ?
public class Ad
{
public int ID { get; set; }
public string Name { get; set; }
public string User { get; set; }
public string Password { get; set; }
public IEnumerable<SelectListItem> Type
{
get
{
return new[]
{
new SelectListItem {Value = "D", Text = "Dev"},
new SelectListItem {Value = "p", Text = "Production"}
};
}
}
The create generated code
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Admin</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<
<div class="form-group">
#Html.LabelFor(model => model.User, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.User)
#Html.ValidationMessageFor(model => model.User)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
THe updated code with the script
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script type="text/javascript">
$('select[name="Type"]').change(function () {
if ($(this).val() === 'Production')
{
$('input[name="User"]').prop("disabled",true);
$('input[name="Password"]').prop("disabled",true);
}
else
{
$('input[name="User"]').prop("disabled",false);
$('input[name="Password"]').prop("disabled",false);
}
});
</script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Admin</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<
<div class="form-group">
#Html.LabelFor(model => model.User, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.User)
#Html.ValidationMessageFor(model => model.User)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You need to do it using jquery like this:
<script type="text/javascript">
$(document).ready(function(){
$('select[name="Type"]').change(function(){
if($(this).val() === 'prod')
{
$('input[name="User"]').prop("disabled",true);
$('input[name="Password"]').prop("disabled",true);
}
else
{
$('input[name="User"]').prop("disabled",false);
$('input[name="Password"]').prop("disabled",false);
}
});
});
</script>
Here is Fiddle DEMO
You can use something like this:
$('#dropDownElement').change(function(){
if($(this).text() == "Production")
{
$('#passwordElement').prop('readonly',true);
$('#userElement').prop('readonly',true);
}
else
{
$('#passwordElement').prop('readonly',false);
$('#userElement').prop('readonly',false);
}
})
If prop('readonly',true); will not work, try attr('disabled', 'disabled');