Get response as json after a post - asp.net-mvc

I don't know if this is possible or not. I am working with asp.net mvc3 form. I am posting a form to a action and i want to get the response as json.
for example-
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { Class = "formValidation", enctype = "multipart/form-data" }))
{
<dt>
<label>
Ad Image:
</label>
</dt>
<dd>
<input id="bannerImage" name="bannerImage" type="file" class="fileupload" />
</dd>
<dt>
<label>
JS Code:
</label>
</dt>
<dd>
#Html.TextAreaFor(m => m.JsCode, 10, 50, new { })
</dd>
<input type="submit" class="button red" value="Update Banner" />}
This is the form. And after submit I want to do something like
public ActionResult Action(Model editModel, HttpPostedFileBase file){
//do something
return Json(new{type="success"});
}
Then receive this from the form page and take some action. Is it possible?
if not please can you give me some hints to do this otherwise.

Use Ajax form instead of Html form. You can subscribe to OnSuccess javascript event and get output in format you like and also in json and process it there.

Related

ASP.NET MVC delete method pass an Id / model to the controller

Using Razor pages for my views, I can't find a way to pass an Id / bounded model to my controller.
I have created a delete template view with my model, added a delete action method to my controller, but I can't figure out how to pass any parameters.
#model AdventureWorks.Models.HumanResources.Department
#{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
#using (Html.BeginForm("DeleteConfirmed", "Department", FormMethod.Post))
{
#Html.AntiForgeryToken()
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Department</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.GroupName)
</dt>
<dd>
#Html.DisplayFor(model => model.GroupName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.ModifiedDate)
</dt>
<dd>
#Html.DisplayFor(model => model.ModifiedDate)
</dd>
</dl>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Delete" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller
public ActionResult DeleteConfirmed(Department department)
{
return ViewDepartments();
}
The Department object that is returned, is a new object with no properties set.
Could you advise me, how to pass at least an Id of the to be deleted object?
I managed to get the model with the form on my create and update method, but I can't figure out, how to do the same on delete.
You can add the parameters you want to pass in Html.BeginForm.Here is a demo:
#using (Html.BeginForm("DeleteConfirmed", "Department",new { Id=Model.Id}, FormMethod.Post))
{
...
}
result:
And you don't need to add #Html.AntiForgeryToken(),because your form method is post.
DisplayFor will not do the Model binding.
Assuming Id is a key of Department, add
#Html.HiddenFor(model => model.Id)
inside of Html.BeginForm.
Inside of you delete action use department.Id to find and delete the item.
You have to pass some value to your controller.
#using (Html.BeginForm("DeleteConfirmed", "Department", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Id) // Use valid expression for id property
...
}
And change signature of DeleteConfirm method to
public ActionResult DeleteConfirmed(int id) // Use valid id property type
{
// Delete object
}
That should do the trick.

ASP.net MVC - How to setup a modal?

I am really unsure how to do approach modal dialogs in ASP.NET MVC:
The situation is as follows: In my home/index action method, I check if the user has already accepted the terms and conditions. If not, I want to show a dialog to prompt the user for a confirmation.
Now I am really unsure how to approach this in MVC:
The possibilities I see:
Store a TaCConfirmNeeded property in ViewBag, in my view notice that the viewbag contains this token, display a jquery modal dialog with a form to confirm the terms and cond., and call account/confirmTA from this form.
Create a View in my shared folder, that uses my common layout, and is styled like a modal dialog, with a form which sends to account/confirmTA.
Is there a better/easier possibility?
This is how I implement a Modal Pop-Up in MVC. Hope it can help you.
Create a partial view (example):
#model CodeFirst.Models.FriendsInfo
<div>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">FriendsInfo</h4>
</div>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Mobile)
</dt>
<dd>
#Html.DisplayFor(model => model.Mobile)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Address)
</dt>
<dd>
#Html.DisplayFor(model => model.Address)
</dd>
</dl>
The controller it's gonna look like:
public ActionResult Details(int Id)
{
FriendsInfo frnds = new FriendsInfo();
frnds = db.FriendsInfo.Find(Id);
return PartialView("_Details",frnds);
}
Later put this on your _Layout:
<div id='myModal' class='modal'>
<div class="modal-dialog">
<div class="modal-content">
<div id='myModalContent'></div>
</div>
</div>
</div>
And your gonna need this script with a little jQuery to call it with AJAX from your view:
<script>
var PostBackURL = '/Home/Details';
$(function () {
// Use your logic, to call this function and replace the parameters like the User.ID
debugger;
var id = User.Id;
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: PostBackURL ,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
debugger;
$('#myModalContent').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
//$("#closebtn").on('click',function(){
// $('#myModal').modal('hide');
$("#closbtn").click(function () {
$('#myModal').modal('hide');
});
</script>

HttpPost Delete MVC for Composite Keys

I have a table with three columns with first two formulating the composite key
SrcSys (CompositeKey Part I)
CustId (CompositeKey Part II)
CustNm
I am new to ASP & starting with MVC Core.
The following code for get method works well:
public async Task<IActionResult> Delete(string _SrcSys, string _CustId)
{
if (_SrcSys == null || _CustId == null)
{
return NotFound();
}
var customer = await _context.Customers.SingleOrDefaultAsync(Cust => Cust.SrcSys == _SrcSys && Cust.CustId == _CustId);
if (customer == null)
{
return NotFound();
}
return View(customer);
}
The relevant code of Delete.cshtml is:
#model RiskDotNet.Models.Customer
#{
ViewData["Title"] = "Delete";
}
#*<h2>Delete</h2>*#
<br />
<hr />
<dl class="dl-horizontal">
<dt>
Src Sys
</dt>
<dd>
#Html.DisplayFor(model => model.SrcSys)
</dd>
<dt>
Cust ID
</dt>
<dd>
#Html.DisplayFor(model => model.CustId)
</dd>
<dt>
Customer
</dt>
<dd>
#Html.DisplayFor(model => model.CustNm)
</dd>
</dl>
<form asp-action="Delete">
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" />
<p />
<p />
<input type="submit" value="Cancel" class="btn btn-default" a asp-action="Index">
</div>
</form>
All the three fields are appearing on the page.
In respect of HttpPost what would be a reasonable piece of code?
You need to put the SrcSys and CustId in the form so they can be passed to the backend on the submit.
You can just put this in the form part:
#Html.HiddenFor(model => model.SrcSys)
#Html.HiddenFor(model => model.CustId)
These properties wont be displayed but they will be submitted.
Sidenote
Dont use Html helpers ( #Html.DisplayFor, #Html.HiddenFor..) they are the old way of doing things.
Use tag helpers that came with MVC Core:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro
I resolved the problem myself:
Updated HttpPost:
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeletePost(Customer customer)
{
try
{
_context.Entry(customer).State = EntityState.Deleted;
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException)
{
return RedirectToAction("Delete", new { ss = customer.SrcSys, ci = customer.CustId });
}
}
and Updated Delete.cshtml:
#model RiskDotNet.Models.Customer
#{
ViewData["Title"] = "Delete";
}
<hr />
<dl class="dl-horizontal">
<dt>
Src Sys
</dt>
<dd>
#Html.DisplayFor(model => model.SrcSys)
</dd>
<dt>
Cust ID
</dt>
<dd>
#Html.DisplayFor(model => model.CustId)
</dd>
<dt>
Customer
</dt>
<dd>
#Html.DisplayFor(model => model.CustNm)
</dd>
</dl>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.SrcSys)
#Html.HiddenFor(model => model.CustId)
<form asp-action="Delete">
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" />
<p />
<p />
<input type="submit" value="Cancel" class="btn btn-default" a asp-action="Index">
</div>
</form>
}
Did the job!!!
:-)

Submitting a form to ASP.NET MVC from Knockout does not bring in all the values

Here is what I have in my view in ASP.NET MVC 5
#model Entities.Coupon
#using (Html.BeginForm("coupon", "marketing", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="scsm-18 scmd-16 sclg-14">
<div class="form-group">
<label>Codes</label>
#Html.TextBoxFor(p => p.Code, new { #class = "form-control", #data_bind = "value: Code", #autofocus = true, #maxlength = "50" })
</div>
<input type="radio" name="IsPerCentOrDollar" value="1" data-bind="checked: IsPerCentOrDollar" />
<span>PercentageAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="2" data-bind="checked: IsPerCentOrDollar" />
<span>DollarAmount</span>
<input type="radio" name="IsPerCentOrDollar" value="3" data-bind="checked: IsPerCentOrDollar" />
<span>FreeShipping</span>
</div>
<div class="panel-footer text-right">
<input type="submit" name="commandType" id="btnSave" class="btn btn-primary" data-bind="click:submit" value="Save" />
</div>
}
In the script:
$(document).ready(function () {
var viewModel = new CouponViewModel(couponModel);
ko.applyBindings(viewModel);
function CouponViewModel(data) {
self.Code = ko.observable(data.Code);
self.IsPerCentOrDollar = ko.observable("1");
self.DiscountLevel = ko.computed(function () {
return self.IsPerCentOrDollar();
});
};
}
Code in MVC:
[HttpPost, ActionName("coupon")]
public ActionResult coupon(Coupon coupon)
{
try
{
// some logic not yet in
}
catch (Exception ex)
{
}
return View();
}
That's all I have in there now.
In Developer tools inside the browser I can see values for self.DiscountLevel change on the selection of radio buttons.
On Submit, at MVC front the value of Code comes in but the values for DiscountLevel are not.
Any help is greatly appreciated.
Regards.
Let me expand on #StephenMuecke's comment (which has the gist of it I think).
ASP.NET MVC's default model binding will fill the argument (Coupon) with values found in the request. Only form elements are sent along with the request. You seem to expect that DiscountLevel is sent along, but it's just a JavaScript function that exists in the user's browser.
Adding something like this may solve your immediate problem:
<input type="hidden" name="DiscountLevel" data-bind="value: DiscountLevel" />
To note a related issue though: the property you have trouble with is a computed observable. However, you probably do not want to send it along as it depends entirely on IsPerCentOrDollar. Just have your server side Coupon class derive the discount level from that property too. That would also prevent users from hacking the hidden input and sending in a malicious value.

ASP.NET MVC: Multiple submit buttons using Ajax.BeginForm

I want to create a page that has a next button and previous button that switches the image displayed.
For that purpose I created an Ajax.BeginForm and inserted into it, an image and two submit buttons.
Can I (should I) have multiple submit buttons inside an Ajax.BeginForm?
How would the controller handle each submit separately?
Try this,
View
#model TwoModelInSinglePageModel.RegisterModel
#using (Ajax.BeginForm("DYmanicControllerPage", "Test", FormMethod.Post,null, new { id = "frmSignUp" }))
{
<div>
<input type="hidden" id="" name="hidden2" id="hdasd" />
#Html.HiddenFor(m => m.hidden1)
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
</div>
<br />
<div>
#Html.LabelFor(m => m.Address)
#Html.TextBoxFor(m => m.Address)
#Html.ValidationMessageFor(m => m.Address)
</div>
<br />
<div>
#Html.LabelFor(m => m.PhoneNo)
#Html.TextBoxFor(m => m.PhoneNo)
#Html.ValidationMessageFor(m => m.PhoneNo)
</div>
<input type="submit" value="Save" id="btnSave" name="ButtonType"/>
<input type="submit" value="Next" id="btnNext" name="ButtonType" />
}
Controller
[HttpPost]
public ActionResult DYmanicControllerPage(RegisterModel model, string ButtonType)
{
if(ButtonType == "Next")
{
// Do Next Here
}
if (ButtonType == "Save")
{
//Do save here
}
return JavaScript("REturn anything()");
}
I would recommend that you have two buttons and then depending on what button was clicked you could set the action on the form:
Razor
$(function (){
$("#btn-prev").click(function() {
$("#form").attr
(
"action",
"#Url.Action("Action", "Controller", new {area="Area" })",
).submit();
});
$("#btn-next").click(function() {
$("#form").attr
(
"action",
"#Url.Action("Action", "Controller", new {area="Area" })",
).submit();
});
});
I am using jQuery here to do this, but I think you can get the idea.
I had the same requirement/issue and tried both solutions here and they both work for me. I LIKE the idea of setting the action via jquery when clicking so I can keep my actions separate so they can be used by other views.
HOWEVER, I've found that when I do this while I debug, it posts TWICE and BOTH the OnSuccess and OnFailure are triggered. It only happens when debugging though. Keep this in mind when picking.

Resources