Visual Studio MVC HTML Web Address - asp.net-mvc

So I can make an address like
www.mysite.com/person
But how can I make it so that it's like
www.mysite.com/person/john-bishop
I guess I need both ID and name, in case there are multiple john bishops?
This is what I got so far
public ActionResult Person(int id, string name)
{
return View();
}

You need add an Id or unique identifier at the end.
www.mysite.com/person/john-bishop-1
www.mysite.com/person/john-bishop-2
and the RouteConfig
routes.MapRoute("Person", "Person/{name}-{id}", new { controller = "Person", action = "Person" });

Related

2 Actions For Same Route in Asp.Net MVC 3

I have route defined as
routes.MapRoute(
"Company", // Route name
"Company/{companyname}", // URL with parameters
new { controller = "Company", action = "CompanyDetail", companyname = UrlParameter.Optional } // Parameter defaults
);
Now the problem is that i have made this route if now i made any request to company controller and pass a parameter it goes to CompanyDetail method , but in one condition i dont want to send to this method i want to send the control to another action CallCompany . How to solve this and note i also need to run both type of request .
you can set it in your controller method:
public ActionResult CompanyDetail(string companyname)
{
if (condition)
{
return RedirectToAction("ActionName", new { companyname = companyname});
}
return View();
}
As I understood your question, you want to realise the following behavior:
There is as set of company names (for example, "test") and they correspond with URL
yourhost/Company/test
They should be routed to CallCompany.
The other URL (such as yourhost/Company/another_company) should be routed to CompanyDetail.
I think, that the best way is to do redirect in CompanyDetail method
public ActionResult CallCompany(string companyname)
{
return View();
}
public ActionResult CompanyDetail(string companyname)
{
IEnumerable<string> myCompanies = GetSpecialCompany();
if (myCompanies.Contains(companyname))
{
return RedirectToAction("CallCompany", new { companyname = companyname });
}
return View();
}
private IEnumerable<string> GetSpecialCompany()
{
throw new NotImplementedException();
}
you should probabaly look into mvc route constraints. that would enable you to forward request on the simillar url to different action depending uopn different parameters which you can programatically set.
for example
routes.MapRoute(
"Product",
"Product/{productId}",
new {controller="Product", action="Details"},
new {productId = #"\d+" }
);
this would only go to controller:Product and action Details in product id is an int
in your case you will have to define the pattern in regex for which request should go to one route and place the second route next to this
so automatically every request which dosent fit the constraint for this route will be handeled by the next one.

ASP.NET MVC, email address as parameter breaking routes

I have the following actionresult:
public ActionResult Confirmation(string emailAddress)
When I try to access it:
http://localhost:8080/Signup/Confirmation?emailAddress=test%40test.com
I get this:
The view 'test#test.com' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Signup/test#test.com.cshtml
~/Views/Signup/test#test.com.vbhtml
What gives why isn't it looking for the correct view? If I go to "/SignUp/" it correctly shows me the index, along with the other ActionResults working correctly. Why does an address break it?
You shouldn't be passing that info in the URL anyway.
If this is kind of a "Confirmation" page from a signup, you could pass another identifier, e.g the UserId that has just been created, then fetch it from the repo.
E.g:
[HttpPost]
public ActionResult Signup(SignupViewModel model)
{
//.. code to save.. etc
return RedirectToAction("Confirmation", new { id = newUser.UserId });
}
[HttpGet]
public ActionResult Confirmation(int id)
{
var user = repo.FindById(id);
// map to model, etc...
return View(model);
}
So your URL would be (without a specialized route)
http://localhost:8080/Signup/Confirmation?id=123213
Putting user's email addresses in the URL is asking for them to be spammed.
Have you tried registering the route in the global.asax.cs?
Something like:
routes.Add("confirmation",
new Route("Signup/Confirmation/{email}",
new RouteValueDictionary(new { controller = "Signup", action = "Confirmation", email = UrlParameter.Optional }),
new MvcRouteHandler())
);

Mandatory field while creating new database record in asp.net mvc

I'm new to ASP.NEt MVC. I've been trying to create a new database record.
public ActionResult Create()
{
var model = new Maping();
return View(model);
}
//
// POST: /Customerservice/Create
[HttpPost]
public ActionResult Create([Bind(Exclude="CustomerServiceMappingID")] Maping serviceToCreate)
{
if (!ModelState.IsValid)
return View();
var dc = new ServicesDataContext();
String s = serviceToCreate.ServiceID.ToString();
if (String.IsNullOrEmpty(s))
ModelState.AddModelError("ServiceID", "ServiceID is required!");
dc.Mapings.InsertOnSubmit(serviceToCreate);
dc.SubmitChanges();
return RedirectToAction("Index","Home");
}
So, what I need to do is I need ServiceID to become mandatory... I tried this with not much use. So, can u please help me out?
Also I need to send the customerID which is another column of the table back to Index method.
If ServiceId is an integer it should automatically be required. Otherwise you can put this attribute on ServiceId in your model class.
[Required]
public string ServiceId {get;set;} //assuming you are using a string
Can you post your model?
Two things ...
1)
You need to add the Is Null = false to your database model, so that when the DataContext tries to save the new record away, then it will either create a new ID if those attributes are set or you need to supply one.
2)
Add an Attribute to your Maping model that tells MVC about the error you are throwing in the Create Action.
[Required]
public int ServiceID // <- replace with the correct type.
if your Index Action is like this ...
public ActionResult Index(int customerID), then you can send it with the RedirectToAction.
new { customerId = /* insert ID here */ }
that I believe is the third parameter in that method call.

ASP.NET MVC - drop down list selection - partial views and model binding

I'm fairly new to ASP.NET MVC and am trying to work out the best way to do this. It's probably simple but I just want to do things correctly so I thought I'd ask.
Lets say I have a model that is this:
Task - Id, Description, AssignedStaffMember
StaffMember - Id, FirstName, LastName
and in my view I want to create a new task. I make a strongly typed Razor view, and can use EditorFor to create textboxes for Description but what about AssignedStaffMember?
I want a drop down list of all current staff and have the option of selecting one, then this gets submitted to an action method which is
NewTask(string description, StaffMember assignedStaffMember)
either that or I could have an int for staffId instead of the StaffMember object and look it up in the action method.
What is the best way to do this? I need to go to the database to get the list off staff, so here's what I thought:
Make a partial view for the listing of staff drop down, which will be used a few times and use #Html.Action("ListStaff", "Staff") to call it. The action method then has
public ActionResult ListStaff()
{
IEnumerable<StaffMember> model = _serviceLayer.GetAllStaff();
return PartialView(model);
}
However I'm not sure on how this will work with model binding, my understanding is that it has to have the correct name for the form to submit it, I'd need to pass the name to the partial view to put on the element I guess?
Instead of having it call a controller to get the staff, make a ViewModel that contains my Task and a IEnumerable possibleStaff collection. possibly send this information to a partial view.
a Html Helper ?
EditorFor could somehow be used?
which one (or is there more) would be best? and how would I do the model binding?
Here is one way to do this. Create a TaskDetailsViewModel
public class TaskDetailsViewModel
{
public TaskDetailsViewModel()
{
this.Task = new Task();
this.StaffMembers = new List<StaffMember>();
}
public Task Task { get; set; }
public IEnumerable<StaffMember> StaffMembers { get; set; }
}
In Controller
public ActionResult Edit(int id)
{
var task = taskRepository.GetTaskByID(id);
var taskDetailsViewModel = new TaskDetailsViewModel();
// Populate taskDetailsViewModel from task and staff
return View(taskDetailsViewModel);
}
[HttpPost]
public ActionResult Edit(TaskDetailsViewModel taskDetailsViewModel)
{
if (ModelState.IsValid)
{
taskRepository.Save(taskDetailsViewModel.Task);
}
else
{
// Show Error
}
return View(taskDetailsViewModel);
}
In View (bound strongly to TaskDetailsViewModel)
#Html.DropDownListFor(model => model.Task.AssignedStaffMember, new SelectList(Model.StaffMembers, "ID", "FirstName", Model.Task.AssignedStaffMember))
#Html.ValidationMessageFor(model => model.Task.AssignedStaffMember)

QueryString id parameter not being used

I've got a very basic ASP.Net MVC project where I'd like to use a parameter name of id on one of my controller actions. From everything I've read that shouldn't be a problem but for some reason using a parameter name of id fails to get the value extracted from the query string but if I change it to any other different name it will work.
I only have a single route in my global.asx
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
My controller method is:
public ActionResult Confirm(string id)
{
....
}
A URL of http://mysite/customer/confirm/abcd works. A URL of http://mysite/customer/confirm?id=abcd fails.
If I change the controller method to:
public ActionResult Confirm(string customerID)
{
....
}
then a URL of http://mysite/customer/confirm?customerID=abcd works.
Is there something special about using "id" as a parameter in an ASP.Net MVC query string?
Update: Changed id from 1234 to abcd, my id's are actually strings.
If you do not apply an id parameter (either querystring or POST), the system just ignores it, and you can remove the "id" parameter in your controller:
public ActionResult Confirm()
In your case, you would just stick with the id parameter. Why make an ugly customerID parameter, when id is "mapped" automatically?
This is an easy and simple example of the use of id parameter.
public ActionResult Confirm(int? id)
{
if (id.HasValue && id.Value > 0) // check the id is actually a valid int
_customerServer.GetById(id.Value);
// do something with the customer
return View();
}
This works too, for me. We're doing it in our application right now with a standard route:
public ActionResult Confirm(string id)
{
if (!string.IsNullOrEmpty(id)) // check the id is actually a valid string
_customerServer.GetByStringId(id);
// do something with the customer
return View();
}
If you need to have id in query string, then don't create route with 'id' parameter.
In case you have route "{controller}/{action}" then you can use public ActionResult Confirm(string id) as your controller method.
Routes don't care about query strings.

Resources