Why do i get this error
The current request for action 'Index' on controller type 'MyController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Index() on type MyProj.Controllers.MyController
System.Web.Mvc.ActionResult Index(MyProj.Models.MyModel) on type MyProj.Controllers.MyController
COntroller Class :
public class MyController : Controller
{
//
// GET: //
public ActionResult Index()
{
return View();
}
public ActionResult Index(MyModel model)
{
string x = "Hello "+ model.name;
return View();
}
}
}
They are both GET actions.
Add this before your second method:
[HttpPost]
Like so:
public class MyController : Controller
{
//
// GET: //
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(MyModel model)
{
string x = "Hello "+ model.name;
return View();
}
}
If you want to overload you need to add attribute to change your method name:
[ActionName("OverloadedName")]
Related
I am working a project and I had some trouble. I want to send id from html beginform but I couldn't do it.
I want to send /BuyTourTicket/tourid
This is my code:
public ActionResult TourTicket(int id)
{
var tour = db.TBLTUR.Find(id);
ViewBag.tourid = tour.id;
ViewBag.tourname = tour.tur_basligi.ToString();
ViewBag.kalkisYeri = tour.kalkis_yeri.ToString();
ViewBag.tarih = tour.tarih.ToString();
ViewBag.detaylar = tour.detay.ToString();
ViewBag.turYetkilisi = db.TBLTURYETKILISI.Find(id).ad + " " + db.TBLTURYETKILISI.Find(id).soyad;
return View("TourTicket",tour);
}
public ActionResult BuyTourTicket()
{
return View();
}
[HttpPost]
public ActionResult BuyTourTicket(int id)
{
TBLTURREZERVASYON reservation = new TBLTURREZERVASYON();
reservation.tur = id;
db.TBLTURREZERVASYON.Add(reservation);
db.SaveChanges();
return View();
}
This is the error I get:
The first, the default route usually describes the id parameter as optional. Therefore change the action method declaration to public ActionResult BuyTourTicket(int? id):
[HttpPost]
public ActionResult BuyTourTicket(int? id)
{
TBLTURREZERVASYON reservation = new TBLTURREZERVASYON();
reservation.tur = id;
db.TBLTURREZERVASYON.Add(reservation);
db.SaveChanges();
return View();
}
The second, change the parameters order in the Html.BeginForm() of the TourTicket.cshtml to:
#using (Html.BeginForm("BuyTourTicket", "Tur", new { id = ViewBag.tourid }, FormMethod.Post))
The route values are third parameter and the HTTP method is the fourth parameter.
I would fix an action route
[HttpPost("{id"})]
public ActionResult BuyTourTicket(int id)
and add Get to another action
[HttGet]
public ActionResult BuyTourTicket()
{
return View();
}
Currently lots of my actions have this type of code
public ActionResult MyAction() {
if (Request.IsAjaxRequest()) {
return PartialView();
}
return View();
}
I would like to simplify them to something like:
public ActionResult MyAction() {
return ViewOrPartialView();
}
One solution is to sub-class Controller and add your special method there:
public class MyControllerBase : Controller
{
protected ActionResult ViewOrPartialView()
{
if (Request.IsAjaxRequest())
return PartialView();
return View();
}
}
You would then modify your existing controllers to inherit from the new base class instead, allowing you to call the new method:
public class YourController : MyControllerBase
{
public ActionResult MyAction()
{
return ViewOrPartialView()
}
}
Since (based on your comments) you don't like the sub-class route, the alternative would be an extension method defined on Controller. Note though that this gets a bit tricky since the methods we need (View and PartialView) are protected (technically protected internal). With a little help from the MVC source code we can reimplement the functionality ourselves:
public static class ControllerExtensions
{
public static ActionResult ViewOrPartialView(
this Controller controller,
object model = null,
string viewName = null)
{
if (controller == null)
throw new ArgumentNullException(nameof(controller));
var vd = controller.ViewData;
var td = controller.TempData;
var vec = controller.ViewEngineCollection;
if (model != null)
{
vd.Model = model;
}
if (controller.Request.IsAjaxRequest())
{
return new PartialViewResult
{
ViewName = viewName,
ViewData = vd,
TempData = td,
ViewEngineCollection = vec
};
}
return new ViewResult
{
ViewName = viewName,
ViewData = vd,
TempData = td,
ViewEngineCollection = vec
};
}
}
We can then invoke them as extension methods. Note the this which becomes required:
public class YourController : Controller
{
public ActionResult MyAction()
{
return this.ViewOrPartialView();
}
public ActionResult MyActionWithModel()
{
var model = GetSomeModel();
return this.ViewOrPartialView(model);
}
public ActionResult MyActionWithViewName()
{
return this.ViewOrPartialView(viewName: "CustomView");
}
public ActionResult MyActionWithModelAndViewName()
{
var model = GetSomeModel();
return this.ViewOrPartialView(model, "CustomView");
}
}
This is the start of my index.cshtml:
#model IEnumerable<UsageReportViewModel>
#{
ViewBag.Title = "UsageReport";
}
<h2>UsageItem</h2>
#(Html.Kendo().Grid(Model)
.Name("Index")
.DataSource(data => data
.Ajax()
.Read(read => read.Action("GetUsageItems", "UsageReport", new { id = ViewBag.usageReportId }))
.Model(model => model.Id(m => m.Id))
^ Index:
public ActionResult Index(int id)
{
return View();
}
public ActionResult Details(int id)
{
ViewBag.usageReportId = id;
return View();
}
public ActionResult Get([DataSourceRequest] DataSourceRequest request)
{
var GetFile = UsageReportSelection();
return Json(GetFile.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
public ActionResult GetUsageItems([DataSourceRequest] DataSourceRequest request)
{
int id = ViewBag.usageReportId; // <--
var GetFile = UsageReportItems(id);
return Json(GetFile.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
The int id from method GetUsageItems is returning "0". I need this to pass through some data like the public ActionResult index is doing with the Get method. I know I am doing something wrong just not sure what.
You don't get the value of ViewBag.usageReportId the way you are trying to get it. The ViewBag value you are passing read => read.Action method would come as extra parameter to the Action method at the server side.
So you have two ways to access this values at the controller action method.
One - Change controller action method to have extra parameter as following.
public ActionResult GetUsageItems([DataSourceRequest] DataSourceRequest request, int id)
{
var GetFile = UsageReportItems(id);
return Json(GetFile.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
Follow https://www.telerik.com/forums/pass-additional-parameters-to-read-ajax-datasource-method---mvc to understand the example.
Two - Access the id from QueryString parameters.
public ActionResult GetUsageItems([DataSourceRequest] DataSourceRequest request)
{
var id = Convert.ToInt32(Request.QueryStrings["id"]);
var GetFile = UsageReportItems(id);
return Json(GetFile.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
This should help you resolve your issue.
I need two differend views for Kaminy/KaminniTopky & Kaminy/KaminniTopky/5.
How can I do it in that way?
public class KaminyController : Controller
{
//
// GET: /Kaminy/
public ActionResult Index()
{
return View();
}
// GET: /Kaminy/KaminniTopky
public ActionResult KaminniTopky()
{
return View();
}
// GET: /Kaminy/KaminniTopky/5
public ActionResult KaminniTopky(int id)
{
return View();
}
}
#Stephen Muecke's idea has merit, you can combine as:
public ActionResult KaminniTopky(int? id)
{
if (!id.HasValue)
{
return View();
}
else
{
return View("OtherViewName");
}
}
There are overloads that take the model too - return View(someModel); and return View("OtherViewName", someModel); respectively.
In MVC 5 you could:
[Route("Kaminy/KaminniTopky")]
public ActionResult KaminniTopky()
{
return View();
}
[Route("Kaminy/KaminniTopky/{id}")]
public ActionResult KaminniTopky(int id)
{
return View("OtherViewName");
}
For something like /Kaminy/KaminniTopky/KaminniTopkyWithOther/5 you would use routing rather than a weird controller structure to support other style URLs.
E.g. In RouteConfig:
routes.MapRoute(
"SomeRoute",
"/Kaminy/KaminniTopky/KaminniTopkyWithOther/{id}",
new { controller = "Kaminy", action = "KaminniTopkyWithOther", id = "" }
);
Make sure this comes before the default route.
Then it doesn't matter what your action is called as long as its the same as defined in the route.
public ActionResult KaminniTopkyWithOther(int id)
{
return View("OtherViewName");
}
Now I have an action A and an action B,I want to jump to action B in action A.But action B has
a parameter "MyModel".If I write like this:
public ActionResult A(MyModel model)
{
...
return B(model);
}
public ActionResult B(MyModel model)
{
...
return View();
}
It will cause an error.
What should I do to transfer the parameter "MyModel" to action B in action A?
Do this:
public ActionResult A(MyModel model)
{
return RedirectToAction("B", model);
}
Try this
public ActionResult A(MyModel model)
{
...
TempData["object"] = new { Model= model };
return RedirectToAction("B");
}
Then in your B action
public ActionResult B(MyModel model)
{
...
var yourObj = TempData["object"];
model=yourObj .Model;
return View();
}