How can I force the Route with .html and id? - c#

I wanna force the Route with .html and a 32 length id.
For example, here is the URL:
https://localhost:44331/Re/test.html?id=12345678901234567890123456789012
I want it when there is no id parameter in the URL or the length of id is not 32, it returns 404 status code.
Here is the controller:
namespace V.Controllers
{
[Route("Re/")]
public class ReController : Controller
{
[Route("test.html{id:length(32)}")]
public IActionResult test(string id)
{
return View();
}
}
}
After I ran the code, it always reports 404 status code.
What's wrong with my route?

I don't think you can specify query string parameters in the route. Try validating the id in the action, or if you can change the route, add it as an additional segment.
[Route("Re/")]
public class ReController : Controller
{
[Route("test.html")]
public IActionResult test(string id)
{
if (id == null || id.Length != 32)
return NotFound();
return Json(new {id= id});
}
[Route("test2.html/{id:length(32)}")]
public IActionResult test2(string id)
{
return Json(new {id= id});
}
}
See: Microsoft Docs

Related

Using model to save a list, works first time but second time it saves 62 count item list as 1 list item [duplicate]

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));
}
}

Need help calling Web Api controller methods to retrieve data

I'm new to Web Api (I'm probably missing something very straightforward here) I have a Web Api project with ProductsController.cs that has a property of type List<Product> and I simply want to call the Api in the browser eg localhost/api/products/1 or /api/products/getproduct/1 to retrieve the product response for the specified Id in the url but I cannot get it to retrieve any data. I get a 'not found' error each time. What am I missing to make it find the data and retrieve the response?
I have tried the following:
public IHttpActionResult Get(int id)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return NotFound();
}
else
{
return Ok(product);
}
}
And even the following which still returns not found:
public string Get(int id)
{
return "product test";
}
Make sure the the routing is configured properly
WebApiConfig.cs
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
From there you have two options of routing to the action.
Convention-based.
public class ProductsController : ApiController {
//...constructor code removed for brevity
[HttpGet] // Matches GET api/products
public IHttpActionResult GetAllProducts() {
return Ok(products);
}
[HttpGet] // Matches GET api/products/1
public IHttpActionResult GetProduct(int id) {
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null) {
return NotFound();
}
return Ok(product);
}
}
or Attribute routing
[RoutePrefix("api/products")]
public class ProductsController : ApiController {
//...constructor code removed for brevity
[HttpGet]
[Route("")] // Matches GET api/products
public IHttpActionResult GetAllProducts() {
return Ok(products);
}
[HttpGet]
[Route("{id:int}")] // Matches GET api/products/1
public IHttpActionResult GetProduct(int id) {
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null) {
return NotFound();
}
return Ok(product);
}
}

Setting up mvc route

I'm trying to create a mvc application. I have a project controller, actions are below
[AllowAnonymous]
[HttpGet]
public ActionResult Index()
{
//TODO: Browse
return View();
}
[AllowAnonymous]
[HttpGet]
public ActionResult Index(long projectId)
{
using (var entity = new dixraContext())
{
var project = entity.Projects.FirstOrDefault(m => m.Id == projectId);
if (project == null)
return RedirectToAction("NotFound", "Error");
else
return RedirectToAction("Index", project.UrlName);
}
}
[AllowAnonymous]
[HttpGet]
public ActionResult Index(string projectName)
{
using (var entity = new dixraContext())
{
var project = entity.Projects.Where(m => m.Name == projectName);
return View(project);
}
}
I want to show URL's like
example.com/Project/ProjectName
But when i enter url as
example.com/Project/1
Got Error.
An error occurred while processing your request
. as response. When i enter example.com/Project/Index/1 i go into first action.
I also want to resolve project from id and redirect to usual Project/ProjectName url.
Looks like you've got conflicting routes. One way to solve this while leaving your three possible inputs would be checking your input parameter.
Also, your RedirectToAction has a string as its second parameter - that overload of RedirectToAction treats the second parameter as the controller name, not the route object:
Assuming your routes file looks ok:
routes.MapRoute(
name: "Project",
url: "Project/{projectName}",
defaults: new { controller = "Project", action = "Index" }
);
Your controller action might be:
[AllowAnonymous]
[HttpGet]
public ActionResult Index(string projectName)
{
if (string.IsNullOrWhiteSpace(projectName))
{
// return your empty view
}
int projectId;
if (int.TryParse(projectName, out projectId))
{
projectName = GetProjectNameFromDatabase(projectId);
return RedirectToAction("Index", new { projectName });
}
// return your view with your model
}
There may be a better way, but this will work.

Web Api routing to action with string paramater

It seems simple like in ASP.NET MVC but I can't figure out how to map an URI with a string parameter to an action on my controller. So I have three actions in my controller as below:
//GET: api/Societe
public IEnumerable<Societe> GetSociete()
{
List<Societe> listeSociete = Librairie.Societes.getAllSociete();
return listeSociete.ToList();
}
//GET: api/Societe/id
[ResponseType(typeof(Societe))]
public IHttpActionResult GetSociete(int id)
{
Societe societeRecherchee = Librairie.Societes.getSociete(id);
if (societeRecherchee == null)
{
return NotFound();
}
else
{
return Ok(societeRecherchee);
}
}
public IHttpActionResult GetSocieteByLibelle(string name)
{
Societe societeRecherchee = new Societe();
if (!string.IsNullOrWhiteSpace(name))
{
societeRecherchee = Librairie.Societes.getSocieteByLibelle(name);
if (societeRecherchee == null)
{
return NotFound();
}
}
return Ok(societeRecherchee);
}
So I would like to map an URI with the action:
GetSocieteByLibelle(string name)
My route configuration is the default one for Wep API project. May someone explain me how to map an URI to that action ? Thanks in advance !
Looks like the two routes are resulting in the same method call being invoked. Try putting a [Route] attribute on one of them as follows:
[Route("api/Societe/libelle/{name}")]
public IHttpActionResult GetSocieteByLibelle(string name)
{
}
Note that the default /api/Societe/{id} should still hit your first Action.

Is it possible to redirect to another action passing it as well our current Model as HttpPost?

So, I am experimenting with ASP.NET MVC and I have the following code:
public class TrollController : Controller
{
public ActionResult Index()
{
var trollModel = new TrollModel()
{
Name = "Default Troll",
Age = "666"
};
return View(trollModel);
}
[HttpPost]
public ActionResult Index(TrollModel trollModel)
{
return View(trollModel);
}
public ActionResult CreateNew()
{
return View();
}
[HttpPost]
public ActionResult CreateNew(TrollModel trollModel)
{
return RedirectToAction("Index");
}
}
The idea is to have an index page which shows the age of our troll as well as his name.
There's an action that allows us to create a troll, and after creating it we should get back to the index page but this time with our data, instead of the default one.
Is there a way to pass the TrollModel CreateNew(TrollModel trollModel) is receiving to Index(TrollModel trollModel)? If yes, how?
The best approach would be to persist the troll somewhere on the server (database?) and then pass only the id to the index action when redirecting so that it can fetch it back. Another possibility is to use TempData or Session:
[HttpPost]
public ActionResult CreateNew(TrollModel trollModel)
{
TempData["troll"] = trollModel;
return RedirectToAction("Index");
}
public ActionResult Index()
{
var trollModel = TempData["troll"] as TrollModel;
if (trollModel == null)
{
trollModel = new TrollModel
{
Name = "Default Troll",
Age = "666"
};
}
return View(trollModel);
}
TempData will survive only a single redirect and be automatically evicted on the subsequent request whereas Session will be persistent across all HTTP requests for the session.
Yet another possibility consists into passing all the properties of the troll object as query string arguments when redirecting:
[HttpPost]
public ActionResult CreateNew(TrollModel trollModel)
{
return RedirectToAction("Index", new
{
Age = trollModel.Age,
Name = trollModel.Name
});
}
public ActionResult Index(TrollModel trollModel)
{
if (trollModel == null)
{
trollModel = new TrollModel
{
Name = "Default Troll",
Age = "666"
};
}
return View(trollModel);
}
Now you might need to rename the Index POST action as you cannot have two methods with the same name and arguments:
[HttpPost]
[ActionName("Index")]
public ActionResult HandleATroll(TrollModel trollModel)
{
return View(trollModel);
}
In CreateNew there must be some kind of persistence e.g. the troll might be saved in database. It must also have some kind of ID. So the Index method can be changed to
public ActionResult Index(string id)
{
TrollModel trollModel;
if (string.IsNullOrEmpty(id))
{
trollModel = new TrollModel()
{
Name = "Default Troll",
Age = "666"
};
}
else
{
trollModel = GetFromPersisted(id);
}
return View(trollModel);
}
and in the CreateNew
[HttpPost]
public ActionResult CreateNew(TrollModel trollModel)
{
return RedirectToAction("Index", new {id = "theNewId"});
}

Categories

Resources