MVC HttpPostedFileBase always null with ajax options - c#

i've encountered some issue where i cannot get the file from the form with ajaxOptions. Below are the code..
#using (Ajax.BeginForm(null, null, new AjaxOptions { OnBegin = "blockUI", OnSuccess = "handleFormSuccess", OnFailure = "onAjaxFailure" }, new { enctype = "multipart/form-data" }))
{
<div class="col-md-4">
<div class="form-group">
#Html.LabelFor(model => model.MediaName, new { #class = "control-label" })
<span class="text-danger" aria-required="true"> * </span>
#Html.TextBoxFor(model => model.MediaName, new { #class = "form-control", #placeholder = LocalizationViewModel.Media.MediaName })
<span class="text-danger">#Html.ValidationMessageFor(model => model.MediaName)</span>
</div>
</div>
<div class="row col-md-12">
<div id="imageContent" class="form-group">
#Html.Label(#LocalizationViewModel.Media.Image, new { #class = "control-label" })
<div class="col-md-12">
#Html.TextBoxFor(model => model.MediaFile, new { type = "file" })
</div>
</div>
</div>
}
if i change to this, it's working file.
#using (Html.BeginForm("CreateMedia", "Media", FormMethod.Post, new { #class = "form-horizontal", enctype = "multipart/form-data" }))
{
<div class="col-md-4">
<div class="form-group">
#Html.LabelFor(model => model.MediaName, new { #class = "control-label" })
<span class="text-danger" aria-required="true"> * </span>
#Html.TextBoxFor(model => model.MediaName, new { #class = "form-control", #placeholder = LocalizationViewModel.Media.MediaName })
<span class="text-danger">#Html.ValidationMessageFor(model => model.MediaName)</span>
</div>
</div>
<div id="imageContent" class="form-group">
#Html.Label(#LocalizationViewModel.Media.Image, new { #class = "control-label" })
<div class="col-md-12">
#Html.TextBoxFor(model => model.MediaFile, new { type = "file" })
</div>
</div>
</div>
}
below are my controller and view model.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CreateMedia(CreateMediaViewModel viewModel)
{ // some code here
}
public class CreateMediaViewModel
{
[Display(ResourceType = typeof(Media), Name = "MediaName")]
[Required(ErrorMessageResourceType = typeof(Message), ErrorMessageResourceName = "MessageFieldRequired")]
public string MediaName { get; set; }
[Display(ResourceType = typeof(Media), Name = "Image")]
public HttpPostedFileBase MediaFile { get; set; }
}
Have anyone have the idea to make it works? :( i been stuck here for some times...thanks..

In the second case, you are explicitly declaring action and controller's names:
Html.BeginForm("Edit", "ClientProgrammeProduct",...
Try the same with Ajax.BeginForm (instead using nulls).
Look here too: How to do a ASP.NET MVC Ajax form post with multipart/form-data?

I added this code on my script section and my file is now detected on my HttpPostedFileBase parameter on my controller.
<script>
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = xhr.responseText;
}
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
</script>

Related

Returning null when trying to upload image file in MVC

I am trying to upload a photo using MVC but it is returning null, I have already used HttpPostedFileBase, yet I still don't know why I am not getting the file. I saw youtube tutorials where they use HTTPPost in their Controller Action Result, but mine is different and I can't update it. Here is my code:
Controller:
public ActionResult CreateOrUpdateOperator(Operator_Profiles operator_Profiles) {
string fileName = Path.GetFileNameWithoutExtension(operator_Profiles.ImageFile.FileName);
string extension = Path.GetExtension(operator_Profiles.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
operator_Profiles.OperatorPic = "../Content/assets/images/operators/" + fileName;
fileName = Path.Combine(Server.MapPath("../Content/assets/images/operators/"), fileName);
operator_Profiles.ImageFile.SaveAs(fileName);
using (db) {
if (operator_Profiles.OperatorID > 0) {
db.Entry(operator_Profiles).State = System.Data.Entity.EntityState.Modified;
} else {
db.Operator_Profiles.Add(operator_Profiles);
}
db.SaveChanges();
ModelState.Clear();
return Json(true, JsonRequestBehavior.AllowGet);
}
}
Model:
public partial class Operator_Profiles
{
public int OperatorID { get; set; }
[DisplayName("Upload Operator Photo")]
public string OperatorPic { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
public string Lastname { get; set; }
public string Firstname { get; set; }
public string Email { get; set; }
[DisplayName("Phone Number")]
public string PhoneNumber { get; set; }
[DataType(DataType.Date, ErrorMessage = "Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> Birthdate { get; set; }
public string Gender { get; set; }
public string Status { get; set; }
}
View:
<form name="operatorForm" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken();
<div class="modal-header">
<h4 class="modal-title">
<span id="headertitle"></span>
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">×</button>
</div>
<div class="modal-body">
#Html.HiddenFor(c => c.OperatorID)
<div class="form-row mb-3">
<div class="col-6">
#Html.LabelFor(x => x.OperatorPic, htmlAttributes: new { #class = "control-label" })
<input type="file" name="ImageFile" class="form-control-file" />
</div>
</div>
<div class="form-row">
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Lastname, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Lastname, new { htmlAttributes = new { #class = "form-control", required = true } })
#Html.ValidationMessageFor(x => x.Lastname, "Invalid Lastname", new { #class = "invalid-feedback" })
</div>
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Firstname, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Firstname, new { htmlAttributes = new { #class = "form-control", required = true } })
#Html.ValidationMessageFor(x => x.Firstname, "Invalid Firstname", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Email, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Email, new { htmlAttributes = new { #class = "form-control", type = "email", required = true } })
#Html.ValidationMessageFor(x => x.Email, "Invalid Email", new { #class = "invalid-feedback" })
</div>
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.PhoneNumber, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.PhoneNumber, new { htmlAttributes = new { #class = "form-control", type = "tel", required = true } })
#Html.ValidationMessageFor(x => x.PhoneNumber, "Invalid Phone Number", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Birthdate, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Birthdate, new { htmlAttributes = new { #class = "form-control", type = "date", required = true } })
#Html.ValidationMessageFor(x => x.Birthdate, "Invalid Birthdate", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Gender, htmlAttributes: new { #class = "control-label" })
#{
var genderList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Male", Value = "Male" }, new SelectListItem { Text = "Female", Value = "Female" }, }, "Value", "Text");
}
#Html.DropDownListFor(x => x.Gender, genderList, "Select Gender", new { #class = "form-control", required = true })
#Html.ValidationMessageFor(x => x.Gender, "Please choose a Gender", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Status, htmlAttributes: new { #class = "control-label" })
#{
var statusList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Clear", Value = "Clear" }, new SelectListItem { Text = "Suspended", Value = "Suspended" }, }, "Value", "Text");
}
#Html.DropDownListFor(x => x.Status, statusList, "Select Status", new { #class = "form-control", required = true })
#Html.ValidationMessageFor(x => x.Status, "Invalid Status", new { #class = "invalid-feedback" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger ml-auto" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-success mr-auto" onclick="SaveOperatorProfile()">Submit</button>
</div>
JS:
function SaveOperatorProfile() {
var modal = $("#operatorModal");
var form = $('form[name = operatorForm]');
form.validate({
errorClass: 'is-invalid',
validClass: 'is-valid',
highlight: function (element, errorClass, validClass) {
$(element).removeClass(validClass).addClass(errorClass);
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
},
errorPlacement: function () {
// Done in highlight/unhighlight
},
submitHandler: function (form) {
alert('Operator Profile has been successfuly saved.');
}
});
if (!form.valid()) {
return;
} else {
var data = form.serialize();
$.post("/Admin/CreateOrUpdateOperator", data, function (res) {
if (res) {
modal.modal('hide');
OprTable.ajax.reload();
}
})
}
}
You aren't getting anything in your ActionResult from the form because you are not asking for it. The "name" of your image object is "ImageFile" as per your HTML input. This needs to match up in your POST method. For example,
[HttpPost]
public ActionResult CreateOrUpdateOperator(HttpPostedFileBase ImageFile, FormCollection col) {
Operater_Profiles operater_Profiles = new Operator_Profiles();
string myString1 = col["SomeName1"].ToString();
string myString2 = col["SomeName2"].ToString();
}
The name of the parameter needs to match with the name from the HTML.
EDIT:
In addition to your controller, you need to actually mark it as a POST method, it's highly recommended. To do this, just add the attribute [HttpPost] before the method declaration.
You are using jquery/js to also post via an ajax method. This is not really how you should be doing this since you aren't doing any dynamic page loading here. You should be making full use of the MVC architecture - why else are you using ASP.NET's MVC?
Instead of using the jquery, you can instead change your input to this:
#using (Html.BeginForm("ACTIONNAME", "CONTROLLERNAME", null, FormMethod.Post, new { enctype = "multipart/form-data" })) {
<input type="file" name="ImageFile" class="form-control-file" />
#Html.LabelFor(x => x.Lastname, htmlAttributes: new { #class = "control-label", #name = "SomeName1" })
#Html.LabelFor(x => x.Firstname, htmlAttributes: new { #class = "control-label", #name = "SomeName2" })
#Html.LabelFor(x => x.Email, htmlAttributes: new { #class = "control-label", #name = "SomeName3" })
}
As you can see, I added names to your data you are posting. These names can be grabbed via FormCollection in the controller.
So after some modifications, It worked! I used FormData instead of serializing my form.
My form now calls the ajax post function if submitted using this modification:
<form name="operatorForm" method="post" enctype="multipart/form-data" onsubmit="SaveOperatorProfile(this)">
Then this is my js code
function SaveOperatorProfile(formData) {
var modal = $("#operatorModal");
var form = $('form[name = operatorForm]');
form.validate({
errorClass: 'is-invalid',
validClass: 'is-valid',
highlight: function (element, errorClass, validClass) {
$(element).removeClass(validClass).addClass(errorClass);
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
},
errorPlacement: function () {
// Done in highlight/unhighlight
},
submitHandler: function (form) {
alert('Operator Profile has been successfuly saved.');
}
});
if (!form.valid()) {
return;
} else {
var ajaxConfig = {
type: "post",
url: "/Admin/CreateOrUpdateOperator",
data: new FormData(formData),
success: function (res) {
if (res) {
modal.modal('hide');
OprTable.ajax.reload();
}
}
}
if ($(formData).attr('enctype') == "multipart/form-data") {
ajaxConfig["contentType"] = false;
ajaxConfig["processData"] = false;
}
$.ajax(ajaxConfig);
return false;
}
}

How to pass array values ​in asp.net mvc?

I am developing an administration page in ASP.NET MVC.
But I have a problem when I edit the film.
When I edit a movie, the sessions appear on my page. And I can remove them.
If I click on edit without removing anything, I get the values ​​well. But when I remove the first session, my array is null.
When I remove the second session, the array comes with this value.
Does anyone know why?
My code:
Edit.cshtml
#using (Html.BeginForm("Edit", "Trans", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID, htmlAttributes: new { #id = "id" })
#Html.HiddenFor(model => model.Selected, htmlAttributes: new { })
<div class="form-group">
#Html.LabelFor(model => model.Titulo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Titulo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Titulo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Descricao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Descricao, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Descricao, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Selected, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Selected, new SelectList(Model.tipos, "ID", "Tipo", Model.Selected), htmlAttributes: new { #id = "ddldropdown", #class = "form-control", #disabled = "disabled" })
#Html.ValidationMessageFor(model => model.Selected, "", new { #class = "text-danger" })
</div>
</div>
<div id="partialDiv">
</div>
<div id="CinemaDiv" style="display:none">
#Html.Partial("Edit_Cinema", Model)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Edit" id="Save" class="btn btn-default" onclick="Fillarrays()" />
</div>
</div>
</div>
}
#section Scripts {
<script type="text/javascript">
//Script para adicionar os Views da pasta Outros no div "partialDiv"
$(document).ready(function () {
var txt = $("#ddldropdown option:selected").text();
var id = $("#id").val();
$.ajax({
type: 'get',
url: '/Outros/Edit_Cinema' + '/' + id,
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
</script>
#*< !--Script Cinema (Partial View)-- >*#
<script type="text/javascript">
//funcao para remover o campo sessao
function rmSessao(id) {
$('#sessao_' + id + '').remove();
}
</script>
<script type="text/javascript">
$('#Save').click(function () {
var form = $("#formH");
var url = form.attr("action");
var formData = form.serialize();
$.post(url, formData, function (data) {
$("#msg").html(data);
//Script para adicionar os campos das partial views
var txt = $("#ddldropdown option:selected").text();
var frm = $("form");
var data = new FormData($("form")[0]);
$.ajax({
url: '/Outros/Edit_Cinema' + '/' + id,
type: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
</script>
}
Edit_Cinema.cshtml
#model ProjetoFinal.Models.ItemViewModel
<div class="form-horizontal">
#*#Html.ValidationSummary(true, "", new { #class = "text-danger" })*#
#Html.HiddenFor(model => model.Cinema.ID)
#Html.LabelFor(model => model.Cinema.Sessoes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="form-group">
#for (int i = 0; i < Model.Cinema_array_Sessoes_Edit.Count; i++)
{
<div class="col-md-10" style="margin-left:195px;margin-bottom:10px" id="sessao_#i">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => Model.Cinema_array_Sessoes_Edit[i], new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => Model.Cinema_array_Sessoes_Edit[i], "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="-" onclick="rmSessao(#i)" />
</span>
</div>
</div>
}
</div>
</div>
Models
ItemViewModel
public class ItemViewModel
{
public int ID { get; set; }
[Display(Name = "Tipo", ResourceType = typeof(Resource))]
//public List<Tipo> tipos { get { return Services.GetTypes(); } } get all types
public List<Tipo> tipos { get; set; }
[Display(Name = "Tipo", ResourceType = typeof(Resource))]
public int? Selected { get; set; }
#region Cinema
public Cinema Cinema { get; set; }
public string[] Cinema_array_sessoes { get; set; }
[Display(Name = "Cinema_array_Sessoes_Edit")]
public List<DateTime?> Cinema_array_Sessoes_Edit { get; set; }
public string[] array_Sessoes_Edit { get; set; }
public string[] array_sessoes { get; set; }
#endregion
public ItemViewModel()
{
tipos = new List<Tipo>();
Cinema = new Cinema();
#region For the cinema
Cinema_array_Sessoes_Edit = new List<DateTime?>();
#endregion
//vai buscar os tipos para aparecer no dropdown
tipos = Services.GetTypes();
}
public class TransmontanosDBContext : DbContext
{
public DbSet<Item> Transmontanos { get; set; }
}
}
TransController.cs
public class TransController : Controller
{
[HttpPost]
public ActionResult Edit(ItemViewModel item, string Latitude, string Longitude)
{
Item obj = new Item();
if (item.Titulo != null)
{
obj.ID=item.ID;
obj.Titulo = item.Titulo;
obj.Descricao = item.Descricao;
obj.Localidade = item.Localidade;
obj.Endereco = item.Endereco;
obj.Latitude =Latitude;
obj.Longitude = Longitude;
obj.Selected = item.Selected;
if (item.Main_Image != null)
{
if (item.Main_Image.ContentLength != 0)
{
//Adiciona a imagem principal à pasta Images
var pathMain = Path.Combine(Server.MapPath("~/Images/"), obj.ID + ".jpg");
item.Main_Image.SaveAs(pathMain);
//Adiciona a imagem principal no ultimo item inserido
Services.AddImage_ToItem(obj.ID);
}
}
Services.EditObject(obj);
return RedirectToAction("Index", "Trans");
}
return View(item);
}
}
OutrosController.cs
public class OutrosController : Controller
{
[HttpPost]
public ActionResult Edit_Cinema(ItemViewModel item)
{
Cinema cinema = new Cinema();
cinema = item.Cinema;
}
}
Results:
Sessions in my movie when I click edit
When I do not remove any of the fields
When I remove the second field
When I remove the first field (Problem)
I would change your view code to this:
#for (int i = 0; i < Model.Cinema_array_Sessoes_Edit.Count; i++)
{
<div class="col-md-10" style="margin-left:195px;margin-bottom:10px" id="sessao_#i">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => Model.Cinema_array_Sessoes_Edit[i], new { htmlAttributes = new { #class = "form-control" #id="id_#i" } })
#Html.ValidationMessageFor(model => Model.Cinema_array_Sessoes_Edit[i], "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="-" onclick="rmSessao(#i)" />
</span>
</div>
</div>
}
Change your delete javascript function:
/funcao para remover o campo sessao
function rmSessao(id) {
$('#id_' + id + '').val(null); //assingn null to date value
$('#sessao_' + id + '').addClass("d-none"); // just hide it
}
And change your controller action:
public ActionResult Edit_Cinema(ItemViewModel item)
{
item.Cinema_array_Sessoes_Edit.RemoveAll(x => x== null);
.... //your code
// you don't need it at all - Cinema cinema = new Cinema();
var cinema = item.Cinema;
}

Mvc Model Validation Errors Not Showing when partial view Inside The another view

When i try to load partial view directly in browser and submit it displaying the error messages but if that same partial view is in another view it is not showing that model error validations. to load partial view inside the view i'm using Ajax.Beginform Method.
When Loading partial view in browser
When including inside the another view
My Partial View
#model FPW.FPWClientModels.SiteClientModel
#if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
#using (Ajax.BeginForm("CreateSite", "Site", null, new AjaxOptions
{
HttpMethod = "POST",
AllowCache = false,
////LoadingElementId = "AjaxOverlay",
//OnSuccess = "SiteOnSaveSuccess",
//OnFailure = "SiteOnSaveFailure",
}, new { #id = "SiteCreateForm" }))
{
<div class="modal-body">
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.SiteName, htmlAttributes: new { #class = "control-label" })
<div class="col-md-12">
#Html.EditorFor(model => model.SiteName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SiteName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SiteAddress, htmlAttributes: new { #class = "control-label" })
<div class="col-md-12">
#Html.EditorFor(model => model.SiteAddress, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SiteAddress, "", new { #class = "text-danger" })
</div>
</div>
<div class="modal-footer">
<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>
}
<script>
function SiteOnSaveSuccess(resp) {
}
function SiteOnSaveFailure(resp) {
}
</script>
My Controller
public ActionResult CreateSite()
{
SiteClientModel oSiteClientModel = new SiteClientModel();
return PartialView(oSiteClientModel);
}
//Create Site
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateSite(SiteClientModel oSiteClientModel)
{
if (ModelState.IsValid)
{
var saveSiteDetails = oSiteApiController.CreateSiteDetails(oSiteClientModel);
return PartialView(saveSiteDetails);
}
else
{
oSiteClientModel.ReturnValue = new ReturnValue { IsSuccess = false, ReturnType = ReturnType.Error, Message = "Form Not Valid" };
}
return PartialView("CreateSite",oSiteClientModel);
}
Found the error. It was not used Update target id in ajax option. After use UpdateTargetId and pointed it to the form id it is working fine as expected

Json is returning "new {success = true } " as String on a blank page when FormData is used in ajax method

I am trying to get data and images from popup modal via ajax method, I am using formdata to put data and images and send it to my action(which returns JsonResult).
Data is sent to action and I can save it to database but Json does not redirects to view, instead it returns "{success = true}" as a String on a blank page.
I understand that the problem is formdata as data, I tried to send only data (data: $(this).serialize()), without images and it got right(redirected me to my view). Yet I don't understand what is wrong i case of formdata, I have been seaching solution for 2 days but can't find proper answer
//model class
public class ArticlesCustomClass
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
[Display(Name = "Title")]
public string Title { get; set; }
[Required]
[AllowHtml]
[Display(Name = "Content")]
public string Content { get; set; }
public HttpPostedFileBase[] Images { get; set; }
}
//action
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult CreateArticles(ArticlesCustomClass model)
{
if (ModelState.IsValid)
{
var filesList = new List<HttpPostedFileBase>();
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase file = Request.Files[i];
filesList.Add(file);
}
ArticlesData.CreateArticles(model,filesList.ToArray());
return Json(new {success = true });
}
return Json(model, JsonRequestBehavior.AllowGet);
}
//View
#using (Html.BeginForm("CreateArticles", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<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 long-textbox required" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Content, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Content, htmlAttributes: new { #class = "form-control long-textbox ckeditor required", #rows = 10 })
#Html.ValidationMessageFor(model => model.Content, "", new { #class = "text-danger" })
</div>
</div>
<div id="uploader" class="form-group">
<div class="control-label col-md-2">Add images</div>
<div class="col-md-10">
<div><input type="file" id="UploadFile" class="btn btn-primary" name="Images" multiple></div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</div>
</div>
}
//ajax method
function bindForm(dialog) {
var formdata = new FormData($('form', dialog)).get(0);
$('form', dialog).submit(function () {
$('#progress').show();
$.ajax({
url: this.action,
type: this.method,
data: formdata,
contentType: false,
processData: false,
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
$('#progress').hide();
location.reload();
} else {
$('#progress').hide();
$('#myModalContent').html(result);
bindForm();
}
}
});
return false;
});
}

Passing a javascript array to controller create action

There is one issue that I cannot find an ideal solution so I'm asking here.
How can I pass an array created in jQuery from view into controller action create.
I have a class model person
public class Person
{
public int personId {get; set;}
public string Name {get; set;}
public int Age {get; set;}
public virtual ICollection <Friend> Friends {get; set;}
}
the controller action create:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Age")]Person person)
{
if (ModelState.IsValid)
{
db.Person.Add(person);
db.SaveChanges();
return View(configuration);
}
The scenario is that I create a new person and add to that person a list of friends. At this point I figured that I create an array of friends in jQuery but have no idea how to post it into create action.
View of create:
#using Life.models
#model Life.models.Person
#{
ViewBag.Title = "Create person";
}
<script src="~/Scripts/jquery-2.1.1.min.js"></script>
<script>
$(function () {
var FriendsIdArray = [];
var FriendsTxtArray = [];
$('#chooseFriendClick').click(function () {
if ($('#friends :selected').text() != "---Select---") {
var Id = $('#friends').val();
var Txt = $('#friends :selected').text();
var test = ifExist(FriendsIdArray, Id);
if (test != null) {
FriendsIdArray.splice(test, 1);
FriendsTxtArray.splice(test, 1);
} else {
FriendsIdArray.push(Id);
FriendsTxtArray.push(Txt);
}
$('#FriendsList').text(FriendsTxtArray);
}
function ifExist(arr, obj) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == obj)
return i;
}
}
});
</script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<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.Age, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Age, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Age, "", 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 class="form-group">
#Html.DropDownList("friends", new SelectList(dbContext.Friends, "FriendId", "Name"), "---Select---", new { #class = "form-control" })
<a id="chooseFriendClick" href="#">Choose Friend</a>
#Html.Label("Choosen Friends:", new { #class = "control-label col-md-2" }) <text id="FriendsList" class="control-label col-md-1"></text>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Any help will be appreciated. I want to pass FriendsIdArray to the controller.

Categories

Resources