Hi. Is this possible to separate URL parameters for two placeholder {Name} and {Surname} like below ?
routes.MapRoute(
name: "Users",
url: "Authorization/{Name}.{Surname}",
defaults: new { controller = "Authorization", action = "Verify" }
);
And in my action method use following code :
private bool Verify (string Name,string Surname)
{
[...]
}
Or do I have to use one placeholder and parse my string to extract information :
routes.MapRoute(
name: "Users",
url: "Authorization/{UserName}",
defaults: new { controller = "Authorization", action = "Verify" }
);
And in Action method use following code :
private bool Verify(string UserName)
{
string name = "UserNameTillDot";
string surname = "UserNameAfterDot";
[...]
}
The first approach is totally fine.
The problem is that your action in controller is defined as private:
Instead of
private bool Verify (string Name, string Surname)
{
[...]
}
It should be
public ActionResult Verify (string Name,string Surname)
{
[...]
}
Also if you want to allow null for Name or Surname you should make them optional:
routes.MapRoute(
name: "Users",
url: "Authorization/{Name}-{Surname}",
defaults: new { controller = "Authorization", action = "Verify", Name = UrlParameter.Optional, Surname = UrlParameter.Optional }
);
You also should place this route before your default route.
EDIT:
There is a issue with "." in the route you can replace it with "-"
Related
I'm trying to create a custom route which will include the users culture in the route (RouteValues). Using default routing convention everything works fine.
I have the following controller:
public class HomeController : Controller
{
public HomeController()
{
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
}
I believe I've configured localization in the app correctly as follows:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RequestLocalizationOptions>(opts =>
{
opts.SupportedCultures = new[] { new CultureInfo("en"), new CultureInfo("fr") };
opts.SupportedUICultures = opts.SupportedCultures;
opts.SetDefaultCulture("en");
opts.DefaultRequestCulture = new RequestCulture("en");
opts.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider);
opts.ApplyCurrentCultureToResponseHeaders = opts.ApplyCurrentCultureToResponseHeaders;
});
services.AddControllersWithViews(opts =>
{
opts.Filters.Add(new CultureFilter("en"));
});
services.AddLocalization();
services.AddMvc();
}
And I have an ActionFilter that sets the users culture based on the route value.
public class CultureFilter : IAuthorizationFilter
{
private readonly string defaultCulture;
public CultureFilter(string defaultCulture)
{
this.defaultCulture = defaultCulture;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var values = context.RouteData.Values;
string culture = (string)values["culture"] ?? this.defaultCulture;
CultureInfo ci = new CultureInfo(culture);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
}
Using the default routing convention I get the desired result (more or less).
Thus for the following routes:
endpoints.MapControllerRoute(
name: "culture-default",
pattern: "{culture=en}/{controller=Home}/{action=Index}");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}");
Thus while on the url "http://localhost" I get:
"#Url.ActionLink("Index", "Home")" = "http://localhost"
"#Url.ActionLink("Privacy", "Home")" = "http://localhost/home/privacy"
And while on the url "http://localhost/fr" I get:
"#Url.ActionLink("Index", "Home")" = "http://localhost/fr"
"#Url.ActionLink("Privacy", "Home")" = "http://localhost/fr/home/privacy"
Ok - so far so goood....
But when I add a custom route for the Privacy ActionMethod I can't seem to get the correct culture in the generated URL.
Thus for the following routes:
endpoints.MapControllerRoute(
name: "culture-privacy",
pattern: "{culture}/h/p",
defaults: new { culture = "en", controller = "Home", action = "Privacy" });
endpoints.MapControllerRoute(
name: "default-privacy",
pattern: "h/p",
defaults: new { controller = "Home", action = "Privacy" });
Thus while on the url "//localhost" I get:
"#Url.ActionLink("Index", "Home")" = "//localhost"
"#Url.ActionLink("Privacy", "Home")" = "//localhost/h/p"
And while on the url "//localhost/fr" I get:
"#Url.ActionLink("Index", "Home")" = "//localhost/fr"
"#Url.ActionLink("Privacy", "Home")" = "//localhost/en/h/p"
Presumably this is because I included the "culture = 'en'" in the default for the "culture-privacy" route, but shouldn't the default value of 'en' only be used if the culture is not otherwise specified in the route?
You are right, the reason is that the default value "en" is overriding the value passed in the route data. If you want to use the culture which user typed, try to use the culture value passed in the route data instead of a fixed value. Here is the code sample:
endpoints.MapControllerRoute(
name: "culture-privacy",
pattern: "{culture}/h/p",
defaults: new { culture = "{culture}", controller = "Home", action = "Privacy" });
i'm getting this error when i'm navigate browser to url:
localhost:10793/RealEstates/10
this my RouteConfig code:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Main", action = "Index" }
);
routes.MapRoute(
name: "RealEstates",
url: "RealEstates/{action}",
defaults: new { controller = "RealEstates", action = "Index" }
);
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id = UrlParameter.Optional }
);
}
}
my error:
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
when changed code to:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}",
// defaults: new { controller = "Main", action = "Index" }
//);
//routes.MapRoute(
// name: "RealEstates",
// url: "RealEstates/{action}",
// defaults: new { controller = "RealEstates", action = "Index" }
//);
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id = UrlParameter.Optional }
);
}
}
it's work but when i call on other actions in controller
localhost:10793/RealEstates/CreateAd
this error found
The parameters dictionary contains a null entry for parameter 'id' of
non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult ViewAd(Int32)' in
'Youe3lan.Controllers.RealEstatesController'. An optional parameter
must be a reference type, a nullable type, or be declared as an
optional parameter.
Parameter name: parameters
and this my controller:
namespace MvcAppliction1.Controllers
{
public class RealEstatesController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult ViewAd(int id)
{
return View();
}
public ActionResult CreateAd()
{
return View();
}
}
}
You need to change it to:
routes.MapRoute(
name: "RealEstatesViewAd",
url: "RealEstates/{action}/{id}",
defaults: new { controller = "RealEstates", action = "ViewAd", id UrlParameter.Optional }
);}}
Have a look here it might help:
http://msdn.microsoft.com/en-us/library/cc668201(v=vs.100).aspx
UPDATE
Add this to your controller:
public ActionResult ViewAd(Int32 id)
{
return View();
}
You see
localhost:10793/RealEstates/10
is translated to:
localhost:10793/RealEstates/ViewAdd/10
So you need that method in the controller accepting an it parameter.
you've flagged your id in your route as optional:
id = UrlParameter.Optional
but I bet your controller isn't nullable??
public ActionResult ViewAd(Int32 id)
{
}
So you cant post a null into your id even though the route allows it. If you change this to:
public ActionResult ViewAd(Int32? id)
{
}
You won't get the error message:
The parameters dictionary contains a null entry for parameter 'id' of
non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult ViewAd(Int32)' in
'Youe3lan.Controllers.RealEstatesController'. An optional parameter
must be a reference type, a nullable type, or be declared as an
optional parameter. Parameter name: parameters
I got an error - No action was found on the controller 'Action' that matches the request.
The url is http://localhost:37331/api/action/FindByModule/1.
The routing I used is
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Controller:
public class ActionController : ApiController
{
private IActionRepository repository = null;
[HttpGet]
[ActionName("All")]
public IEnumerable<JsonAction> All()
{
return from action in this.repository.Get()
select new JsonAction
{
ID = action.ID,
Text = action.Text.Trim(),
Description = action.Description.Trim(),
};
}
[HttpGet]
[ActionName("FindByModule")]
public IEnumerable<JsonAction> FindByModule(Int64 moduleId)
{
return from action in this.repository.FindByModule(moduleId)
select new JsonAction
{
ID = action.ID,
Text = action.Text.Trim(),
Description = action.Description.Trim(),
};
}
}
This is because there is a parameter name mismatch. From your route the value 1 is assigned to parameter named id and your action is looking for parameter named moduleId.
First option is to change your route like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{moduleId}",
defaults: new { moduleId = RouteParameter.Optional }
);
Second is to change your URL like this:
http://localhost:37331/api/action/FindByModule?moduleId=1
So the parameter name match.
My api had too many parameters and I was getting an error. I solved the problem with Route.
[Route("addressverification/{id}/{no}/{day}/{month}/{year}")]
public AdressVerificationResult Get(long? id, long? no ,long? day, long? month, long? year)
{
return new AdressVerificationResult
{
Aciklama = "19........4 kimlik numaralı kişinin 18.......1 adres numarasında 'YerlesimYeri' adres tipi için geçerli bir yurtiçi adres beyanı mevcuttur.",
DurumKod = true
};
}
my current url is something like this => http://localhost:4330/Restaurants/?Location=Manchester&Cuisine=0&NetProfit=0&Turnover=0&MaxPrice=120000&SortPriceBy=Low&Page=0
i want it to make something like this => http://localhost:4330/Restaurants/Manchester/?Cuisine=Chinese&MaxPrice=120000
Where Param Query string that doesnt have values (0) will not be included on query string URL
Is it possible?
UPDATED
stringAdd this to Global.asax routes
routes.MapRoute(
"Name of route", // Route name
"Restaurants/{cityid}/", // URL with parameters
new { controller = "Restaurants", action = "Index" } // Parameter defaults
);
This is controller:
public ActionResult Index(string city, int cuisine = 0, int ChineseMaxPrice=0)
{
Return View();
}
Like int cuisine = 0 - this set the default value to parameter if this parameter is not set in querystring
string city - is a parameter that should be in string (not optional)
Try adding add the corresponding route:
routes.MapRoute(
"Restaurants",
"Restaurants/{city}",
new { controller = "Restaurants", action = "Index", city = UrlParameter.Optional }
);
which would map to the Index action on the Restaurants controller:
public ActionResult Index(string city)
{
...
}
I am working on a website in asp.net mvc. I have a route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
// Parameter defaults
);
which is the default route. And I have a method
public ActionResult ErrorPage(int errorno)
{
return View();
}
Now if I want to run this code with http://something/mycontroller/Errorpage/1
it doesn't work. But if I change the parameter name to id from errorno
it works.
Is it compulsory to have same parameter name for this method? Or do I need to create separate routes for such situations?
So, you have a parameter named errorno, and you want it to have a value from parameter id. This is obviously the binding problem.
How to solve it:
create a class for model binder:
public class ParameterBinder : IModelBinder
{
public string ActualParameter { get; private set; }
public ParameterBinder(string actualParameter)
{
this.ActualParameter = actualParameter;
}
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object id = controllerContext.RouteData.Values[this.ActualParameter];
return id;
}
}
create a custom attribute for custom model binding:
[AttributeUsage(AttributeTargets.Parameter)]
public class BindParameterAttribute : CustomModelBinderAttribute
{
public string ActualParameter { get; private set; }
public BindParameterAttribute(string actualParameter)
{
this.ActualParameter = actualParameter;
}
public override IModelBinder GetBinder()
{
return new ParameterBinder(this.ActualParameter);
}
}
apply the new attribute to your action parameters as needed:
public ActionResult ErrorPage(
[BindParameter("id")]
int errorno)
{
return View();
}
Now your errorno will have the value, which was passed as id for your url.
Note: you can remove the paramter id from the example above, if you are sure you need it solved only for id.
Leaving this way will allow you bind other parameters too.
Option 1
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
public ActionResult ErrorPage(int id)
{
return View();
}
Option 2
routes.MapRoute(
"Default",
"{controller}/{action}/{errorno}",
new { controller = "Home", action = "Index", errorno = UrlParameter.Optional }
);
public ActionResult ErrorPage(int errorno)
{
return View();
}
Option 3
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
public ActionResult ErrorPage(int id)
{
int errorno = id;
return View();
}
use the bind attribute prefix:
public ActionResult Customer([Bind(Prefix = "id")]string cname) {}
#Parminder
The default route can handle all action with one parameter "id". And I think not every action need this parameter. So I change my default route
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index"}
);
and you can add a new route:
routes.MapRoute("errorpage", "yourcontroller/errorpage/{errorno}",
new {controller="controllername", action="errorpage"});
this just handle your controll name is "controllername". If you want to handle all controller, you can add this:
routes.MapRoute("errorpage", "{controller}/errorpage/{errorno}",
new {controller="controllername", action="errorpage"});
This method will create very much code in global.asax if you need a lot of custom route.
You could either rename the parameter in the default root (which probably is not a good idea) or rename it in the action method. Adding another root will not help because it will be the same as the default one and given an url the routing engine cannot distinguish between the two and will always take the first one in the list.
try to use the same name of parameter in action method as in in the route table url parameter.
global.asx
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
myController
public ActionResult ErrorPage(int id)
{
return View();
}