I am deleting a row in my webgrid , and redirecting to my GET index as normal after delete.
However as expected my view is showing the old deleted row still in the grid. I know this is by design and i should be able to set the Modelstate to clear , or remove the item individually to achieve this :
ModelState.Remove("id");
Or
foreach (var key in ModelState.Keys.Where(m => m.StartsWith("id")).ToList())
ModelState.Remove(key);
Or
ModelState.Remove("Applicant.ApplicantId");
Or even :
ModelState.Clear()
However none have working for me.
Here is my delete method (simplified -all error handling and non necessary code removed )
public ActionResult DeleteApplicant(int id)
{
var q =
(from a in context.Applicants
where a.ApplicantId == id
select a).Single<Applicant>();
q.ApplicantDocuments.ToList().ForEach(r => context.ApplicantDocuments.Remove(r));
context.Applicants.Remove(q);
context.SaveChanges();
foreach (var key in ModelState.Keys.Where(m => m.StartsWith("id")).ToList())
ModelState.Remove(key);
TempData["SuccessMessage"] = "Successfully deleted row.";
return RedirectToAction("Index");
}
And here is my call to my delete method from the view :
, grid.Column(format: (item) => #Html.ActionLink("Delete", "DeleteApplicant",
new { id = item.ApplicantId }, new { #class = "delete-link" }), style: "DeleteButton")
I have looked at various posts on stackoverflow etc but none seem to solve my issue : MVC 3 The View is not being refreshed after model submit
I have tried also tried re-directing to the Index action via jquery and calling the delete controller action with ajaxOptions , but this hasn't worked either.
, grid.Column(format: (item) => #Ajax.ActionLink("Delete", "DeleteApplicant",
new { id = item.ApplicantId },
new AjaxOptions { HttpMethod = "GET" , OnSuccess= "reloadGrid" }))
And adding a little script to call the home index:
function reloadGrid() {
var pathArray = window.location.pathname.split('/');
var segment_1 = pathArray[1];
var newURL = window.location.protocol + "//" + window.location.host + "/" + segment_1 + "/Home/Index";
$.ajax(
{
type: "GET",
url: newURL,
data: "{}",
cache: false,
dataType: "html",
success: function (data)
{ $().html(data); }
})
}
I am obviously doing something wrong. Is there any other way i can force a refresh of the page in a different way or can anyone spot anything obviously wrong in my current approach. Thanks in advance.
Note: I do have my webgrid markup on my Index view and not in a separate partial viewbut i don't think this should be causing this?
Update :
Here is up GET method as requested: (for context, the filters object is used when search button is clicked and page is posted back ,no filters applied in initial page load)
public ActionResult Index(string page)
{
/////Peform paging initiation
int pageIndex = 0;
if (!string.IsNullOrEmpty(page))
{
pageIndex = int.Parse(page) - 1;
}
////initialize total record count and filter results object
int totalRecordCount = 0;
var filters = new ApplicantSearchFilter();
////Perform search with paging
var applicants = this.GetApplicantsPaging(filters ,pageIndex, out totalRecordCount);
////Return view type
var data = new ApplicantViewModel()
{
Filters =filters ,
TotalRecordCount = totalRecordCount,
ApplicantReportLists = applicants,
PageIndex = pageIndex,
};
////return Index view passing data result to build it
return this.View("Index", data);
}
}
I have finally managed to get this working.
If it helps anyone else here is what i did in the end. I used a solution posted by Dror here : How to achieve edit and delete on Webgrid of MVC3 Razor? . Where he turned a GET delete call from the webgrid into a post. Not exactly what i was looking for but it works.
Does anyone have a better , alternative solution ?
View Code :
added Function :
#functions{
string Delete(dynamic p)
{
string actionController = Url.Action("Delete", "Admin", new {id=p.AccountId});
return "<form style='display:inline;' method='post' action='" + actionController + "'><input type='submit' value='Delete' onclick=\"return confirm('Are you sure?')\"/></form>";
}
}
and changed my delete call in my webgrid to :
grid.Column(header: "", format: p => Html.Raw(Delete(p)))
In the Controller:
[HttpPost]
public ActionResult Delete(int id)
{
PerformDelete(id);
return RedirectToAction("Index");
}
Related
In my view I have a ActionLink that passes an Id to another View. I used this multiple times but for some reason it does not work on this ActionLink. I even tried with a AJAX POST call in javascript but with no success either. Am I doing something wrong? If so, I am not seeing what.
Controller:
The parameter Id in this function is 0 and should be filled.
public ActionResult NieuwPriveBericht(int Id)
{
TblPER_Personeelslid Sender = BCL.GetEmployeeByLoginName(Session["LoginName"].ToString());
TblPER_Personeelslid Receiver = BCL.GetEmployeeById(Id);
var Model = new TblALG_PrvBericht();
Model.Datum = DateTime.Now.Date;
Model.Zender = Sender.IDPersoneelslid;
Model.Ontvanger = Receiver.IDPersoneelslid;
ViewBag.ReceiverName = Receiver.Voornaam + " " + Receiver.Naam;
return View(Model);
}
public ActionResult PriveBerichten()
{
ViewBag.SelectedEmployee = "";
var Model = new PriveBerichten();
return View(Model);
}
View:
If I debug my view I clearly see #Model.SelectedOption filled.
#using (Html.BeginForm("PriveBerichten", "Home", #Model, FormMethod.Post))
{
#Html.ActionLink("Nieuw bericht maken", "NieuwPriveBericht", new { Id = #Model.SelectedOption }, new { #class = "button-add" })
}
AJAX CALL
$("#DdlEmployees").change(function () {
var SelectedEmployee = $('#DdlEmployees option:selected').val();
$.ajax({
type: "POST",
url: 'PriveBerichten?SelectedEmployee=' + SelectedEmployee, // this works
dataType: "json",
data: $('form').serialize(),
success: function () {
alert("test"); // does not show
},
error: function () {
}
});
})
If you didn't set up the id of route is "Id", you need to use "id". Also delete "#Model" in the BeginForm.
Action
public ActionResult NieuwPriveBericht(int id)
{
//
}
View:
#using (Html.BeginForm("PriveBerichten", "Home", FormMethod.Post))
{
#Html.ActionLink("Nieuw bericht maken", "NieuwPriveBericht",
new { id = #Model.SelectedOption }, new{ #class = "button-add" })
}
Thanks for showing the ActionResult that generates the view. I think this is your problem:
var Model = new PriveBerichten();
return View(Model);
I assume your class PriveBerichten contains the SelectedOption property? If you do not change/initialize this property value in the constructor of PriveBerichten it is 0 by default, and so it will be 0 in your actionlink.
I have a List of Listings within my Database. On my View, I have a DropDownList which contains categories. A category contains many listings.
When I select a specific category, I wish to only display those listings which have the category selected.
My main worry is how to generate the JQuery to call my SortListing method in my ListingController.
Here is the current HTML (Razor):
#Html.DropDownListFor(m => m.Categories, Model.Categories, "Select a Category")
My SortListing Method:
public List<Listing> SortListing(string categoryId)
{
var listings = new List<Listing>();
foreach (var listing in _service.ListAllEntities<Listing>())
{
if (listing.CategoryId == categoryId)
{
listings.Add(listing);
}
}
return listings;
}
EDIT I have the following. Put the categoryGuid is coming in null.
This is my code:
$(function () {
$('#SelectedCategoryGuid').change(function () {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function (result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
</script>
<h2>Index</h2>
#Html.ActionLink("Create New Listing", "Create")
<br/>
<strong>Filter Listings</strong>
#Html.DropDownListFor(
m => m.SelectedCategoryGuid,
Model.Categories,
"Select a Category",
new {
id = "SelectedCategoryGuid",
data_url = Url.Action("SortListing", "Listing")
}
)
My main worry is how to generate the JQuery to call my SortListing
method in my ListingController.
Actually you should be having other worries as well that I will try to cover throughout my answer.
There's an issue with your DropDownListFor helper. You have used the same property on your model for both binding the selected category value and the list of categories which is wrong. The first parameter of the DropDownListFor helper represents a lambda expression pointing to a primitive type property on your view model:
#Html.DropDownListFor(
m => m.CategoryId,
Model.Categories,
"Select a Category",
new {
id = "categoryDdl",
data_url = Url.Action("SortListing", "Listing")
}
)
and then subscribe to the .change() event and trigger the AJAX request:
$(function() {
$('#categoryDdl').change(function() {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function(result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
Now let's take a look at your SortListing controller action because there are issues with it. In ASP.NET MVC standard convention dictates that controller actions must return ActionResults. In your case you seem to be returning some List<Listing>. So the first thing you have to decide is the format you would like to use. One possibility is to return those listings as JSON formatted values:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return Json(listings, JsonRequestBehavior.AllowGet);
}
In this case inside your AJAX success callback you will receive this collection of listings and you will have to update your DOM:
success: function(result) {
// result represents an array of listings
// so you could loop through them and generate some DOM elements
}
Another possibility is to have your controller action return a partial view:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return PartialView("Listings", listings);
}
and then you will have a corresponding partial view:
#model List<Listing>
#foreach (var listing in Model)
{
<div>#listing.SomeProperty</div>
}
and then inside the success callback you will refresh some containing placeholder:
success: function(result) {
$('#SomeDivIdThatWrapsAroundTheListingsPartial').html(result);
}
So to recap you could either have the controller action return JSON and then manually build the corresponding DOM tree using javascript or return a partial view which will already contain the corresponding markup and simply refresh some containing div with this partial.
I am using Telerik MVC Grid where one of the columns is checkboxes. If I select checkboxes and then go to page 2 and then come back to page 1 all the checkboxes are gone. Which is of course the way HTTP works. Now, I put all the selected checkboxes inside the hidden field but since the grid does some sort of postback my hidden field is cleared next time.
If you're using Client Side data binding you can use the javascript/jquery below to maintain checkbox state.
Maintain checkbox state:
var selectedIds = [];
$(document).ready(function () {
//wire up checkboxes.
$('#YOUR_GRID_ID :checkbox').live('change', function (e) {
var $check = $(this);
console.log($check);
if ($check.is(':checked')) {
//add id to selectedIds.
selectedIds.push($check.val());
}
else {
//remove id from selectedIds.
selectedIds = $.grep(selectedIds, function (item, index) {
return item != $check.val();
});
}
});
});
Restore checkbox state after data binding:
function onDataBound(e) {
//restore selected checkboxes.
$('#YOUR_GRID_ID :checkbox').each(function () {
//set checked based on if current checkbox's value is in selectedIds.
$(this).attr('checked', jQuery.inArray($(this).val(), selectedIds) > -1);
});
}
A more verbose explanation available on my blog:
http://blog.cdeutsch.com/2011/02/preserve-telerik-mvc-grid-checkboxes.html
You need to save the state of the checkboxes to your database, and then retrieve them again from the database when you reload the page.
During paging, you need to reload only those records that pertain to a particular page. You can do that using the Skip() and Take() methods from Linq.
to preserve checked /unchecked checkbox state using telerik grid clientemplate across postbacks and async postbacks and in refreshing grid and (auto)paging, I tried the solution above with no avail and so went up with a bit harder solution; as I could not save the state in db, I used a session variable and an hiddenfield:
first, a way to do ajax postback (see function DoAjaxPostAndMore , courtesy of somebody herearound), where in success we take care of client values of selections, adding and removing as checked /unchecked
I also had to manually check / uncheck the checkboxes inside the manual ajax post
second, an hidden field (see 'hidSelectedRefs') to preserve clientactions, as the Session variable I am using will not be seen clientside in partial rendering
#model IEnumerable<yourInterfaceOrClass>
#{
ViewBag.Title = "Select Something via checkboxes";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Select Something via checkboxes</h2>
<!-- we need a form with an id, action must be there but can be an empty string -->
<form id="frm" name ="frm" action="">
<p>
<!--we need this as Session new values will not be takein in aajax requests clientisde, so it is easier to mange this field, which, in first and subsequent complete postbacks can have the value of the Session variable -->
<input type="hidden" name="hidSelectedRefs" id="hidSelectedRefs" value= '#Session["SelectedReferencesToPrint"]' />
</p>
<br />
<script type="text/javascript">
//ajax manual post to a custom action of controller, passing the id of record and the state of the checkbox
//to adjust the Session value
//data: $form.serialize() will have the single checbox value
//but only if checked. To make my life eaasier, I added the value (is id ) and the checked/unchecked
//state of checkbox (is the $(chkClicked).attr('checked'))
function DoAjaxPostAndMore(chkClicked) {
var $form = $("#frm");
$.ajax({
type: "POST",
url: 'SelectReferences',
data: $form.serialize() + '&id=' + $(chkClicked).val() + '&checked=' + $(chkClicked).attr('checked'),
error: function (xhr, status, error) {
//do something about the error
alert("Sorry, we were not able to get your selection...");
},
success: function (response) {
//I also needed to check / uncheck manually the checkboxes:
$(chkClicked).attr('checked', !$(chkClicked).attr('checked'));
//and now put correct values in hidSelectedRefs hidden field:
if ($(chkClicked).attr('checked')) {
$('input[name=hidSelectedRefs]').val($('input[name=hidSelectedRefs]').val() + '|' + $(chkClicked).val() + '|');
} else {
var tmp = $('input[name=hidSelectedRefs]').val();
$('input[name=hidSelectedRefs]').val(tmp.toString().replace('|' + $(chkClicked).val() + '|', ''));
}
}
});
return false; // if it's a link to prevent post
}
Then I handled the OnRowDataBound, to ensure the checboxes would be correctly checked on postbacks,
function onRowDataBound(e) {
var itemsChecked = $('input[name=hidSelectedRefs]').val();
if (itemsChecked)
{
if (itemsChecked.indexOf('|' + $(e.row).find('input[name=checkedRecords]').val() + '|') >= 0)
{
$(e.row).find('input[name=checkedRecords]').attr('checked', true);
}
}
}
</script>
The telerik mvc Grid is as follows:
(you can see I also handled OnDataBinding and OnDataBound, but thats's only to show a
"Loading" gif. The controller is named "Output" and the action that normally would be called "Index" here is callled "PrintReferences". The correspondenting Ajax action is called "_PrintReferences")
Of interest here is the ClientTemplate for checkbox (cortuesy of someone else herearound, where onclick
we call our custom ajax action (named "SelectReferences") on our Output controller via a call to the
DoAjaxPostAndMore() javascript/jquery function
#(Html.Telerik().Grid<yourInterfaceOrClass>()
.Name("Grid")
.ClientEvents(e => e.OnDataBinding("showProgress").OnDataBound("hideProgress").OnRowDataBound("onRowDataBound"))
.DataBinding(dataBinding =>
{
dataBinding.Server().Select("PrintReferences", "Output", new { ajax = ViewData["ajax"]});
dataBinding.Ajax().Select("_PrintReferences", "Output").Enabled((bool)ViewData["ajax"]);
})
.Columns( columns =>
{
columns.Bound(o => o.ID);
columns.Bound(o => o.ID)
.ClientTemplate(
"<input type='checkbox' name='checkedRecords' value='<#= ID #>' onclick='return DoAjaxPostAndMore(this)' />"
)
.Width(30)
.Title("")
.HtmlAttributes(new { style = "text-align:center; padding: 0px; margin: 0px;" });
columns.Bound(o => o.TITLE);
columns.Bound(o => o.JOBCODE);
columns.Bound(o => o.ORDERCODE );
//columns.Bound(o => o.AUTHOR);
columns.Bound(o => o.STATE);
columns.Command(commands =>
commands
.Custom("Details")
.ButtonType(GridButtonType.Image)
.HtmlAttributes(new { #class = "t-icon-details" })
.DataRouteValues(route => route.Add(o => o.ID)
.RouteKey("ID"))
.Ajax(false)
.Action("Details", "Referenza")
);
})
.Pageable(paging =>
paging.PageSize(10)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Position(GridPagerPosition.Bottom))
.Sortable()
.Filterable()
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.NoRecordsTemplate("No Reference found. Please review your filters...")
.ColumnContextMenu()
)
</form>
that's all for the View. Now, to the controller:
//Get : this is the usally called "Index" action
//here we can load data, but we also must ensure the Session variable is fine
public ActionResult PrintReferences(bool? ajax, string msgInfo, string selectedRef)
{
if (Session["SelectedReferencesToPrint"] == null)
{
Session["SelectedReferencesToPrint"] = string.Empty;
}
if (string.IsNullOrEmpty(selectedRef))
{
selectedRef = "|0|";
}
string msgOut = string.Empty;
//this is where I get data to show
List<yourInterfaceOrClass> ret = LoadData(out msgOut);
if (!string.IsNullOrEmpty(msgInfo) && !string.IsNullOrEmpty(msgInfo.Trim()))
{
msgOut = msgInfo + ' ' + msgOut;
}
ViewBag.msgOut = msgOut;
ViewData["ajax"] = ajax ?? true;
return View(ret);
}
//GridAction: here is telerik grid Ajax get request for your "_Index"
[GridAction]
public ActionResult _PrintReferences(string msgInfo)
{
//again, we must take care of Session variable
if (Session["SelectedReferencesToPrint"] == null)
{
Session["SelectedReferencesToPrint"] = string.Empty;
}
string msgOut = string.Empty;
List<yourInterfaceOrClass> ret = LoadData(out msgOut);
return View(new GridModel(ret));
}
//Post: this is where our custom ajax post goes
//we are here if a checkbox is cheched or unchecked
//in the FormCollection parameter we get the checkbox value only if checked, and also
//(and always) the parms we passed (id of record and state of checkbox: we cannot simply add,
//we must also subtract unchecked)
[HttpPost]
public ActionResult SelectReferences(FormCollection collection)
{
//we need a session variable
if (Session["SelectedReferencesToPrint"] == null)
{
Session["SelectedReferencesToPrint"] = string.Empty;
}
//use a local variable for calculations
string wholeSelectionToPrint = Session["SelectedReferencesToPrint"].ToString();
//get value passed: id
string selectedRefId = collection["id"];
if (!string.IsNullOrEmpty(selectedRefId))
{
selectedRefId = "|" + selectedRefId + "|";
}
bool cheked = (collection["checked"].ToString()=="checked");
//get vcalue passed :checked or unchecked
if (cheked)
{
//the element is to add
wholeSelectionToPrint += selectedRefId;
}
else
{
//the element is to remove
wholeSelectionToPrint = wholeSelectionToPrint.Replace(selectedRefId, "");
}
//set session variable final value
Session["SelectedReferencesToPrint"] = wholeSelectionToPrint;
return null;
}
//normal postback:
//we will be here if we add a button type submit in our page,
//here we can collect all data from session variable to do
//something with selection
[HttpPost]
public ActionResult PrintReferences(FormCollection collection)
{
//get selected references id
if (Session["SelectedReferencesToPrint"] == null)
{
Session["SelectedReferencesToPrint"] = string.Empty;
}
//use a local variable for calculations
string wholeSelectionToPrint = Session["SelectedReferencesToPrint"].ToString();
wholeSelectionToPrint = wholeSelectionToPrint.Replace("||", "|");
string[] selectdIDs = wholeSelectionToPrint.Split(new char[] { '|' });
foreach (string id in selectdIDs)
{
if (!string.IsNullOrEmpty(id))
{
//do something with single selected record ID
System.Diagnostics.Debug.WriteLine(id);
}
}
//omitted [....]
ViewData["ajax"] = true;
return View(ret);
}
I have a ASP.Net MVC JsonResult function in which I want to return the contents of a PartialView (The content has to be loaded using Ajax, and for some reason I can't return a PartialViewResult).
To render the PartialView I need the ViewContext object.
How do you get the current ViewContext object within an Action method? I don't even see HttpContext.Current in my action method.
I am using ASP.net MVC 1.
a ViewContext is not available within the action method because it is constructed later before rendering the view. I would suggest you using MVCContrib's BlockRenderer to render the contents of a partial view into a string.
I may have missed a point somewhere but my Actions that returned partial views do so by returning a View object that refers to an ascx page. This will return partial HTML without the full page constructs (html, head, body, etc.). Not sure why you'd want to do anything beyond that, is there a specific reason you need to return PartialViewResult? Here's an example from my working code.
First the Action in my controller:
public ViewResult GetPrincipleList(string id)
{
if (id.Length > 1)
id = id.Substring(0, 1);
var Principles = competitorRepository.Principles.Where(p => p.NaturalKey.StartsWith(id)).Select(p=>p);
return View(Principles);
}
And then the partial view (ascx):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MyProject.Data.Principle>>" %>
<% foreach (var item in Model) { %>
<div class="principleTitle" title="<%= Html.Encode(item.NaturalKey) %>"><%= Html.Encode(item.Title) %></div>
<%} %>
Lastly, the Jquery that sets up the call:
$(function() {
$(".letterSelector").click(function() {
$("#principleList").load("/GetPrincipleList/" + $(this).attr("title"), null, setListClicks);
});
});
So, a full AJAX process, hope that helps.
---- UPDATE following comment ----
Returning Json data is just as easy:
Firstly, initiating the AJAX call when a select box changes:
$("#users").change(function() {
var url = "/Series/GetUserInfo/" + $("#users option:selected").attr("value");
$.post(url, null, function(data) { UpdateDisplay(data); }, 'json');
});
The javascript that processes the returned json data:
function UpdateDisplay(data) {
if (data != null) {
$("div.Message").fadeOut("slow", function() { $("div.Message").remove(); });
$("#Firstname").val(data.Firstname);
$("#Lastname").val(data.Lastname);
$("#List").val(data.List);
$("#Biography").val(data.Biography);
if (data.ImageID == null) {
$("#Photo").attr({ src: "/Content/Images/nophoto.png" });
$("#ImageID").val("");
}
else {
if (data.Image.OnDisk) {
$("#Photo").attr({ src: data.Image.ImagePath });
}
else {
$("#Photo").attr({ src: "/Series/GetImage?ImageID=" + data.ImageID });
}
$("#ImageID").val(data.ImageID);
}
$("form[action*='UpdateUser']").show();
} else {
$("form[action*='UpdateUser']").hide();
}
};
And finally the Action itself that returns the json data:
public JsonResult GetUserInfo(Guid id)
{
MyUser myuser = (from u in seriesRepository.Users
where u.LoginID == id
select u).FirstOrDefault();
if (myuser == null)
{
myuser = new MyUser();
myuser.UserID = 0;
myuser.Firstname = Membership.GetUser(id).UserName;
myuser.Lastname = "";
myuser.List = "";
myuser.Biography = "No yet completed";
myuser.LoginID = id;
}
return Json(myuser);
}
Does that help? If not then can you post some of the code you are working on as I'm missing something.
ok. simple one that is wrapping my brain
I have a method that I have in the controller
public ActionResult Details(string strFirstName, string strLastName)
{
return View(repository.getListByFirstNameSurname(strFirstName, strLastName)
}
How do i get multiple parameters from the URL to the controller?
I dont want to use the QueryString as it seems to be non-mvc mind set.
Is there a Route? Or Other mechanism to make this work? Or am I missing something altogehter here with MVC
EDIT
the url that I am trying for is
http://site.com/search/details/FirstName and Surname
so if this was classic asp
http://site.com/search/details?FirstName+Surname
But i feel that i have missed understood something which in my haste to get to working code, I have missed the point that there really should be in a put request - and I should collect this from the formcollection.
Though might be worth while seeing if this can be done - for future reference =>
For example, suppose that you have an action method that calculates the distance between two points:
public void Distance(int x1, int y1, int x2, int y2)
{
double xSquared = Math.Pow(x2 - x1, 2);
double ySquared = Math.Pow(y2 - y1, 2);
Response.Write(Math.Sqrt(xSquared + ySquared));
}
Using only the default route, the request would need to look like this:
/simple/distance?x2=1&y2=2&x1=0&y1=0
We can improve on this by defining a route that allows you to specify the parameters in a cleaner format.
Add this code inside the RegisterRoutes methods within the Global.asax.cs.
routes.MapRoute("distance",
"simple/distance/{x1},{y1}/{x2},{y2}",
new { Controller = "Simple", action = "Distance" }
);
We can now call it using /simple/distance/0,0/1,2
Something like this?:
routes.MapRoute("TheRoute",
"{controller}/{action}/{strFirstName}/{strLastName}",
new { controller = "Home", action = "Index", strFirstName = "", strLastName = "" }
);
or:
routes.MapRoute("TheRoute2",
"people/details/{strFirstName}/{strLastName}",
new { controller = "people", action = "details", strFirstName = "", strLastName = "" }
);
UPDATED:
This route should be placed before "Default" route:
// for urls like http://site.com/search/details/FirstName/Surname
routes.MapRoute("TheRoute",
"search/details/{strFirstName}/{strLastName}",
new { controller = "search", action = "details", strFirstName = "", strLastName = "" }
);
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
Use hidden values in your form
<%= Html.Hidden("strFirstName", Model.FirstName)%>
<%= Html.Hidden("strLastName", Model.LastName)%>
and the model binder will do the binding
public ActionResult Details(string strFirstName, string strLastName)
{
return View(repository.getListByFirstNameSurname(strFirstName, strLastName)
}
It is also possible to use FormCollection:
public ActionResult Details(int listId, FormCollection form)
{
return View(rep.getList(form["firstName"], form["lastName"])
}
Likewise, if the HTTP request contains a form value with the exact same name (case sensitive), it will automatically be passed into the ActionResult method.
Also, just to be clear, there is nothing un-MVC about querystring parameters.
I also had the same problem once and what I did was use the Ajax call inside the jQuery function. First I selected all parameter values using jQuery selectors. Below is my jQuery function.
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#btnSendNow').click(function () {
var grid = $('#Patient-kendo-Grid').data('kendoGrid');
var location = $('#EmailTempalteLocation option:selected').text();
var appoinmentType = $('#EmailTemplateAppoinmentType option:selected').text();
var emailTemplateId = $('#EmailTemplateDropdown').val();
var single = $('input:radio[name=rdbSingle]:checked').val();
var data = grid.dataSource.view();
var dataToSend = {
patients: data,
place: location,
appoinment: appoinmentType,
rdbsingle: single,
templateId: emailTemplateId
};
debugger;
$.ajax({
url: 'Controller/Action',
type: 'post',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(dataToSend)
});
});
});
</script>
My controller method has five parameters and it is as below.
[HttpPost]
public ActionResult SendEmailToMany(List<PatientModel> patients, string place, string appoinment, string rdbsingle, string templateId)
{
emailScheduleModel = new EmailScheduleModel();
AmazonSentEmailResultModel result;
List<string> _toEmailAddressList = new List<string>();
List<string> _ccEmailAddressList = new List<string>();
List<string> _bccEmailAddressList = new List<string>();
IEmailTemplateService emailTemplateService = new EmailTemplateService();
EmailTemplateContract template = emailTemplateService.GetEmailTemplateById(new Guid(templateId));
emailScheduleModel.EmailTemplateContract = new EmailTemplateContract();
emailScheduleModel.EmailTemplateContract = template;
}
It is working fine in my developments.
For further details please follow the below url.
http://dushanthamaduranga.blogspot.com/