asp.net mvc route constraints regular expression - regex

I want to server dynamic pages using url without controller and action on the basis of page title
default url : domain.com/pages/details/1
I want this to be server as
domain.com/title-of-dynamic-page-in-db-space-replaced-with-dash
domain.com/about-us
domain.com/contact-us
if I am doing this without dash than routing will confuse with controller name
thats why I added dash - for dynamic pages
my action looks like this
// GET: Pages/View/5
public ActionResult View(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Page page = db.Pages.First(p => p.name_english == id.Replace("-"," "));
if (page == null)
{
return HttpNotFound();
}
}
my routes are
routes.MapRoute(
name: "aaaaa",
url: "{id}",
defaults: new { controller = "pages", action = "view" },
constraints: new { id = #"^[A-Za-z\d-]+$" } //*********help needed in this line ******************************
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
above Constrain ^[A-Za-z\d-]+$
accepts alpha(optional) numeric(optional) and dash(optional)
while I need alpha(optional) numeric(optional) and dash(*mandatory*)
this way routing engine will not confuse page title with controller/action as I will make sure my name of dynamic page will contain space(i m replacing with dash)
and my controller/action will not be named contained dash
also tell me, is this approach ok or not, is there any other optimized solution for this?

I hope the following snippet will work for you.
routes.MapRoute(
name: "aaaaa",
url: "{id}",
defaults: new { controller = "pages", action = "view" },
constraints: new { id = #"^([-]*[a-zA-Z0-9]*-[a-zA-Z0-9]*[-]*)+$" } //*********this should work**
);
//---------------------------------------
// ^([-]*[a-zA-Z0-9]*-[a-zA-Z0-9]*[-]*)+$
//---------------------------------------

Related

Microsoft Edge extension weird behaviour

I have a Microsoft Edge extension which blocks specific URLs and redirect the browser to another page where the user click a button and it redirects back to the original page.
The extension sends the original URL in the redirection URL and it is used when the target page redirect back to it.
My problem, sometime the original page sends not its own URL but a jpg image on it. It happens when the original page load a bit slowly in the browser.
I don't understand this error.
//background.js
const apps = [
['ABCD', 'abcd']
];
const triggerUrls = [
"http://abcd/*"
];
function logURL(requestDetails) {
const domain = (new URL(requestDetails.url)).hostname.replace('www.','').toLowerCase();
const partDomain = apps.findIndex(u => domain.toUpperCase().split('.')[0].includes(u[0]));
chrome.cookies.get({ 'url': requestDetails.url.toLowerCase(), 'name': 'status' },
function(data){
if (data === null) {
if (partDomain > -1) {
chrome.cookies.set({
url: requestDetails.url.toLowerCase(),
name: "status",
value: "opened"
});
var backUrl = requestDetails.url;
const url = 'http://warning.xx/?title=' + apps[partDomain][0] + '&url=' + backUrl;
chrome.tabs.update( requestDetails.tabId, { url: url} );
}
}
}
);
}
chrome.webRequest.onBeforeRequest.addListener(
logURL,
{urls: triggerUrls},
["blocking"]
);

Sitecore 8 SPEAK - Calling Custom components Javascript method

My question is somewhat similar to followin unanswered question. (Not sure though)
Sitecore 8 SPEAK: Getting an Error When calling a Method in JS File
I am using Sitecore8
On my page there is a button and on its click event I want to call add() of custom datasource component.
Layout:
JS Code for the Page:
define(["sitecore"], function (Sitecore) {
var JsonListPage = Sitecore.Definitions.App.extend({
initialized: function () {
alert('Inside Json PageList Init');
},
loadData: function () {
alert('Button clicked');
app.add();
}
});
return JsonListPage;
});
JS Code for the custom datasource component:
define(["sitecore"], function (Sitecore) {
var model = Sitecore.Definitions.Models.ControlModel.extend({
initialize: function (options) {
this._super();
this.set("json", null);
alert('Inside Jsondatasource Init');
},
add: function (data) {
var json = this.get("json");
if (json === null)
json = new Array();
// this is done because array.push changes the array to an object which then do no work on the SPEAK listcontrol.
var newArray = new Array(json.length + 1);
for (var i = json.length - 1; i >= 0; i--)
newArray[i + 1] = json[i];
newArray[0] = data;
this.set("json", newArray);
}
});
var view = Sitecore.Definitions.Views.ControlView.extend({
initialize: function (options) {
this._super();
this.model.set("json", null);
}
});
Sitecore.Factories.createComponent("JsonDatasource", model, view, ".x-sitecore-jsondatasource");
});
.cshtml for Custom component:
#using Sitecore.Mvc
#using Sitecore.Mvc.Presentation
#using Sitecore.Web.UI.Controls.Common.UserControls
#model RenderingModel
#{
var userControl = Html.Sitecore().Controls().GetUserControl(Model.Rendering);
userControl.Requires.Script("client", "JsonDatasource.js");
userControl.Class = "x-sitecore-jsondatasource";
userControl.Attributes["type"] = "text/x-sitecore-jsondatasource";
userControl.DataBind = "Json: json";
var htmlAttributes = userControl.HtmlAttributes;
}
<div #htmlAttributes>
am here again
</div>
When the page loads:
It shows alert from Custom components Init
Then shows alert from host page's Init
On button click it shows the alert and after that gives error on "app".
There is some bit which I am missing.. any help would be appreciated.. Please let me know if you need anymore inputs.
Thanks in advance!
app is only available in debug mode so id avoid using that, use "this" instead.
From your code example it appears that you are calling app.Add(), There is no Add function on your pageCode, this is what your code is doing. Instead you need to access your components's Add Method.
Instead to access events within your component you want to call the function like this:
this.ComponentID.Add();
I have an example of a custom SPEAK component here you can refer to for how to create the component. https://github.com/sobek1985/MikeRobbinsSPEAKRichTextEditor
From the code is seems your creating a JSON datasource, there is an example by Anders here http://laubplusco.net/creating-simple-sitecore-speak-json-datasource/

Ember-simple-auth: Authenticating from URL

I have a requirement that I can append ?auth_token=x to any URL in my app and it will restore the session as if you had a cookie or the details were stored in local storage.
I've tried every manner I can think of to implement this over the last few hours but I'm not getting anywhere. Is this possible? Where should I be looking to add such functionality?
I'm answering my own question here as I managed to find a solution, although how correct it is I'm not sure!
application.js:
// Really simple query parameter access
(function($) {
$.QueryString = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'))
})(jQuery);
initializers/authentication.js.coffee:
LocalStorageWithURLAuth = Ember.SimpleAuth.Stores.LocalStorage.extend
init: ->
if $.QueryString['auth_token']
auth_token = $.QueryString['auth_token']
Ember.$.ajax(
async: false
url: '/users/sign_in'
type: 'POST'
data: { auth_token: auth_token }
dataType: 'json'
).then (data) =>
#persist
auth_token: data.auth_token
auth_email: data.auth_email
user_id: data.user_id
authenticatorFactory: 'authenticator:devise'
#_super()
, (error) =>
#_super()
else
#_super()
Ember.Application.initializer
name: 'authentication'
initialize: (container, application) ->
Ember.SimpleAuth.Session.reopen
user: (->
userId = #get 'user_id'
if !Ember.isEmpty userId
container.lookup('store:main').find 'user', userId
).property('user_id')
container.register 'session-store:local-storage-url', LocalStorageWithURLAuth
Ember.SimpleAuth.setup container, application,
storeFactory: 'session-store:local-storage-url'
authenticatorFactory: 'authenticator:devise'
authorizerFactory: 'authorizer:devise'
I'm not sure I understand what you're doing. It seems like you're restoring the session from an auth token in the query string? That's actually what the authenticator's restore method is for (see docs here: http://ember-simple-auth.simplabs.com/ember-simple-auth-devise-api-docs.html#Ember-SimpleAuth-Authenticators-Devise-restore). Also when the application starts isn't the query string empty?

Ember.js global routed/transitioned events

Is it possible to subscribe to all transition events in the application? Or alternatively some observable property containing the current route?
I'm integrating with a third-party UI component that needs to be synchronized to the current route.
The application controller has a currentRouteName property, as explained here. It's mostly for debugging, but I imagine that it's a fairly stable property that could be used in production.
EDIT: If you need to be alerted of all changes, use the hashchange event like Ember does internally. This will only work if you're using hash based routing though. If you're using Ember's history API based routing, you'll have to use that.
In your app_controller you can add this snippet which fires on every path/route change
currentPathDidChange: function currentPathDidChange() {
var path = this.get('currentPath')
}.observes('currentPath')
I solved this by hooking into Router.didTransition
Live example: http://jsbin.com/yuzedacu/5/edit (modified the example found here)
App.Router.reopen({
updateCurrentRoute: function(infos) {
var appController = this.container.lookup('controller:application');
if (!('currentRoute' in appController)) {
Ember.defineProperty(appController, 'currentRoute');
}
if (infos && infos.length > 0) {
// The last part of the route contains the route name
var route = infos[infos.length - 1].name;
// Collect the dynamic route parameters
var params = infos.reduce(function(a, b) {
// Parameter can be named anything
// assume there are 0 or 1 parameters
for (var name in b.params) {
if (b.params.hasOwnProperty(name)) {
// 1 parameter
return a.concat(b.params[name]);
}
}
// 0 parameters
return a;
}, []);
var path = [route].concat(params);
Ember.set(appController, 'currentRoute', path);
} else {
Ember.set(appController, 'currentRoute', []);
}
},
didTransition: function(infos) {
this.updateCurrentRoute(infos);
return this._super(infos);
}
});

Configuring RESTAdapter to not set the .json extension for get / list requests

I'm using a cross domain REST api.
I have defined my custom REST adapter to trigg my API.
Pb is to remove the ".json" automaticaly set by ember-model.
How to configure my adapter to avoid setting my "replace function" (url=url.replace('.json', '');)
App.Book.adapter = Ember.RESTAdapter.create({
ajaxSettings: function(url, method) {
var authorization= "Basic " + btoa("login" + ":" + "pwd");
url=url.replace('.json', '');
return {
url: url,
type: method,
dataType: "json",
headers: {
"Authorization": authorization
},
};
}
});
App.Certificate.url='http://mysite/api/v1/books';
How to configure my adapter to avoid setting my "replace function" (url=url.replace('.json', '');)
Since ember-model does not provide any configuration option to change this behaviour, IMHO, your solution by doing url = url.replace('.json', ''); isn't that bad.
Another possible way I can think of could be to reopen the RESTAdapter and override the buildURL function to not include the .json.
Ember.RESTAdapter.reopen({
buildURL: function(klass, id) {
var urlRoot = Ember.get(klass, 'url');
if (!urlRoot) { throw new Error('Ember.RESTAdapter requires a `url` property to be specified'); }
if (!Ember.isEmpty(id)) {
return urlRoot + "/" + id;
} else {
return urlRoot;
}
}
});
But this is not that future proof if the original code changes and you want to update the lib you had to change also your override.
Hope it helps.