I have such a url:
www.test.com/MyAreaName/MyControllerName/MyAction?key1=value&key2=value
I need a method like:
string generatedUrlWithQueryParams = Url.Action<MyController>(x => x.MyAction(MyViewModel));
I need to call the above method from a .cs class NOT from razor html file.
How can I do that? I heard of asp.net mvc futures but I can not find the appropriate method or namespace to use that method.
Are you looking for something like this:
string url = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext);
If you have the Request available(it is available in your controller actions), you can use the UrlHelper class.
var urlBuilder = new UrlHelper(Request.RequestContext);
var url = urlBuilder .Action("YourAction", new YourViewModel { Age = 44, Code = "Test"});
or
var url = urlBuilder .Action("YourAction", "YourController",
new YourViewModel { Age = 44, Code = "Test"});
Assuming YourViewModel has Age and Code property and you need those as the route values of the generated url.
If you are invoking this code from another class, you may pass the RequestContext to that from your controller/action.
Related
I'm trying to get the edit URL of a content as a string from backend, the catch is I'm inside a workflow activity, so I can't use Url.Action... or Url.ItemEditLink... or other UrlHelpers as if it were a controller or a view. Also, although I'm inside a workflow, the contents I need it for are not part of the workflowContext or the activityContext, so I can't use those or tokens either.
A solution could be to get the content metadata and the site baseUrl and try to build it manually, but I think this way is prone to errors.
Thanks.
This is how I build a Uri in an activity:
public class MyClass : Task
{
private readonly RequestContext _requestContext;
...
public MyActivity(RequestContext requestContext, ...)
{
_requestContext = requestContext;
...
}
...
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext)
{
var content = ... get using ID
var helper = new UrlHelper(_requestContext);
var baseurl = new Uri(_orchardServices.WorkContext.CurrentSite.BaseUrl);
Uri completeurl = new Uri(baseurl, helper.ItemDisplayUrl(content));
yield return T("Done");
}
}
Turns out that I actually do build the Uri semi-manually, but I haven't had issues with this method. You may be able to use just the ItemDisplayUrl for navigation inside of Orchard; I had to get the full URL because the string gets sent to an outside program (Slack).
I created an ASP.NET Core 2 projects with razor pages and I would like to give the opportunity to the visitor to select a language. The first problem that I had was to change the web application url so that ti will include the current language code. I solved this problem by adding the following code in ConfigureServices.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
options.Conventions.AddFolderRouteModelConvention("/", model =>
{
foreach (var selector in model.Selectors)
{
var attributeRouteModel = selector.AttributeRouteModel;
attributeRouteModel.Template = AttributeRouteModel.CombineTemplates("{language=el-GR}", attributeRouteModel.Template);
}
});
});
}
}
Now I could visit a page using the following URL:
http://domain/el-GR/MyPage
The last thing that I would like to do is to change the culture of each request. The best solution that I fount which I do not like is to put the following code in my page:
System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo((string)RouteData.Values["language"]);
System.Globalization.CultureInfo.CurrentUICulture = new System.Globalization.CultureInfo((string)RouteData.Values["language"]);
This is not nice because I will have to add these lies in every razor page that I will create in my project.
Is there another way to set the culture for all the requests of my web application?
Refer to this article: https://joonasw.net/view/aspnet-core-localization-deep-dive
There are a few methods, I use the RequestCultureProviders.
NuGet: Microsoft.AspNetCore.Localization
in my Startup.Configure method.
IList<CultureInfo> sc = new List<CultureInfo>();
sc.Add(new CultureInfo("en-US"));
sc.Add(new CultureInfo("zh-TW"));
var lo = new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = sc,
SupportedUICultures = sc
};
var cp = lo.RequestCultureProviders.OfType<CookieRequestCultureProvider>().First();
cp.CookieName = "UserCulture"; // Or whatever name that you like
app.UseRequestLocalization(lo);
Set your cookie "UserCulture" to "c=zh-TW|uic=zh-TW" once.
And it works magically.
I'm trying to implement some domain name logic in my existing MVC5 app. The problem I'm running in to is if I try to use my custom subclass from Route, it doesn't respect the Namespaces field and throws an error because I have 2 different User controllers.
As a control, this works perfectly fine:
routes.MapRoute("Login",
"login/",
new { controller = "User", action = "Login" },
new[] { "Quotes.Web.Controllers" });
My DomainRoute class inherits from Route and just adds a Domain property. Here is the relevant constructor:
public DomainRoute(string domain, string url, object defaults, string[] namespaces = null)
: base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
Domain = domain;
DataTokens = new RouteValueDictionary {["Namespaces"] = namespaces};
}
and I register it like:
var loginRoute = new DomainRoute(
domain,
"login/",
new { controller = "User", action = "Login" },
new[] { "Quotes.Web.Controllers" });
routes.Add("Login", loginRoute);
DataTokens looks identical between the working version and my broken version yet it seems to ignore the fact that my DomainRoute has a Namespace entry
Multiple types were found that match the controller named 'User'. This can happen if the route that services this request ('login/') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
What am I missing?
I think,this will help you, i had the same issue, solved this by adding the below code
var dataTokens = new RouteValueDictionary();
var ns = new string[] {"MyProject.Controllers"};
dataTokens["Namespaces"] = ns;
routes.Add("Default", new CultureRoute(
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
null /*constraints*/,
dataTokens
));
I switched my DomainRoute class with the much improved version found here: https://gist.github.com/IDisposable/77f11c6f7693f9d181bb
Now my route creation is just:
var clientRoutes = new DomainRouteCollection("mydomain",
"Quotes.Web.Controllers",
routes);
clientRoutes.MapRoute("Login", "login/", new { controller = "User", action = "Login" });
...which is more concise and even more importantly, it works.
My URL structure is like http://website.com/city-state/category e.g. /miami-fl/restaurants or /los-angeles-ca/bars. In order to send it to the correct controller, I have a class derived from RouteBase, which splits the request path and figures out the city, state and category. This is working fine for incoming URLs.
public class LegacyUrlRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData routeData = new RouteData();
routeData.RouteHandler = new MvcRouteHandler();
string url = httpContext.Request.Path.ToLower(); //e.g. url = /los-angeles
string[] path = url.TrimStart('/').Split('/'); //
if (path.Length > 1)
{
string[] locale = path[0].Split('-');
if (locale.Length > 1) //This is a city page, so send it to category controller
{
string stateName = locale[locale.Length - 1];
string cityName = path[0].Replace(stateName, "").TrimEnd('-');
routeData.Values.Add("controller", "Category");
routeData.Values.Add("action", "City");
routeData.Values.Add("categoryname", path[1]);
routeData.Values.Add("city", cityName);
routeData.Values.Add("state", stateName);
}
}
}
}
However, when I try to use Html.ActionLink to create a link, it doesn't pick up from this class.
#Html.ActionLink("Restaurants in Miami", "Index", "Category", new {categoryname="Restaurants", state="FL", city="Miami"})
gives me a url of /category/index?categoryname=restaurants&state=fl&city=miami.
How do I generate accurate links for my URL structure.
If you want your outgoing URLs to function, you must implement GetVirtualPath, which converts a set of route values into a URL. It should typically be the mirror image of your GetRouteData method.
The simplest way to implement it would just be to make a data structure that maps your route values to URLs and then use it in both methods as in this example.
I am working on publish event on facebook by Facebook C# SDK. I am able to login and generate Access Token through it. But when I am publishing event I got error :
Facebook.FacebookOAuthException: (OAuthException - #100) (#100) Param eid must be a valid event id
at Facebook.FacebookClient.ProcessResponse(HttpHelper httpHelper, String responseString, Type resultType, Boolean containsEtag, IList`1 batchEtags)
at Facebook.FacebookClient.Api(HttpMethod httpMethod, String path, Object parameters, Type resultType)
at Facebook.FacebookClient.Post(String path, Object parameters)
at FacebookSDK.Facebook.CreateEvent(FBEvent fbEvent)
My code is
public void CreateEvent(FBEvent fbEvent)
{
var fb = new FacebookClient(this.AccessToken);
dynamic parameters = new ExpandoObject();
parameters.eid = "524654568165461";
parameters.owner = "me";
parameters.description = fbEvent.Description;
parameters.name = fbEvent.Title;
parameters.start_time = fbEvent.StartTime.ToString("yyyy-MM-dd hh:mm:ss");
parameters.end_time = fbEvent.EndTime.ToString("yyyy-MM-dd hh:mm:ss");
parameters.privacy = fbEvent.PrivacyInfo;
parameters.access_token = this.AccessToken;
dynamic result = fb.Post("me/event", parameters);
}
How i can resolve it....
Are you creating a new event? If so, delete this line from your code:
parameters.eid = "524654568165461";
If you are trying to edit an event, this eid is wrong.
After searching a lot I found the solution for it ....
You have to consider following link
asp.net + facebook create event
In my case i am trying to get data as dynamic but changed to JsonObject, it is working for me like,
JsonObject result = facebookClient.Post("/me/events", createEventParameters) as JsonObject;
I am using facebook sdk v 6.0.20