When typing in my URL
SalaryFor/Microsoft/Balmer
i need to display salary for user with name Balmer
and if I type in URL
SalaryFor/Microsoft
i need to display salary for all employee in Microsoft company
Is it possible?
because when I use this link
SalaryFor/Microsoft/Balmer
all works fine
public ActionResult Salary(string company, string person)
both company and person contains values
but this link does not work
SalaryFor/Microsoft
public ActionResult SalaryFor(string company, string person)
both values contains null
my route in global.asax is
routes.MapRoute("Salary",
"{controller}/{action}/{company}/{position}",
new
{
controller = "Salary",
action = "SalaryFor",
company = "",
test = ""
});
O maybe I am making something wrong?
Thanks,
Alexander.
You need to map a second route.
routes.MapRoute("Salary2",
"{controller}/{action}/{company}",
new
{
controller = "Salary",
action = "SalaryFor",
company = ""
});
Related
Hi i have this actionlink in my "cursos" index view(wich redirects to another controller)
#Html.ActionLink("Ver Alumnos", "Index", "Usuarios", new { id= item.idCurso}, null)
in my controller i got this
public ActionResult Index(int? idCursos)
{
var usuarios = db.Usuario.ToList();
if(!(idCursos == null))
{
var query = from Usuario in db.Usuario
from Relaciones in db.Relaciones
where Relaciones.Cursos.idCurso == idCursos
select new Usuario
{
Nombre = Usuario.Nombre,
Apellido = Usuario.Apellido,
DNI = Usuario.DNI,
};
usuarios = query.ToList();
}
the problem is that it never enter that if beacuse the idCursos is always null, even though my link route in the browser looks like this
http://localhost:54680/Usuarios/Index/3
Thanks
The action parameter name must match the parameter passed to the actionlink, so in your case
public ActionResult Index(int? id)
should take care of it
Update: I just noticed your URL, it is likely that your routing is configured to map to "id" parameter by default (if you haven't changed the default VS template).So even though the above correction works ... it is because the framework is expecting to map to the parameter "id" as configured in the routing.
I want map all urls like /Home/User or /Home/About or /Home/Register or ... to c# page like this:
for example User.cs Page is like this:
public class User
{
public string run(UrlParameter id){
return "Hello World";
}
}
i want when user send request for /Home/User .. Call Run function of User Class and show return value to user. How can i do that in ASP MVC?
can i do this with change routes in RouteConfig? now current of my MVC routes is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and when i call some url program run an asp page in view folder as default of MVC Project in c#.net.
For more explains:
I have protocol between my client side and server side program that is JSON. i want return string JSON when client ask something and for do it i do not need to asp page for rendering html, i only need to call some function that return JSON to client.
How can i do that with MVC?
I'm assuming your question has two parts.
For the first part : Mapping a url to a page. This is in a sense what routing is. It maps a url to an action, which could be a page or maybe a resource like a picture, or a response like JSON data. Notice it's not always a page, generally a url maps to a resource.
Read the URL routing docs here:
routes.MapRoute(
name: "Default",
url: "/Page1",
defaults: new { controller = "Home", action = "Page1",
id = UrlParameter.Optional }
);
In the above example : fakedomain.com/Page1 will run the Page1 method on the HomeController class and if there isn't any code you've added in there it will search for a Page1.aspx or Page1.cshtml inside your views folder.
I would recommend at this point reading about REST. I suggest this article : How I explained REST to my wife
For your second part : How do you return JSON data. Well you use WebApi. See the docs here.
WebApi allows you to write controllers that return data based on the request. So if your client sends an Ajax request with accept headers set to application/json, WebApi will return JSON.
Also it follows the typical system of asp.net-MVC's controllers, routes and actions.
So to return JSON data that represents products you would have a ProductController that looks like this:
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup",
Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo",
Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer",
Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
}
With asp.net-mvc4 and the default routing setup for WebApi the above controller would respond to the following URLs
This would get all products
/api/products/
This would get call the GetProductById and return ONE product:
/api/products/put_id_here
I would highly recommend getting all the pre-requisites like visual studio and asp.net-mvc from Web Platform installer and then follow this tutorial.
I have a Person DB table that has a surname, name, and IdCity fields.
In the View, I've implemented an autocomplete field to let the user digit the city.
How should I design the ViewModel for handling the IdCity and how can I pass it to the controller? It is a string but I need to pass the id and eventually insert it in the DB if it does not exist there yet.
Receive the city name in your view action, then look if a city exists for this name. If it does, use its ID. If it doesn't create a new one, and use that ID:
public ActionResult Update(PersonModel model)
{
var city = _cityRepository.GetCityByName(model.CityName);
if (city == null) _cityRepository.Add(city);
// At this point city.Id contains your city Id
var person = new Person
{
...
CityId = city.Id,
...
};
// Proceed to save your Person object
}
How can I get pretty urls like localhost:8888/News/Example-post instead of localhost:8888/Home/Details/2
My HomeController has the following for the Details method
public ActionResult Details(int id)
{
var ArticleToView = (from m in _db.ArticleSet where m.storyId == id select m).First();
return View(ArticleToView);
As the ASP.NET routing system is somewhat complicated, there are many ways to accomplish what you describe.
First of all, do you just want to have a pretty URL for the Details method? If so, you might consider renaming HomeController to NewsController or moving the Details method into a new NewsController class - that will automatically form the /News part of the URL. If you don't want a /Details part, you might rename your Details method Index, as that will be automatically called by /News. Finally, you need to change your int id parameter into string name.
If you want many custom URLs, you're going to have to define your own routes. Here are two ways of doing this:
1.
The easiest way I've found is to use an ASP.NET MVC Attribute-Based Route Mapper. That way, all you have to do is add an attribute on each method you want a pretty URL for and specify what URL you want.
First, you must follow a few steps to set up the attribute-based route mapping system, as outlined on that link.
After completing those steps, you must change your method to look like this:
[Url("News/{name}")]
public ActionResult Details(string name)
{
var ArticleToView = (from m in _db.ArticleSet where m.storyName == name select m).First();
return View(ArticleToView);
}
2.
Alternatively, you can define your custom routes manually in Global.asax.cs. In your RegisterRoutes method, you can add the following in the middle:
routes.MapRoute(
"NewsDetails",
"News/{name}",
new { controller = "News", action = "Details", name = "" }
);
What I do on my sites is that I check the URL against either the Page Title or Page Stub in cases where the page titles could have the same name for instance if you have a site that posts a "Picture of the Week" you may want to use a stub instead of title as you'll have multiples named the same thing.
URLs look like this: http://mySite.com/Page/Verse-of-the-Week
Global.asax contains this:
routes.MapRoute("Pages", "{controller}/{pageID}", new { controller = "Page", action = "Index", pageID = "Home" });
PageController is this:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index(string pageID)
{
if (pageID == null)
{
pageID = pageRepository.HomeOrLowest();
}
var p = pageRepository.ByStub(pageID);
if (p == null) { return RedirectToAction("NotFound", "Error"); }
return View(p);
}
The repository looks like this:
private static Func<mvCmsContext, string, Page> _byStub =
CompiledQuery.Compile((mvCmsContext context, string pageTitle) =>
(from p in context.Pages
where p.pageTitle.Replace(" ", "-") == pageTitle
select p).SingleOrDefault());
public Page ByStub(string pageTitle)
{
return _byStub(context, pageTitle);
}
I hope that helps.
Edit to add duplicate handling:
private static Func<mvCmsContext, string, int> _pageExists =
CompiledQuery.Compile((mvCmsContext context, string pageTitle) =>
(from p in context.Pages
where p.pageTitle.Replace(" ", "-") == pageTitle
select p).Count());
public bool PageExists(string pageTitle)
{
return Convert.ToBoolean(_pageExists(context, pageTitle));
}
Validates like this:
IValidationErrors errors = new ValidationErrors();
if (CreateOrEdit == "Create")
{
if (pageRepository.PageExists(model.pageTitle) && !String.IsNullOrEmpty(model.pageTitle))
errors.Add("pageTitle", "A page with this title already exists. Please edit it and try again.");
}
Please check out this package I've created: https://www.nuget.org/packages/LowercaseDashedRoute/
And read the one-line configuration here: https://github.com/AtaS/lowercase-dashed-route
I am trying to create a route with a Username...
So the URL would be mydomain.com/abrudtkhul (abrudtkhul being the username)
My application will have public profiles based on usernames (Ex: http://delicious.com/abrudtkuhl). I want to replicate this URL scheme.
How can I structure this in ASP.Net MVC? I am using Membership/Roles Providers too.
Here's what you want to do, first define your route map:
routes.MapRoute(
"Users",
"{username}",
new { controller = "User", action="index", username=""});
What this allows you to do is to setup the following convention:
Controller: User (the UserController type)
Action: Index (this is mapped to the Index method of UserController)
Username: This is the parameter for the Index method
So when you request the url http://mydomain.com/javier this will be translated to the call for UserController.Index(string username) where username is set to the value of javier.
Now since you're planning on using the MembershipProvider classes, you want to something more like this:
public ActionResult Index(MembershipUser usr)
{
ViewData["Welcome"] = "Viewing " + usr.UserName;
return View();
}
In order to do this, you will need to use a ModelBinder to do the work of, well, binding from a username to a MembershipUser type. To do this, you will need to create your own ModelBinder type and apply it to the user parameter of the Index method. Your class can look something like this:
public class UserBinder : IModelBinder
{
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
var request = bindingContext.HttpContext.Request;
var username = request["username"];
MembershipUser user = Membership.GetUser(username);
return new ModelBinderResult(user);
}
}
This allows you to change the declaration of the Index method to be:
public ActionResult Index([ModelBinder(typeof(UserBinder))]
MembershipUser usr)
{
ViewData["Welcome"] = "Viewing " + usr.Username;
return View();
}
As you can see, we've applied the [ModelBinder(typeof(UserBinder))] attribute to the method's parameter. This means that before your method is called the logic of your UserBinder type will be called so by the time the method gets called you will have a valid instance of your MembershipUser type.
You might want to consider not allowing usernames of certain types if you want to have some other functional controllers like Account, Admin, Profile, Settings, etc. Also you might want your static content not to trigger the "username" route. In order to achieve that kind of functionality (similar to how twitter urls are processed) you could use the following Routes:
// do not route the following
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("content/{*pathInfo}");
routes.IgnoreRoute("images/{*pathInfo}");
// route the following based on the controller constraints
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
, new { controller = #"(admin|help|profile|settings)" } // Constraints
);
// this will catch the remaining allowed usernames
routes.MapRoute(
"Users",
"{username}",
new { controller = "Users", action = "View", username = "" }
);
Then you will need to have a controller for each of the tokens in the constraint string (e.g. admin, help, profile, settings), as well as a controller named Users, and of course the default controller of Home in this example.
If you have a lot of usernames you don't want to allow, then you might consider a more dynamic approach by creating a custom route handler.
You could have a route that looks like:
{username}
with the defaults of
Controller = "Users"
For the finished product of:
routes.MapRoute(
"Users",
"{username}",
new { controller = "Users" }
So that the Username is the only url parameter, the MVC assumes it passes it to the users controller.
Are you trying to pass it as a parameter to a Controller?
Theoretically you could do something like this:
routes.MapRoute("name", "{user}/{controller}/{action}", new { controller = "blah", action = "blah", user = "" })
I'm not too experienced with ASP.NET routing, but I figure that should work.
routes.MapRoute(
"Users",
"{username}",
new { controller = "Users", action="ShowUser", username=""});
Ok, what this will do is default the username parameter to the value of {username}
so even though you've written username="" it'll know to pass the value of {username} .. by virtue of the strings match.
This would expect
for the url form
http://website.com/username
Users Contoller
ShowUser Action (method in controller)
username parameter on the ShowUser action (method)