Seemingly silly query about parameters - c#

I am working in ASP.NET MVC 4 with C#, and i'm trying to turn the parameter of one ActionResult method into a variable for use in another method. So I have this for example:
public ActionResult Index(int ser)
{
var invoice = InvoiceLogic.GetInvoice(this.HttpContext);
// Set up our ViewModel
var pageViewModel = new InvoicePageViewModel
{
Orders = (from orders in proent.Orders
where orders.Invoice == null
select orders).ToList(),
Callouts = (from callouts in proent.Callouts
where callouts.Invoice == null
select callouts).ToList(),
InvoiceId = ser,
InvoiceViewModel = new InvoiceViewModel
{
InvoiceId = ser,
InvoiceItems = invoice.GetInvoiceItems(),
Clients = proent.Clients.ToList(),
InvoiceTotal = invoice.GetTotal()
}
};
// Return the view
return View(pageViewModel);
}
I need that int ser to somehow become "global" and its value become available to this method:
public ActionResult AddServiceToInvoice(int id)
{
return Redirect("/Invoice/Index/");
}
As you can see in my return statement just above, I get an error as I am not passing the variable "ser" back to Index, but I need it to be the same value that was passed to Index when the action was called. Can anyone assist?

When you construct your link to that method, you need to ensure you are passing your variable ser to the method along with any other parameters that it needs (it is unclear if the id in the AddServiceToInvoice method is actually the ser parameter or not. This assumes it is not)
Action Link In View
#Html.ActionLink("Add Service", "Invoice", "AddServiceToInvoice", new {id = IdVariable, ser = Model.InvoiceId})
AddServiceToInvoice Action Method
public ActionResult AddServiceToInvoice(int id, int ser)
{
//Use the redirect to action helper and pass the ser variable back
return RedirectToAction("Index", "Invoice", new{ser = ser});
}

You need to create a link with that ID:
if you're doing a get-request that would be something like this:
#Html.ActionLink("Add service to invoice", "Controller", "AddServiceToInvoice",
new {id = Model.InvoiceViewModel.InvoiceId})
Otherwise if you want to do a post you need to create a form:
#using Html.BeginForm(action, controller, FormMethod.Post)
{
<input type="hidden" value="#Model.InvoiceViewModel.InvoiceId" />
<input type="submit" value="Add service to invoice" />
}

Related

How do you retrieve a URL value in MVC?

I am having a slight little problem and wondering is there anyway that you could help me?
I am passing information using angularJs to an MVC controller. I am passing an Id of a user to the controller to allow the admin to change the user into an administrator.
Here is the code for the view,
<tr ng-repeat="r in students | filter : searchStudent">
<td><input type="text" name="Id" value="{{r.ID}}" readonly id="AdminIdText" /></td>
<td>{{r.username}}</td>
<td>{{r.Email}}</td>
<td>{{r.AccountStatus}}</td>
<td>test</td>
<td><input type="submit" value="Make Admin" class="btn btn-warning" /></td>
</tr>
Here is the controller,
public ActionResult AdminStatus(int id)
{
int Id = id;
//Connection to the database
var db = WebMatrix.Data.Database.Open("Database");
db.Execute("UPDATE tblaccount SET AccountStatus= 1 WHERE ID =" + id);
db.Close();
return View("AddAdministrator");
}
}
What I am wondering is, how do you retrieve the numeric value that has been passed through to the controller? This is because placing the information into a model is not working correctly.
Thanks in advance
I think you need to do 2 things. Make the <a> tag look something like this:
<a href="Action/{{r.ID}}">
And add a controller method like this:
public ActionResult Action(int id)
{
// Do something with the id
}
As long as the default route maps are set up in the MVC project, that should map the id value to the id parameter.
Use the MVC 'UrlHelper' to generate URLs that keep working even after controllers have been moved around:
#Url.Action("<ActionName>", "<ControllerName>", new { Area = "<AreaName>", parameter1 = parameter1Value, parameter2 = parameter2Value })
For example:
#Url.Action("AdminStatus", "Admin", new { Area = "Admin", id = r.ID})
will hit the "AdminStatus" action in the "AdminController" in the Area named "Admin" and send a parameter named "id".
you can also use name attribute to get the id value to your controller method.
public void action(int Id)
{
// your code
}

Hide the parameters in query string using GridMvc and ActionLink MVC C#

I am wondering if anyone could help me, the problem I have is that I am trying to not show the parameter in URL, when the parameter is posted to another controller. I have tried routing and changing the ActionLink. If anyone one could help it would be greatly appreciated.
I get "/Accounts/ViewCustomer/Index/3316", I want to hide 3316
Customer list view
#Html.Grid(Model.CustomerList).Columns(columns =>
{
columns.Add(data => data.Referance).Titled("Reference").Sanitized(false).Encoded(false).Filterable(true).
RenderValueAs(model => Html.ActionLink(model.Referance, "Index", "ViewCustomer",
routeValues: new { id = model.CustomerID },
htmlAttributes: new { id = "cust" }).ToHtmlString());
columns.Add(data => data.Company).Titled("Company").Sanitized(false).Encoded(false).Filterable(true).
RenderValueAs(model => Html.ActionLink(model.Company, "Index", "ViewCustomer", new { id = model.CustomerID }, null).ToHtmlString());
}).WithPaging(#ViewBag.Pagesize, #ViewBag.PageCountLimit).Sortable()
From view customer Controller to which int is posted
public ActionResult Index(int? id)
{
Paging paginginfo = GridPageProvider.Pagesize();
ViewData["Pagesize"] = paginginfo.Pagesize;
ViewData["PageCountLimit"] = paginginfo.PageCountLimit;
SetCustomerInfo(id);
if (_customerdetail.Contacts.Count != 0)
{
return View( _customerdetail);
}
else
{
return RedirectToAction("Index", "Home");
}
}
In this case 3316 is part of your URL and you can't hide it. But you can send id as parameter (you will need change routing) and use POST method to hide it in method body

Receiving an error while passing an argument from a view to a method from controller

So, these are the 2 pieces of code that are causing the error.
The View:
...
#foreach (FinalCampaign fc in #Model)
{
<h1>#fc.Camp.Id</h1>
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home", fc.Camp.Id, null)</h2>
<p>#fc.Camp.CampaignStartDate - <font color="Blue"><u>#fc.Username</u></font></p>
<p>#fc.Camp.Description</p>
}
And here is the "GotoPage" function from my controller:
public ActionResult GoToPage(string id)
{
CampaignCommentsModel ff = new CampaignCommentsModel();
var cT = new CampaignTable(new OracleDatabase("DefaultConnection"));
Campaign camp = cT.GetCampaignById(id);
...
return View(ff);
}
And this is my problem: the "id" from GotoPage (the argument) is null, it doesn't receive the value from my view.
You should use:
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home", new { id = fc.Camp.Id}, null)</h2>
You can not pass a nested properties in this way. The default model binder can not associate such an object with a parameter in your action method.
ActionLink extension: https://msdn.microsoft.com/en-us/library/dd492124(v=vs.118).aspx
Model binding: What is model binding in ASP.NET MVC?
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home",new {id = fc.Camp.Id}, null)</h2>
See here Actionlink method

Can I put a RedirectResult into a view link?

I have the following situation:
Into a view I define a link in this way:
<a href="#Url.Action("Edit", "Vulnerability", new { id = Model.Id })" data-mini="true" data-inline="true" data-role="button" >Annulla</a>
As you can see when the user click the link it is executed the Edit() method ot the VulnerabilityController class passing and Id value
Ok, this works fine but in this view I want have something like I have in a controller, this thing:
return new RedirectResult(Url.Action("Edit", "Vulnerability", new { id = vulnId }) + "#tab-2");
As you can see in this second version I always call the Edit() method of the VulnerabilityController class but the value of Id variable is something like "1234#tab-2"
Can I do something like this in my view and not only in my controller?
If you want to render (include) the results of some action inside your View you can use Html.Action:
#Html.Action("Edit", "Vulnerability", new { id = vulnId + "#tab-2" })
See MSDN
For doing this using Razor Syntax, you can try like this:
#Html.ActionLink("Annulla", "Edit", "Vulnerability", new { id = Model.Id },
new{ #data_mini="true", #data_inline="true", #data_role="button"})

How to save query values when searching? ASP.NET MVC

I have such an action method:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Search(String filter, String value, Int32? page) {
var set = new List<Employee>();
switch(filter) {
case "by-name": {
set = this.repository.Get(
e => (e.LastName + " " + e.FirstName + " " + e.MiddleName) == value
).ToList();
break;
}
case "by-empn": {
set = this.repository.Get(
e => e.EmployeeNumber == value
).ToList();
break;
}
default: return RedirectToAction("Search", "Employee");
}
ViewBag.SearchedEmployees = set.Count();
return View(set.ToPagedList(page ?? 1, PageSize));
}
Search view is like this:
#if(Model.Count > 0) {
foreach(var item in Model) {
Html.RenderPartial("Employee.Card", item);
}
#Html.PagedListPager(
Model,
page => Url.Action("Search", new { page = page }),
new PagedListRenderOptions {
LinkToFirstPageFormat = "<< Beginning",
LinkToPreviousPageFormat = "< Back",
LinkToNextPageFormat = "Forth >",
LinkToLastPageFormat = "End >>"
}
)
}
Search form is presented as a partial view:
#using(Html.BeginForm("Search", "Employee", FormMethod.Get, new { #class = "search-form" }))
{
<p>
#Html.TextBox("value")
</p>
<p>
#Html.RadioButton("filter", "by-name", true) By name <br/>
#Html.RadioButton("filter", "by-empn") By empn <br/>
</p>
<p>
<input type="image" src="#Url.Content("~/Content/Images/Search.png")" />
</p>
}
Problem: I have N page links. When I try to go to the second page I face an infinite loop of redirects. That's the way I implemented my action - default case is fired. So filter/value values are null on the second action call? Why?
How do I refactor my search action?
Also how should I configure route for such an action?
Thanks!
EDIT
So should route for the search action look like:
routes.MapRoute(
null,
"{controller}/{action}/Page{page}/filter{filter}/val{value}",
new { controller = "Employee", action = "Search" }
);
?
EDIT 2
So it is possible to write next:
page => Url.Action("Search", new { filter = ViewBag.SearchFilter, value = ViewBag.SearchValue, page = page }),
And inside a controller:
public ActionResult Search(String filter, String value, Int32? page) {
ViewBag.SearchFilter = filter;
ViewBag.SearchValue = value;
// ...
}
Is this right?
So filter/value values are null on the second action call? Why?
Because their corresponding input fields are inside a separate form and are never sent to the server.
You seem to be using some custom Html.PagedListPager helper (the code for which you haven't shown) but I guess that this helper generates the page links as anchors and it simply doesn't take into account any current query string or POSTed values when generating those links. So the href of your pagination link looks like this /SomeController/Search?page=5 instead of the correct one which would take into account those parameters which is /SomeController/Search?page=5&filter=somefilter&value=somevalue.
You can now easily understand why the filter and value parameters in your controller action are always null. It's because you never send them to the server when clicking on the pagination links.
So in order to resolve this issue you could modify this custom HTML helper that you are using to generate the pagination links to include those additional parameters. Or maybe the helper allows you to pass additional parameters? Check the documentation if this is some third party plugin that you are using.

Categories