ASP NET MVC RAZOR Upload Multiple Images FileList - c#

I'm new in asp net and I have a List of images and I want to send through javascript to the controller.
I'm using FileList and here is an example.
.Create.cshtml
<div class="form-group">
#Html.LabelFor(model => model.description, "Escolha as Imagens", htmlAttributes: new { #class = "control-label col-md-2" })
<input id="files" type="file" name="files[]" />
<br>
<div id="preview"></div>
</div>
#section Scripts{
<script type="text/javascript">
function handleFileSelect(evt) {
var files = evt.target.files;
var f = files[0];
//kiem tra co fai file anh
if (f.type.match('image.*')) {
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var span = document.createElement('span');
span.innerHTML = [
'<img class="thumb" src="', e.target.result, '" title="', escape(theFile.name),
'"/><span class="remove_img_preview"></span>'
].join('');
document.getElementById('preview').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
$('#files').change(function(evt) {
handleFileSelect(evt);
});
$('#preview').on('click',
'.remove_img_preview',
function() {
$(this).parent('span').remove();
});
$('#btnSave').click(function() {
$.ajax({
url: '/Dishes/Create',
data: { files: files },
type: "POST",
cache: false,
datatype: "html",
success: function(data) {
console.log(data);
},
error: function(jqXhr, textStatus, errorThrown) {
//do your own thing
alert("fail");
}
});
});
</script>
}
</fieldset>
<div class="form-group">
<div class="footer text-center">
<button class="btn btn-fill btn-info" name="btnSave" id="btnSave">Inserir novo</button>
</div>
</div>
Controller.cs
public ActionResult Create()
{
ViewBag.idTypeDish = new SelectList(db.TypeDish, "idTypeDish", "name");
return View();
}
// POST: Dishes/Create
[HttpPost]
public ActionResult Create(IEnumerable<HttpPostedFileBase> files)
{
return View();
}
In the controller, files are always null.
I'm using that example, http://jsfiddle.net/Lwczca6p/1/, I just adapt to my project.

You've got a few problems. First, you're trying to use files with your AJAX, but that variable was defined in the scope of another function (i.e. you don't have access to it here). Second, when using jQuery's $.ajax to do a file upload, you need to set the processData option to false. Here's how I would handle it:
$('#MyForm').on('submit', function (e) {
e.preventDefault();
var formData = new FormData(this); // `this` is the form instance
$.ajax({
url: '/path/to/handler',
type: 'POST',
data: formData,
processData: false,
contentType: 'multipart/form-data',
success: function (data, textStatus, jqXHR) {
// do something on success
},
error: function (jqXHR, textStatus, errorThrown) {
// do something on error
}
});
});

Try this, first create a model for your view:
public class FileModel
{
[Required(ErrorMessage ="Please select file.")]
[Display(Name ="Browse File")]
public HttpPostedFileBase[] files { get; set; }
}
Then, edit your view to this (to enable upload many files you need to put multiple="multiple" in your element):
#model Models.FileModel
#using (Html.BeginForm("Create", "YourController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.files, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.files, "", new { #type = "file", #multiple = "multiple" })
#Html.ValidationMessageFor(model => model.files, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Upload" class="btn btn-primary" />
</div>
</div>
</div>
}

Related

Display value from controller based on two dropdown selection on the view(when select both of them at the same time). MVC asp.net

On the product output insert page, when user select from two dropdown lists(depoId and materialId) at the same time, I would like to display the stock quantity (stockAmount) of the product with the help of material id and the depot id. I do not know how I display on the view part and how I write based on two dropdownlist selection.
Create.cshtml
#model StockControl.Models.EntityFramework.OutgoingProduct
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.materialId, "Material Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("materialId", null, htmlAttributes: new { #class = "form-control chosen" })
#Html.ValidationMessageFor(model => model.materialId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.depoId, "Product Outlet", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("depoId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.depoId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-success" />
</div>
</div>
</div>
}
#section scripts{
<script>
$(function () {
$('.chosen').chosen();
});
$("#materialId", "#depoId").change( function (event) {
var materialId = $(this).val();
var depoId = $(this).val();
$.ajax({
url: "#Url.Action("GetStock", "OutgoingProduct")",
data: { id : materialId, id: depoId },
type: "Get",
dataType: "html",
success: function (data) {
document.write(model.stockAmount);
$("#divPartialView").html( data );
}
});
});
</script>
}
use ajax to send these id to controller
import jquery
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
listen the select change event and send data to controller
<script type="text/javascript">
$(document).ready(function () {
$('#depoId').change(function () { sendDataByAjax(); });
})
function sendDataByAjax() {
// make sure two dropdownlists have selected option
var materialId= $('#materialId option:selected').val();
var depoId= $('#depoIdoption:selected').val();
if (!materialId || !depoId) {
// one of dropdownlist doesn't select an option yet
}
var DTO = {
'materialId': materialId,
'depoId': depoId
};
$.ajax({
type: "POST",
url: "#Url.Action("GetStock", "OutgoingProduct")",
data: JSON.stringify(DTO),
contentType: "application/json",
success: function (data) {
// append data into your target part of view
}
});
}
</script>

Mvc Save Items From Cascading DropdownList

This is my controller.
public class DokuzasController : Controller
{
schoolEntities se = new schoolEntities();
public ActionResult Index()
{
IEnumerable<DersViewModel> leclist;
HttpResponseMessage responselec = GlobalVariables.LecturesClient.GetAsync("dokuzas").Result;
leclist = responselec.Content.ReadAsAsync<IEnumerable<DersViewModel>>().Result;
return View(leclist);
}
public ActionResult AddOrEdit()
{
List<ders> dersList = se.ders.ToList();
ViewBag.dersList = new SelectList(dersList, "DersID", "Ders1");
return View();
}
public JsonResult GetDersList(int DersID)
{
se.Configuration.ProxyCreationEnabled = false;
List<saat> saatList = se.saat.Where(x => x.DersID == DersID).ToList();
return Json(saatList, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult AddOrEdit(DersViewModel lec)
{
if (lec.LectureId == 0)
{
HttpResponseMessage response = GlobalVariables.LecturesClient.PostAsJsonAsync("dokuzas", lec).Result;
TempData["SuccessMessage"] = "Kaydedildi.";
}
else
{
HttpResponseMessage response = GlobalVariables.LecturesClient.PutAsJsonAsync("dokuzas/" + lec.LectureId, lec).Result;
TempData["SuccessMessage"] = "Güncellendi.";
}
return RedirectToAction("Index");
}
}
And this is AddOrEdit part.
#model Mvc.Models.DersViewModel
<div class="container">
<div class="form-group">
#if (ViewBag.dersList != null)
{
#Html.DropDownListFor(model => model.DersID, ViewBag.dersList as SelectList, "--Lecture--", new { #class = "form-control" })
}
</div>
<div class="form-group">
#Html.DropDownListFor(model => model.SaatID, new SelectList(" "), "--Time--", new { #class = "form-control" })
</div>
</div>
#using (Html.BeginForm())
{
<div class="form-group">
<input type="submit" value="Kaydet" class="btn button" />
<input type="reset" value="Sil" class="btn button" />
</div>
}
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function () {
$("#DersID").change(function () {
$.get("/Dokuzas/GetDersList", { DersID: $("#DersID").val() },
function (data) {
$("#SaatID").empty();
$.each(data, function (index, row) {
$("#SaatID").append("<option value='" + row.SaatID + "'>" + row.Saat1 + "</option>");
});
});
});
});
</script>
I create a cascading dropdown list for lecture and time but i cannot save it to the table. When i choose items and select submit button i can submit only null to the table. It did not save what i choose from the dropdownlist. How can i save from my cascading dropdown list to the table?
Your Dropdowns are not inside your Form, so they are not included in the post. Try the below code for your view.
#model Mvc.Models.DersViewModel
#using (Html.BeginForm())
{
<div class="container">
<div class="form-group">
#if (ViewBag.dersList != null)
{
#Html.DropDownListFor(model => model.DersID, ViewBag.dersList as SelectList, "--Lecture--", new { #class = "form-control" })
}
</div>
<div class="form-group">
#Html.DropDownListFor(model => model.SaatID, new SelectList(" "), "--Time--", new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<input type="submit" value="Kaydet" class="btn button" />
<input type="reset" value="Sil" class="btn button" />
</div>
}
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function () {
$("#DersID").change(function () {
$.get("/Dokuzas/GetDersList", { DersID: $("#DersID").val() },
function (data) {
$("#SaatID").empty();
$.each(data, function (index, row) {
$("#SaatID").append("<option value='" + row.SaatID + "'>" + row.Saat1 + "</option>");
});
});
});
});
</script>

asp.NET mvc, get model list values from view

I am new to mvc and am trying to do something like in the below image (im not using partial views).
I have an IEnumerable property on Model
Like in this image, (i have not enough reputation to show image directly)
but on controller if i put FormCollection as parameter to accepting post method when i process same name fields i get an extra character ',', which might be also used by user...
Any idea....
[EDIT]
My view
#model Models.Question
#{
ViewBag.Title = "Add";
}
<h2>Add</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Question</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.SurveyId)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#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">
#Html.LabelFor(model => model.QuestionTypeId, "Question type", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.QuestionTypeId, new SelectList(ViewBag.QuestionTypes, "QuestionTypeId", "Name"), new { #class = "form-control col-md-10" })
<button type="button" class="btn btn-default addAnswer hide"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
#Html.ValidationMessageFor(model => model.QuestionTypeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group hide">
#Html.LabelFor(model => model.Answers, "Options", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="allAnswers">
#Html.ValidationMessageFor(model => model.Answers, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Sort, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Sort, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Sort, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Mandatory, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Mandatory)
#Html.ValidationMessageFor(model => model.Mandatory, "", new { #class = "text-danger" })
</div>
</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", "Question", "Survey", new { id = Model.SurveyId }, null)
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval", "~/Scripts/QuestionAdd.js")
}
Controller
[HttpGet]
public ActionResult Add(long id)
{
var question = new Models.Question();
question.SurveyId = id;
ViewBag.QuestionTypes = BLL.Questions.GetQuestionTypes();
return View(question);
}
[HttpPost]
public ActionResult Add(FormCollection coll)
{
if (ModelState.IsValid)
{
var question = new Models.Question();
question.Name = coll["Name"];
byte qid = 0, sort = 0;
bool mandatory = false;
byte.TryParse(coll["QuestionTypeId"], out qid);
byte.TryParse(coll["Sort"], out sort);
bool.TryParse(coll["Mandatory"], out mandatory);
question.QuestionTypeId = qid;
question.Sort = sort;
question.Mandatory = mandatory;
foreach (var answer in coll["Answers"])
question.Answers.Add(new Models.Answer() { Value = answer + "" });
if (question != null)
{
if (BLL.Questions.Insert(question) != null)
ViewBag.Message = "Successfully inserted";
else
ViewBag.Message = "Insert could not be done";
return RedirectToAction("Index", "Question", new { questionId = question.QuestionId });
}
}
return View();
}
When (+) clicked
$('#allAnswers').append(
'<div class="input-group col-lg-4">' +
'<input class="form-control" name="Answers"> ' +
'<div class="input-group-btn">' +
' <button type="button" class="btn btn-default removeAnswer"><span class="glyphicon glyphicon glyphicon-trash" aria-hidden="true"></span></button>' +
'</div> </div>');
As discussed.. here is how i would approach this.
I have a view model to hold the questions and answers and the selected question to which we will be adding answers.
public class CurrentViewModel
{
public string QuestionSelected { get; set; }
public List<SelectListItem> Questions { get; set; }
public List<string> Answers { get; set; }
}
Then in your controller we have an action to return the view, an action to get the answers for the selected question, an action to add a new answer for the selected question and also a save method which just demonstrates the final model content posted.
public class TestController : Controller
{
public ActionResult Test()
{
var model = new CurrentViewModel()
{
Questions = new List<SelectListItem>()
{
new SelectListItem()
{
Text = "Question 1",
Value = "Question 1"
},
new SelectListItem()
{
Text = "Question 2",
Value = "Question 2"
}
},
Answers = new List<string>()
};
return View("Test", model);
}
public PartialViewResult GetAnswers(CurrentViewModel model)
{
model.Answers = new List<string>();
//model.Answers = Get Answers from some service based on QuestionSelected?!
model.Answers.Add("Answer 1");
model.Answers.Add("Answer 2"); //Add manuall for example
return PartialView("_Answers", model);
}
public PartialViewResult AddAnswer(CurrentViewModel model)
{
model.Answers.Add("Add answer here...");
return PartialView("_Answers", model);
}
public ActionResult SaveQuestionsAndAnswers(CurrentViewModel model)
{
if (model.Questions.Count == 0)
{
}
return View("Test", model);
}
}
Then we have a main view for showing the questions dropdown and a partial view that will show us the answers.
Main View
#model TestMVC.Models.CurrentViewModel
#{
ViewBag.Title = "Test";
}
<link href="~/Content/StyleSheets/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/Scripts/jquery-2.2.3.js"></script>
<script src="~/Content/Scripts/jquery-ui-1.11.4.js"></script>
<div id="divBodyContent">
<div>
<h3>Q & A</h3>
</div>
#using (Html.BeginForm("SaveQuestionsAndAnswers", "Test", FormMethod.Post, new { id = "frmQandA" }))
{
#Html.Label("lblQ", "Questions", new { #class = "form-control inline" })
#Html.DropDownListFor(model => model.QuestionSelected, Model.Questions, "Select--", new { #class = "form-control inline", id="ddQuestions" })
<div id="divAnswers">
#Html.Partial("_Answers")
</div>
<div style="margin-top: 1%;">
<button id="btnSave" type="submit" class="btn btn-primary" style="margin-left: 4px; margin-bottom: 10px; width: 7%">save</button>
</div>
}
</div>
<script>
$("#ddQuestions").on("change", function() {
var myData = $('#frmQandA').serialize();
$.ajax({
type: "POST",
url: "#Url.Action("GetAnswers", "Test")",
data: myData,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function(data) {
$("#divAnswers").html(data);
}
})});
</script>
Partial View
#model TestMVC.Models.CurrentViewModel
<link href="~/Content/StyleSheets/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/Scripts/jquery-2.2.3.js"></script>
<script src="~/Content/Scripts/jquery-ui-1.11.4.js"></script>
<div>
#for (var counter = 0; counter <= (Model.Answers.Count - 1); counter++)
{
#Html.TextBoxFor(model => model.Answers[counter], new {#class = "form-control inline"})
}
<div style="margin-top: 1%;">
<button id="btnAddAnswer" type="button" class="btn btn-primary" style="margin-left: 4px; margin-bottom: 10px; width: 7%">Add</button>
</div>
</div>
<script>
$("#btnAddAnswer").on("click", function() {
var myData = $('#frmQandA').serialize();
$.ajax({
type: "POST",
url: "#Url.Action("AddAnswer", "Test")",
data: myData,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function (data) {
$("#divAnswers").html(data);
}
})});
</script>
I've tested this locally and it works. In a nutshell, when we need a new answer adding to the model, we add it in server side so we can then bind to the model in the browser. We do this via an Ajax call on the change event of the questions drop down. The partial view iterates through each answer via a counter which generates a unique id and textbox for each answer. Adding a new answer is also achieved via ajax. These can then all be posted back.
Hope that helps.

how to return partial view as html using ajax

i want to return partial view as html so i can render in div as html, but its not working, i don't able to find the issue why its not working, here is my code.
function getPartial(id) {
$.ajax({
type: "POST",
url: "/Home/GetPartial",
contentType: "application/html",
data: { ID: id },
success: function (response) {
$(".ui-layout-east").html(response);
alert(response);
}
});
}
in my controller i am doing like this.
[HttpPost]
public ActionResult GetPartial(int ID)
{
var gopal = DataAccess.DataAccess.FillDetailByID(ID);
return PartialView("parent", gopal);
}
but when i return as json then its working, i don't understand, please help me how to resolve this.
below is my partial which i want to return.
#model WebTreeDemo.Models.Employee
<div id="widget">
<div id="x">
#using (Html.BeginForm("Home", "Update", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.EmpCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EmpCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EmpCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.JobDesc, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.JobDesc, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.JobDesc, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DateOfJoining, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateOfJoining, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DateOfJoining, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="submitButton" value="Save" class="btn btn-default" />
#Html.HiddenFor(x => x.ID)
</div>
</div>
</div>
}
</div> <!-- end of #foo -->
Try with this...
function getPartial(id) {
$.ajax({
type: "POST",
url: "/Home/GetPartial",
contentType: "application/html",
dataType: "html",
data: { ID: id },
success: function (response) {
$(".ui-layout-east").html(response);
alert(response);
}
});
}
Try this one: Pass contenttype as json as your data is in json or normal a javascript object.
but datatype must be in html as you are returning View from server so it will work fine for you.
var data = {"ID":123}
$.ajax({
url: "/Home/GetPartial",
type: "POST",
dataType : "html",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(data),
success : function(response) {
$(".ui-layout-east").html(response);
alert(response);
},
});

Retrieving ViewModel data collection is null

I am passing model from view to controller. in my viewmodel List<TradeLaneDetailsDTO> is null always, and i am passing my data through ajax. what is the problem in my code.
please help me...
here is my viewmodel
public class SLAViewModel
{
public List<TradeLaneDetailsDTO> Items { get; set; }
}
here is my view
#using (Html.BeginForm("SaveSLA", "SLAMgmt", FormMethod.Post, htmlAttributes: new { #class = "form-horizontal", #role = "form", id = "frmEstDays" }))
{
for (int i = 0; i < Model.Items.Count; i++)
{
<div class="form-group">
#Html.LabelFor(model => model.Items.ElementAt(i).legname, Model.Items.ElementAt(i).legname, new { #class = "col-md-4" })
<div class="col-md-3">
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
</div>
</div>
}
<div class="form-group">
<div class="offset-3 col-md-8">
<button id="btnSave" type="button" title="Save" class="btn btn-success" onclick="getPage1('#Url.Action("SaveSLA", "SLAMgmt")')">
<span class="glyphicon glyphicon-floppy-disk"></span>Save
</button>
</div>
</div>
}
and here is my ajax function
function getPage1(page)
{
alert("get page1");
$.ajax({
type: "POST",
url: page,
data: $("#frmEstDays").serialize(),
xhrFields: {
withCredentials: true
},
success: function (html) {
alert(html.responseText);
},
error: function (data) {
var error = "Error ";
}
});
}
here is my controller functions
public ActionResult SaveSLA(SLAViewModel slavModel)
{
string[] ErrorMessageArray = new string[4];
int errorIndex = 0;
return anything;
}
Simply use model=>model.Items[i].PROPERTYNAME as below
#Html.TextBoxFor(model => model.Items[i].estddays, new { #class = "form-control", type = "text", MaxLength = "10" })
hope this will help
Please remove type = "text" from TextBoxFor html helper.
#Html.TextBoxFor(model => model.Items.ElementAt(i).estddays, new { #class = "form-control", MaxLength = "10" })
The HtmlTextboxFor always creates a textbox <input type="text" />. So you don't have to specify explicitly.

Categories