I want to route a URL like http://localhost:8888/api/orders?id=1
to an action, but it only works when the URL is given in this format: http://localhost:8888/api/orders/1
Two actions:
[HttpGet]
public IActionResult Get(bool includeItems=true)
{
var results = _repository.GetAllOrders(includeItems);
return Ok(_mapper.Map<IEnumerable<Order>, IEnumerable<OrderViewModel>>(results));
}
[HttpGet("{id:int}")]
public IActionResult Get(int id)
{
var order = _repository.GetOrderById(id);
if (order != null)
return Ok(_mapper.Map<Order, OrderViewModel>(order));
else
return NotFound();
}
It works fine if I send a URL like:
http://localhost:8888/api/orders?includeItems=false.
When I send the URL http://localhost:8888/api/orders?id=1, it gets mapped to the first Action which has includeItems as parameter.
I have [Route("api/[Controller]")] attribute on top of my controller.
Related
I need some help figuring out how I can get entities by name in this setup:
// get: /api/v1/users/
[HttpGet]
public virtual async Task<IActionResult> Get()
{
var items = await service.GetAll();
if (!items.Any()) return NotFound();
return Ok(items);
}
// get: /api/v1/users/{id}
[HttpGet("{id}")]
public virtual async Task<IActionResult> Get(int id)
{
var item = await service.Get(id);
if (item == null) return NotFound();
return Ok(item);
}
// get: /api/v1/users/?name={name}
[HttpGet("{name}")]
public virtual async Task<IActionResult> Get([FromQuery]string name)
{
var item = await service.GetByUserId(name);
if (item == null) return NotFound();
return Ok(item);
}
Get() and Get(int id) workes but when I call https://xxx/api/v1/users/?name=foo the Get() method is hit and all entities are returned. How can I get entities by name?
The routing middleware maps an incoming request's URL into an appropriate action method. During this process, the middleware only uses URL segment values to identify a suitable action method. As a result, even if you specify the ?name="" value in a query string, the middleware always maps your request to the default Get() method.
You can solve this problem easily by modifying the URL paths (I believe, you know how to implement it). However, if you plan to keep your URL path as it is, then tweak your code a bit, and it will work.
// get: /api/v1/users/
// get: /api/v1/users/?name={name}
[HttpGet]
public virtual async Task<IActionResult> Get([FromQuery]string name)
{
if(name is null) return GetAllUsers();
return return GetByUserName(name);
}
I want to know, there is any technique so we can pass Model as a parameter in RedirectToAction
For Example:
public class Student{
public int Id{get;set;}
public string Name{get;set;}
}
Controller
public class StudentController : Controller
{
public ActionResult FillStudent()
{
return View();
}
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return RedirectToAction("GetStudent","Student",new{student=student1});
}
public ActionResult GetStudent(Student student)
{
return View();
}
}
My Question - Can I pass student model in RedirectToAction?
Using TempData
Represents a set of data that persists only from one request to the
next
[HttpPost]
public ActionResult FillStudent(Student student1)
{
TempData["student"]= new Student();
return RedirectToAction("GetStudent","Student");
}
[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
Student std=(Student)TempData["student"];
return View();
}
Alternative way
Pass the data using Query string
return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});
This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz
Ensure the method you want to redirect to is decorated with [HttpGet] as
the above RedirectToAction will issue GET Request with http status
code 302 Found (common way of performing url redirect)
Just call the action no need for redirect to action or the new keyword for model.
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return GetStudent(student1); //this will also work
}
public ActionResult GetStudent(Student student)
{
return View(student);
}
Yes you can pass the model that you have shown using
return RedirectToAction("GetStudent", "Student", student1 );
assuming student1 is an instance of Student
which will generate the following url (assuming your using the default routes and the value of student1 are ID=4 and Name="Amit")
.../Student/GetStudent/4?Name=Amit
Internally the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. However, binding will only work if all the properties in the model are simple properties and it fails if any properties are complex objects or collections because the method does not use recursion. If for example, Student contained a property List<string> Subjects, then that property would result in a query string value of
....&Subjects=System.Collections.Generic.List'1[System.String]
and binding would fail and that property would be null
[HttpPost]
public async Task<ActionResult> Capture(string imageData)
{
if (imageData.Length > 0)
{
var imageBytes = Convert.FromBase64String(imageData);
using (var stream = new MemoryStream(imageBytes))
{
var result = (JsonResult)await IdentifyFace(stream);
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));
if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });
}
}
return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);
}
// GET: Auth
[HttpGet]
public ActionResult Index(string param)
{
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(param);
return View(faceRecon);
}
[NonAction]
private ActionResult CRUD(someModel entity)
{
try
{
//you business logic here
return View(entity);
}
catch (Exception exp)
{
ModelState.AddModelError("", exp.InnerException.Message);
Response.StatusCode = 350;
return someerrohandilingactionresult(entity, actionType);
}
//Retrun appropriate message or redirect to proper action
return RedirectToAction("Index");
}
i did find something like this, helps get rid of hardcoded tempdata tags
public class AccountController : Controller
{
[HttpGet]
public ActionResult Index(IndexPresentationModel model)
{
return View(model);
}
[HttpPost]
public ActionResult Save(SaveUpdateModel model)
{
// save the information
var presentationModel = new IndexPresentationModel();
presentationModel.Message = model.Message;
return this.RedirectToAction(c => c.Index(presentationModel));
}
}
In MVC I am trying to pass an optional ID parameter from one ActionResult method and I want to capture that ID in another ActionResult method. I currently have the following code but I still can't find a way to get the ID in the Method2().
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Method1(SomeModel model)
{
int someID = model.something.Id;
.
..
...
return RedirectToAction("Method2", new { userID = someID});
}
After clicking on a button on Method1's View page, the code will direct me to Method2 page and I will see something like this in my URL
http://localhost:1234/myController/method2?userid=100 note that the ?userid=100 was sucessfully passed to the URL when Method2 got called.
and this is my Method2. I am trying to get the userid but I can't.
[HttpGet]
public ActionResult Method2()
{
**I want to get the userID from the URL**
}
I even tried to use int? id but still I am getting a null for id.
public ActionResult Method2(int? id)
{
//id return null all the time
}
Any help on how I can get the userid in the URL in Method2()?
your query string's variable name and actionresult variable name must match
[HttpGet]
public ActionResult Method2(int userid)
{
//your code
}
or even
public ActionResult Method2(int? userid)
{
//id return null all the time
}
The value key value pair for userid is in the request querystring collection. To get it do something like the following:
if (Request.QueryString.Count > 0)
{
if(Request.QueryString["userid"] != null)
{
int userId = (int)Request.QueryString["userid"];
}
}
I want to know, there is any technique so we can pass Model as a parameter in RedirectToAction
For Example:
public class Student{
public int Id{get;set;}
public string Name{get;set;}
}
Controller
public class StudentController : Controller
{
public ActionResult FillStudent()
{
return View();
}
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return RedirectToAction("GetStudent","Student",new{student=student1});
}
public ActionResult GetStudent(Student student)
{
return View();
}
}
My Question - Can I pass student model in RedirectToAction?
Using TempData
Represents a set of data that persists only from one request to the
next
[HttpPost]
public ActionResult FillStudent(Student student1)
{
TempData["student"]= new Student();
return RedirectToAction("GetStudent","Student");
}
[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
Student std=(Student)TempData["student"];
return View();
}
Alternative way
Pass the data using Query string
return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});
This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz
Ensure the method you want to redirect to is decorated with [HttpGet] as
the above RedirectToAction will issue GET Request with http status
code 302 Found (common way of performing url redirect)
Just call the action no need for redirect to action or the new keyword for model.
[HttpPost]
public ActionResult FillStudent(Student student1)
{
return GetStudent(student1); //this will also work
}
public ActionResult GetStudent(Student student)
{
return View(student);
}
Yes you can pass the model that you have shown using
return RedirectToAction("GetStudent", "Student", student1 );
assuming student1 is an instance of Student
which will generate the following url (assuming your using the default routes and the value of student1 are ID=4 and Name="Amit")
.../Student/GetStudent/4?Name=Amit
Internally the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. However, binding will only work if all the properties in the model are simple properties and it fails if any properties are complex objects or collections because the method does not use recursion. If for example, Student contained a property List<string> Subjects, then that property would result in a query string value of
....&Subjects=System.Collections.Generic.List'1[System.String]
and binding would fail and that property would be null
[HttpPost]
public async Task<ActionResult> Capture(string imageData)
{
if (imageData.Length > 0)
{
var imageBytes = Convert.FromBase64String(imageData);
using (var stream = new MemoryStream(imageBytes))
{
var result = (JsonResult)await IdentifyFace(stream);
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));
if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });
}
}
return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);
}
// GET: Auth
[HttpGet]
public ActionResult Index(string param)
{
var serializer = new JavaScriptSerializer();
var faceRecon = serializer.Deserialize<FaceIdentity>(param);
return View(faceRecon);
}
[NonAction]
private ActionResult CRUD(someModel entity)
{
try
{
//you business logic here
return View(entity);
}
catch (Exception exp)
{
ModelState.AddModelError("", exp.InnerException.Message);
Response.StatusCode = 350;
return someerrohandilingactionresult(entity, actionType);
}
//Retrun appropriate message or redirect to proper action
return RedirectToAction("Index");
}
i did find something like this, helps get rid of hardcoded tempdata tags
public class AccountController : Controller
{
[HttpGet]
public ActionResult Index(IndexPresentationModel model)
{
return View(model);
}
[HttpPost]
public ActionResult Save(SaveUpdateModel model)
{
// save the information
var presentationModel = new IndexPresentationModel();
presentationModel.Message = model.Message;
return this.RedirectToAction(c => c.Index(presentationModel));
}
}
How can i prevent a partial view from being loaded by typing http://mydomain.com/site/edit/1 Is there any way of doing this?
/Martin
If you load your partials through Ajax then you can check if the request HTTP header HTTP_X_REQUESTED_WITH is present and its value is equals to XMLHttpRequest.
When a request is made through the browser that header is not present
Here is a very simple implementation of an Action Filter attribute that does the job for you
public class CheckAjaxRequestAttribute : ActionFilterAttribute
{
private const string AJAX_HEADER = "X-Requested-With";
public override void OnActionExecuting( ActionExecutingContext filterContext ) {
bool isAjaxRequest = filterContext.HttpContext.Request.Headers[AJAX_HEADER] != null;
if ( !isAjaxRequest ) {
filterContext.Result = new ViewResult { ViewName = "Unauthorized" };
}
}
}
You can use it to decorate any action where you want to check if the request is an ajax request
[HttpGet]
[CheckAjaxRequest]
public virtual ActionResult ListCustomers() {
}
I believe the [ChildActionOnly] attribute is what you're looking for.
[ChildActionOnly]
public ActionResult Edit( int? id )
{
var item = _service.GetItem(id ?? 0);
return PartialView( new EditModel(item) )
}
Phil Haack has an article using it here