How to give duplicate name in the url bar - asp.net-mvc-3

How to duplicate the names in the url bar. For example i am having products controller and index method. Now in my project i am running like localhost:89733/Products/Index. But instead of Products/Index what want to give another name to run the same action method. How can i do that. I mean i don't want to leak my controllers information to others. Any help is appreciated.

You could configure a custom route:
routes.MapRoute(
"ProductsRoute",
"mycustomproductsname/{id}",
new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
Now when you navigate to mycustomproductsname/123, the Index action of the Products controller will be executed and passed 123 as id parameter.

i Hope Routing can solve the purpose In Global.asax file apllication start event
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RegisterRoutes(RouteTable.Routes);
}
public void RegisterRoutes(RouteCollection routes)
{
//Treeview routing
routes.MapPageRoute("Home", "User/Dashboard", "~/Products/Index");
routes.MapPageRoute("SearchCustomer", "User/Search-Customer", "~/Products/SearchCustomer");
}
i Hope you were asking for this and it helps you

Related

Restricting auto Help Page contents when using Attribute Routing in Web API 2

I'm currently implementing a Web API using Web API 2's attribute routing (http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2). I am also using the Help Pages module in order to automatically generate documentation from XML comments (http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages).
For this API I am providing support for optional return format extensions, so that every API method has a pair of routes defined on it like so:
[HttpGet]
[Route("Path/Foo")]
[Route("Path/Foo.{ext}")]
public HttpResponseMessage DoFoo()
{
// Some API function.
}
This allows a user to hit any of these and get a result:
www.example.com/api/Controller/Path/Foo
www.example.com/api/Controller/Path/Foo.json
www.example.com/api/Controller/Path/Foo.xml
My issue is that when Help Pages uses MapHttpAttributeRoutes() to generate documentation, it is picking up both routes for each method. So right now I see help for:
api/Controller/Foo
api/Controller/Foo.{ext}
But I want to only see:
api/Controller/Foo.{ext}
I would prefer to hide the non-extension route on each method, so that every method only shows a single Help Page entry.
Has anyone else tried something similar? Is there a work around that I am missing?
My question would be is that, would consumers of your api figure out easily that the {ext} is optional?...personally, I would prefer the default behavior...but anyways following are some workarounds that I can think of:
A quick and dirty workaround. Split the DoFoo into 2 actions like DoFoo() and DoFooWithExt maybe. Notice that I am using an attribute called ApiExplorerSettings, which is for HelpPage purposes. Example below:
[HttpGet]
[Route("Path/Foo")]
[ApiExplorerSettings(IgnoreApi=true)]
public HttpResponseMessage DoFoo()
{
return DoFooHelper();
}
[HttpGet]
[Route("Path/Foo.{ext}")]
public HttpResponseMessage DoFooWithExt()
{
return DoFooHelper();
}
private HttpResponseMessage DoFooHelper()
{
//do something
}
Create a custom ApiExplorer (which HelpPage feature uses internally) and check for specific routes like the following and can decide whether to show the action or not for that particular route.
// update the config with this custom implementation
config.Services.Replace(typeof(IApiExplorer), new CustomApiExplorer(config));
public class CustomApiExplorer : ApiExplorer
{
public CustomApiExplorer(HttpConfiguration config) : base(config)
{
}
public override bool ShouldExploreAction(string actionVariableValue, HttpActionDescriptor actionDescriptor, IHttpRoute route)
{
if (route.RouteTemplate.EndsWith("Path/Foo", StringComparison.OrdinalIgnoreCase))
{
return false;
}
return base.ShouldExploreAction(actionVariableValue, actionDescriptor, route);
}
}
Get list of all ApiDescription from the default ApiExplorer and then filter out the descriptions which you do not like. Example:
Configuration.Services.GetApiExplorer().ApiDescriptions.Where((apiDesc) => !apiDesc.RelativePath.EndsWith("Path/Foo", StringComparison.OrdinalIgnoreCase))

Windows Phone Back button and page instance creation

I need to recreate new page instance on every page load (also when user pressed Back button).
So I overrided OnBackKeyPress method:
protected override void OnBackKeyPress(CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (NavigationService.CanGoBack) {
e.Cancel = true;
var j = NavigationService.RemoveBackEntry();
NavigationService.Navigate(j.Source);
NavigationService.RemoveBackEntry();
}
}
The problem is that I can't handle case when user press back button to close CustomMessageBox dialog. How can I check it? Or is there any way to force recreation of page instance when going back through history state?
Why do you need to recreate the page instance? If you are simply trying to re-read the data to be displayed, why not put the data loading logic into OnNavigatedTo()?
Assuming that is what you are actually trying to achieve, try something like this...
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// don't do your data loading here. This will only be called on page creation.
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LoadData();
base.OnNavigatedTo(e);
}
MyViewModel model;
async void LoadData()
{
model = new MyViewModel();
await model.LoadDataAsync();
}
}
If you also have specific logic that you need to run on first construction of the page vs. on a back key navigation, check the NavigationMode property of the NavigationEventArgs object that gets passed to OnNavigatedTo.
if(e.NavigationMode == NavigationMode.New)
{
//do what you need to do specifically for a new page instance
}
if (e.NavigationMode == NavigationMode.Back)
{
// do anything specific for back navigation here.
}
Ha, in the near thread, i have opposite question :)
What about MessageBox - it depends, which one are you using. It can be custom message box, for example. Anyway, try to check MessageBox.IsOpened (or alternative for your MessageBox) in your OnBackKeyPress().
Another solution is to use OnNavigatedTo() of the page you want to be new each time.
Third solution: in case you works with Mvvm Light, add some unique id in ViewModel getter, like
public MyViewModel MyViewModel
{
get
{
return ServiceLocator.Current.GetInstance<MyViewModel>((++Uid).ToString());
}
}
This would force to recreate new ViewModel each time, so you'd have different instance of VM, so you would have another data on the View.

How to Cleanup a ViewModel in Mvvm Light?

I have a list of items that goes to another page, That page is hooked up to a view model. In the constructor of this view model I have code that grabs data from the server for that particular item.
What I found is that when I hit the back button and choose another item fromt hat list and it goes to the other page the constructor does not get hit.
I think it is because the VM is now created and thinks it does not need a new one. I am wondering how do I force a cleanup so that a fresh one is always grabbed when I select from my list?
I faced the same issue, that's how i solved it.
Have a BaseView class, override OnNavigatedTo
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (NavigatedToCommand != null && NavigatedToCommand.CanExecute(null))
NavigatedToCommand.Execute(null);
}
add DependencyProperty.
public static readonly DependencyProperty NavigatedToCommandProperty =
DependencyProperty.Register("NavigatedToCommand", typeof(ICommand), typeof(BaseView), null);
public ICommand NavigatedToCommand
{
get { return (ICommand)GetValue(NavigatedToCommandProperty); }
set { SetValue(NavigatedToCommandProperty, value); }
}
On the necessary pages, add to xaml (and, of course, inherit BaseView )
NavigatedToCommand="{Binding OnNavigatedToCommand}"
In the ViewModel, make command itself
public RelayCommand OnNavigatedToCommand
{ get { return new RelayCommand(OnNavigatedTo); } }
and implement method you want to call to update list
public async void OnNavigatedTo()
{
var result = await myDataService.UpdateMyList();
if (result.Status == OK)
MyList = result.List;
}
So, now, every time you navigate to page with list, inside of overriden OnNavigatedTo(), a NavigatedToCommand would be executed, which would execute OnNavigatedToCommand (which you set in xaml), which would call OnNavigatedTo, which would update your list.
A bit messy, but MVVM :)
EDIT: What about cleanings, they can be done in OnNavigatedFrom(), which works the same. Or OnNavigatingFrom(), which also can be useful in some cases.

HttpRoutes - how do they work?

I´m struggling with URLs for ajax-reader/JSON. Each time I think I understand it, it seems that I haven´t.
Please, can anybody explain the logic behind this???
I got this Controller:
public class ServiceController : DnnApiController
{
[AllowAnonymous]
[HttpGet]
public HttpResponseMessage GetAllItems(int moduleId)
{
MyProjectController controller = new MyProjectController();
IEnumerable<ItemInfo> items = controller.GetAllItems(moduleId);
return Request.CreateResponse(HttpStatusCode.OK, items);
}
}
I got this Routemapper:
public class RouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapHttpRoute("MyProject",
"default",
"{controller}/{action}",
new[] { "MyCompany.MyProject.Services" });
}
}
At what URL can I read the data with $.ajax() and what is the URL showing me the data in a browser?
Thanx in Advance!
Asle :)
This is how I do it (Note: this will only work with DNN6.2 and above);
In the View.ascx.cs add
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ServicesFramework.Instance.RequestAjaxScriptSupport();
ServicesFramework.Instance.RequestAjaxAntiForgerySupport();
jQuery.RequestDnnPluginsRegistration();
}
This ensures that jquery and the required DNN ajax plugins are added.
Initiate the services framework jquery plugin in the View.ascx like this inside javascript script tags (S.O. wouldn't allow me to include them)
var modId = <%=ModuleId %>;
var sf = $.ServicesFramework(modId);
Now in a separate javascript file or in the view.ascx control add the ajax function
function getAllItems(){
$.ajax({
type:"GET",
url:sf.getServiceRoot("MyProject")+"Service/GetAllItems",
beforeSend:sf.setModuleHeaders,
data:{moduleId:modId},
cache:false
}).done(function(data){
alert("Success!");
}).fail(function(){
alert("Crashed!");
}).always(function(){
//something you want done whether passed or failed
//like hide progress bar, ajax spinner etc.
});
}
The DNN jquery plugin will build the url which will look similar to this (Note: 142 is just for illustration purpose and will be replace with actual module id)
/DesktopModules/MyProject/API/Service/GetAllItems?moduleId=142
The URL will be something like
/desktopmodules/SlidePresentation/API/SlidePresetnation.ashx/ListOfSlides
I have examples at
https://slidepresentation.codeplex.com/SourceControl/latest
but they were for DNN6, they might require a few updates due to the API changes for DNN 7
you can see a DNN7 module that has a service layer at https://dnnsimplearticle.codeplex.com/SourceControl/latest#cs/services/

MVC 3 area using wrong controller

I'm using nopCommerce 2.3 and trying to setup a custom Area but the area tries to use the main applications Home controller during run-time and explodes. nopCommerce already has an area called "Admin" that is setup as a separate project and I'm simply trying to follow that architecture. I created a new MVC 3 application and removed all of the login related files and web.config registrations related to profiling and account registration. The area I created is clearly registering with the main application because you can browse its url path. However when you visit its path (http://mysite/backoffice/) it explodes because its trying to use the HomeController.cs file that is in the main application instead of the HomeController.cs that is in my area's assembly (Backoffice.dll). The assemblies/namespaces are completely different between my area project and the main project so I don't know why its confused. Is my registration correct below?
Here is my area registration:
namespace Backoffice
{
public class BackofficeRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Backoffice"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Backoffice_default",
"Backoffice/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional, area = AreaName },
new[] { "Backoffice.Controllers" }
);
}
}
}
Figured it out. see here: http://www.nopcommerce.com/boards/t/16098/new-mvc-3-area-registration.aspx#66171

Resources