ASP.Net MVC AJAX upload file to controller is being submitted twice - c#

I have an ASP.Net MVC application. I need to send a file to Controller with ajax. but I have twice request.
#using (Ajax.BeginForm("Create", "MyController", new { area = "" },
new AjaxOptions
{
HttpMethod = "POST",
OnBegin = "onBegin",
OnSuccess = "onSuccess(data)"
}, new { enctype = "multipart/form-data", id = "myform" }))
{
<section class="col col-md-12">
#Html.DisplayFor(model => model.Title)
<label class="input">
#Html.TextBoxFor(model => model.Title)
</label>
</section>
<section class="col-md-6">
<label class="label text-left">
My File
</label>
<label for="file" class="input input-file">
<div class="button">
<input name="files" type="file" id="file" onchange=" this.parentNode.nextSibling.value = this.value ">choose...
</div>
<input type="text" readonly="" class="text-right">
</label>
</section>
<button type="submit" class="btn btn-primary">
Submit
</button>
}
Controller Action, When posting my data using AJAX, here's twice request in my Action.
[HttpPost]
public ActionResult Create(HttpPostedFileBase files, CreateViewModel model)
{
// The Request comes here twice.
}
and my references in page,
<script src="/Scripts/jquery.min.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="/Scripts/bootstrap/bootstrap.min.js"></script>
<script src="/Scripts/jquery.form.js"></script>
$(function () {
$('#myform').ajaxForm({
beforeSubmit: ShowRequest,
success: SubmitSuccesful,
error: AjaxError
});
});
function ShowRequest(formData, jqForm, options) {
var queryString = $.param(formData);
alert('BeforeSend method: \n\nAbout to submit: \n\n' + queryString);
return true;
}
function AjaxError() {
alert("An AJAX error occured.");
}
function SubmitSuccesful(responseText, statusText) {
alert("SuccesMethod:\n\n" + responseText);
}
what should I do?

The problem is that you are using ASP.NET MVC AjaxForm as well jQuery ajaxForm plugin. When you press submit button, the request is sent by MVC as well jQuery.

Related

Using Html.BeginForm and ajax call same action conflict?

When I try to add Ajax to pass another data into my action controller my model parameter was affected the value was null and my Ajax parameter has a value. I do not think it is because I am using Html.beginform('index', 'payable') and I used Ajax url: '#Url.Action("index", "payable")', with the same ActionResult.
You can see the reference below.
#using (Html.BeginForm("index", "payable", FormMethod.Post, new { enctype = "multipart/form-data" }))<div class="col-md-2">
<div class="form-group">
#Html.LabelFor(x => x.Amount, new { #class = "form-label" })
#Html.TextBoxFor(x => x.Amount, new { #class = "form-control" })
</div>
</div>
<div class="col-md-2">
<div class="form-group">
#Html.LabelFor(x => x.ImagePath, new { #class = "form-label" })
<input type="file" name="file" id="files" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<button type="submit" id="btnUpload" class="btn btn-primary btn-sm" onclick="saveSelected()"><i class="fas fa-save"></i> Submit Payment</button>
</div>
</div>{
My Ajax
function saveSelected() {
$.ajax({
url: '#Url.Action("index", "payable")',
type: 'POST',
data: { ids: ids },
traditional: true,
success: function (data) {
alert("success");
}
});
}
My Controller
public ActionResult Index(PayableFormModel model, HttpPostedFileBase file, int[] ids)
{
return View();
}
Html.Beginform and ajax cannot use at same time,even you add a
onclick function. So the ajax won't work and all data are submitted
by form. If you want to submit model and any other data, put all them into form or only use ajax.
When you upload file, model cannot get file's name or path directly. You should store file into a folder or directory,then assign this path to model's imagepath.(Examle code is blew)
In index page, {} should follow using(), otherwise it will report error.
public ActionResult Index(PayableFormModel model,HttpPostedFileBase file,int[] ids)
{
string filepath = Server.MapPath("~/image/");
Directory.CreateDirectory(filepath);
file.SaveAs(Path.Combine(filepath, file.FileName));
model.ImagePath = filepath + file.FileName ;
return View();
}

Filling other controls by combobox selected item asp.net core Razor Page

I'm new to asp.net core and trying to learn… I've a razor page with some controls. (Asp.Net Core 2.2) and i wanna fill text-boxes or other controls by selecting an item from a combobox… When i used GET method, the data contains html tags… If i use POST no value comes back. Need help to understand if my way is wrong or not
the cshtml as follows
<script type="text/javascript">
$(function () {
$("#txtTcKimlikNo").change(function () {
$.ajax({
url: '#Url.Action("fillOgrenciData")',
type: "POST",
data: { "code": $(this).val() },
"success": function (data) {
if (data != null) {
alert(data);
$("#name").val(data.Okulno);
alert($("#name").val());
alert("ok");
}
}
});
});
});
</script>
<section class="well">
<h2 class="ra-well-title">Öğrenci Bilgileri</h2>
<div class="form-group">
<label class="control-label col-sm-4" for="name">Adı Soyadı</label>
<div class="col-sm-8 col-md-6">
<input id="name" class="k-textbox" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-4" for="birthday">Doğum Tarihi</label>
<div class="col-sm-8 col-md-6">
#(Html.Kendo().DatePicker().Name("date").Value("10/09/1979"))
</div>
</div>
</div>
<div class="form-horizontal form-widgets col-sm-6">
<div class="form-group">
<label class="control-label col-sm-4" for="txtTcKimlikNo">Tc Kimlik No</label>
<div class="col-sm-8 col-md-6">
#(Html.Kendo().ComboBox()
.Name("txtTcKimlikNo")
.DataTextField("Tckimlikno")
.DataValueField("Ogrid")
.BindTo(Model.ogrenciler)
.Filter("Contains")
.Height(300)
.Template("<span class=\"k-state-default\">#: data.Adisoyadi #<p>#: data.Okulno #</p></span>"))
</div>
</div>
</div>
and the cshtml.cs is as follows
public void OnGet()
{
Data = _db.Okul.ToList();
EgOgyillar = _db.PrEgogyillar.ToList();
ogrenciler = _db.Ogrenci.ToList();
}
public JsonResult ReadOkul()
{
return new JsonResult(_db.Okul.ToList());
}
[HttpPost]
public ActionResult fillOgrenciData(string code)
{
var query = from c in _db.Ogrenci
where c.Tckimlikno == Convert.ToInt64(code)
select c;
return new JsonResult(query);
}
But i can't fill the name textbox with data.Okulno. It always comes undefined. By the way i didn't use models in app. If it's need to used, i will restart to write the app.

Passing and handling of varibles to a function with AJAX in MVC

I'm having trouble passing a variable into a function in my view. I'm fairly new to MVC and not sure how I save and pass information.
#model Models.Schedule.SheduleModel
#{
Layout = null;
}
<div>
<div class="tableRow">
<p>Make a schedule reminder.</p>
</div>
<div class="tableRow tableRowHeading">
<div class="row" style="width: 210px">Name</div>
<div class="row" style="width: 210px">Number</div>
</div>
#foreach (var shedule in Model.ScheduleList)
{
<div class="tableRow">
#using (Html.BeginForm("UpdateSchedule", "Schedule", FormMethod.Post))
{
<div class="cell" style="width: 210px">
#Html.HiddenFor(model => schedule.Id)
#Html.TextBoxFor(model => schedule.Name, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => schedule.Name)
</div>
<div class="cell" style="width: 210px">
#Html.TextBoxFor(model => agent.ContactNumber, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => agent.ContactNumber)
</div>
<div class="cell">
<button name="Update" type="submit" value="Update" class="button" title="Update details">
<span class="text">Update</span>
</button>
</div>
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule();" value="Delete">
<span class="text">Delete</span>
</button>
</div>
}
</div>
}
</div>
#Scripts.Render("~/bundles/jqueryval")
<script>
function deleteFromSchedule() {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + Id,
data:
{
Id: Id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>
I'm trying to pass the schedule Id in HiddenFor into the delete function but everything I try doesn't work, i'm also curious on how to handle the information gotten from the text box in a later unwritten div, I'd like to produce text on the screen saying
User #Model.Name and number #Model.Number will be notified of schedule change but I keep displaying blank spaces. an I use the form I'm creating for this information, what would the syntax be?. My method in the schedule controller is very straight forward.
[HttpPost]
public void UpdateSchedule(int Id)
{
////do stuff here
}
The simplest way is to add your id from the schedule into the inline function call (using razor), and add an id param into your javascript delete function:
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule(#schedule.Id);" value="Delete">
<span class="text">Delete</span>
</button>
</div>
<script>
function deleteFromSchedule(id) {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + id,
data:
{
Id: id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>

Pass data from html form to c# webservice using ajax

I have a form html made using bootstrap in phpstorm, and I want to pass the information to a c# webservice using ajax.
Bust I have some doubts in what to put in the ajax url (represented bellow).
This is my html/bootstrap form:
<form role="form" action="" method="post" class="login-form">
<div class="form-group">
<label class="sr-only" for="form-username">Email</label>
<input type="text" name="form-username" placeholder="Email....." class="form-username form-control" id="form-email">
</div>
<div class="form-group">
<label class="sr-only" for="form-text">Type Order</label>
<input type="text" name="order" placeholder="Tipo Encomenda" class="form-text form-control" id="textbox1">
</div>
<span id="spnGetdet" style="font-size:x-large" />
<div class="form-group">
<label class="sr-only" for="form-number">Number</label>
<input type="number" min="0" max="150" name="orderQuantity" placeholder="Numero Peças" class="form-number form-control" id="form-number">
</div>
<div class="form-group">
<label class="sr-only" for="form-radio">Urgente</label>
<label class="radio-inline">
<input type="radio" name="optradio">Urgente</label>
<label class="radio-inline">
<input type="radio" name="optradio">Não Urgente
</label>
</div>
<button type="submit" class="btn btn-primary" id="submitOrder">Enviar</button>
</form>
And this is my ajax/jquery code:
<script type="text/javascript">
$("#submitOrder").click(function(){
$(document).ready(function () {
var TextBox1 = $("#textbox1");
TextBox1.change(function (e) {
var Name = TextBox1.val();
if (Name != -1) {
Getdet(Name);
}else {
<?php echo "erro"?>;
}
});
});
}
function Getdet(Name) {
$.ajax({
type: "POST",
url: "",
data: "{'Custname':'" + Name + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response){
$("#spnGetdet").html(response.d);
},
failure: function (msg)
{
alert(msg);
}
});
}
</script>
And the last my c# webservice (this is a test, and i only want to collect the type of the order):
[WebMethod]
public String GetCustdet(string Custname)
{
return Custname;
}
So, if i have the project(website) made in phpstorm and webservice visual studio, what do I have to put in the url of ajax to reach the web service???
P.S: WebSite running in xampp
I'm assuming that, you are using MVC pattern I have given following url. You should replace controller name in [controller] place. You should replace localhost:5566 in or whatever in to [server-name].
option 1: [GET] http://[server-name]/[controller]/GetCustdet?Custname=Jhon
without data.
option 2: [POST] http://[server-name]/[controller]/GetCustdet
with data: '{Custname:"Jhon"}'
Otherwise, If you are using Asp.Net template to create the WebMethod then you should use the aspx page name in place the of [controller].
Alternatively, you have Route configurations to customize the URL and the data.

How to correctly use Partial views with Ajax Begin form

I have the following code, in my index.cshtml
#using Kendo.Mvc.UI;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Custom;
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#model PresupuestosGenerale
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="">
<div id="ContenedorPresupuestoGeneral">
#Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
<br />
<br />
Then I have the following PartialView
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using Kendo.Mvc.UI;
#model PresupuestosGenerale
<div class="panel panel-default">
<div class="panel-heading">
#using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "ContenedorPresupuestoGeneral", InsertionMode = InsertionMode.Replace }))
{
#Html.HiddenFor(h => h.PresupuestoGeneralId)
#Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<label>Presupuesto Global xx</label>
<br />
#(Html.Kendo().NumericTextBoxFor(e => e.PresupuestoGlobal)
.Decimals(0)
.DecreaseButtonTitle("Decrementar")
.IncreaseButtonTitle("Incrementar")
.Format("c0")
.HtmlAttributes(new { style = "width:99%;" })
.Max(1000000000000000000)
.Min(1)
.Step(100000)
.Placeholder("Presupuesto General xx"))
#Html.ValidationMessageFor(v => v.Valor, "", new { #style = "color: rgba(247, 20, 10, 0.97);" })
</div>
<div class="col-md-3">
<br />
<input type="submit" class="form-control btn btn-primary" value="Guardar Presupuesto" onclick="SetMostrarVentana();" />
</div>
</div>
}
</div>
</div>
<script type="text/javascript">
$(function () {
MostrarVentanaLoading = false;
#if (!string.IsNullOrEmpty(ViewBag.MensajeError))
{
#:mostrarMensajeAlertGlobal("#ViewBag.MensajeError",15000)
}
else if (!string.IsNullOrEmpty(ViewBag.MensajeSuccess))
{
#:mostrarMensajeAlertSuccessGlobal("#ViewBag.MensajeSuccess", 15000);
}
});
</script>
Then on my controller I have business logic that returns something different depending on conditions
public ActionResult CreateOrEditPresupuestoGeneralxx(PresupuestosGenerale presupuestoGeneralxx)
{
try
{
ModelState.Remove("PresupuestoGlobal");
if (presupuestoGeneralxx == null)
{
return PartialView();
}
if (!ModelState.IsValid)
{
return PartialView(presupuestoGeneraxx);
}
if (presupuestoGeneralxx.Valor < 1)
{
ModelState.AddModelError("Valor", "Por favor ingrese un presupuesto total");
return PartialView(presupuestoGeneralxx);
}
So, when the user submits the form, the container from the index view is replaced with the new html.
The code works perfectly fine, however I feel that the code is ugly, not maintainable and difficult to read.
My questions, is, with asp.net mvc and ajax is there a better and more organized way to achieve the same thing with more readable code?
I would refactor the views moving the ajax form outside the partial. That way the full partial which is rendered inside the form is refreshed on ajax posts, keeps unaware and decoupled of container structure and every view has their own responsibility:
Index.cshtml
<div class="panel panel-default">
<div class="panel-heading">
#using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "form-content", InsertionMode = InsertionMode.Replace }))
{
<div id="form-content">
#Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
}
</div>
</div>
CreateOrEditPresupuestoGeneralxx.cshtml
#using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
#using xx.Relacionamiento.Modelo.Bussiness.Entities;
#using Kendo.Mvc.UI;
#model PresupuestosGenerale
#Html.HiddenFor(h => h.PresupuestoGeneralId)
#Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
...
Here is one of the example that I used in some of my projects. In this example not only PartialView is rendered, also a DropdownList value is passed to the PartialView and displayed on it.
View :
<div id="divPartialView">
#Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
$(document).ready(function () {
$(".SelectedCustomer").change(function (event) {
$.ajax({
url: '#Url.Action("GetPartialDiv", "Home")',
data: { id: $(this).val() /*add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
},
error: function (data) { onError(data); }
});
});
function SetData(data) {
$("#divPartialView").html(data); //HTML DOM replace
}
});
Controller :
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* ddl's selectedvalue */)
{
Models.GuestResponse guestResponse = new Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
}

Categories