No breadcrumbs with MVCSiteMapProvider custom MvcRouteHandler - breadcrumbs

I have 2 routes in global.asax
routes.MapRoute(
"DefaultFriendlyUrl",
"Page/{FriendlyUrl}",
null,
new string[] { "MvcApplication2.Controllers" }
).RouteHandler = new FriendlyUrlRouteHandler();
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "index", id = UrlParameter.Optional },
new string[] { "MvcApplication2.Controllers" }
);
so, FriendlyUrlRouteHandler work all my /Page/blablabla routes and send to PageController with 1 action Index
public class FriendlyUrlRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var friendlyUrl = (string)requestContext.RouteData.Values["FriendlyUrl"];
PageItem page = null;
if (!string.IsNullOrEmpty(friendlyUrl))
page = PageManager.GetPageByFriendlyUrl(friendlyUrl);
if (page == null)
{
requestContext.RouteData.Values["controller"] = "home";
requestContext.RouteData.Values["action"] = "index";
requestContext.RouteData.Values["id"] = null;
}
else
{
requestContext.RouteData.Values["controller"] = "page";
requestContext.RouteData.Values["action"] = "index";
requestContext.RouteData.Values["id"] = page.PageID;
}
return base.GetHttpHandler(requestContext);
}
}
Then PageController get content for my page and show it. But MvcSiteMapProvider don't show breadcrumbs for these pages
SiteMap.cs
public class SiteMap : DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
var returnValue = new List<DynamicNode>();
returnValue.Add(new DynamicNode() { Key = "id1", Title="CustomPage", Controller="Page", Action="Index" });
return returnValue;
}
}
And my CustomPage doesn,t exists in #Html.MvcSiteMap().SiteMapPath(), but page is showed correctly. What,s wrong in my code?
So I can,t build tree of my custom pages in breadcrumbs string...

Please provide your Mvc.sitemap.
Your instance of DynamicNode appears to be missing the ParentKey.

Related

microsoft bot framework typing indicator form flow(Form Builder)

I need to add typing indicator activity inside the form flow, I have used the following code but it only works out side of form flow, once the user enter the form builder the typing indicator does not appear.
Activity replytyping1 = activity.CreateReply();
replytyping1.Type = ActivityTypes.Typing;
replytyping1.Text = null;
ConnectorClient connector2 = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector2.Conversations.ReplyToActivityAsync(replytyping1);
I am using the following code inside dialog to call the form builder:
var myform = new FormDialog<TrainingForm>(new TrainingForm(), TrainingForm.MYBuildForm, FormOptions.PromptInStart, null);
context.Call<TrainingForm>(myform, AfterChildDialog);
my form builder code:
public enum MoreHelp { Yes, No };
public enum Helpfull { Yes, No };
[Serializable]
public class TrainingForm
{
public string More = string.Empty;
public string usefull = string.Empty;
[Prompt("Is there anything else I can help you with today? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public MoreHelp? needMoreHelp { get; set; }
[Prompt("Was this helpful? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public Helpfull? WasHelpful { get; set; }
public static IForm<TrainingForm> MYBuildForm()
{
return new FormBuilder<TrainingForm>()
.Field(new FieldReflector<TrainingForm>(nameof(needMoreHelp))
.SetActive(state => true)
.SetNext(SetNext2).SetIsNullable(false))
.Field(new FieldReflector<TrainingForm>(nameof(WasHelpful))
.SetActive(state => state.More.Contains("No"))
.SetNext(SetNext).SetIsNullable(false)).OnCompletion(async (context, state) =>
{
if (state.usefull == "No")
{
await context.PostAsync("Sorry I could not help you");
}
else if (state.usefull == "Yes")
{
await context.PostAsync("Glad I could help");
}
if(state.More == "Yes")
{
await context.PostAsync("Ok! How can I help?");
}
context.Done<object>(new object());
})
.Build();
}
If you are attempting to send the typing activity from the dialog that loaded the FormFlow dialog, it will not work because the code in the parent dialog does not execute every time the FormFlow dialog is loaded.
However, you can modify the MessagesController and inspect the dialog stack. If the FormFlow dialog is the last dialog on the stack, then send typing:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity) {
if (activity.Type == ActivityTypes.Message)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(default(CancellationToken));
var stack = scope.Resolve<IDialogTask>();
if (stack.Frames != null && stack.Frames.Count > 0)
{
var lastFrame = stack.Frames[stack.Frames.Count - 1];
var frameValue = lastFrame.Target.GetType().GetFields()[0].GetValue(lastFrame.Target);
if(frameValue is FormDialog<TrainingForm>)
{
var typingReply = activity.CreateReply();
typingReply.Type = ActivityTypes.Typing;
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(typingReply);
}
}
}
await Conversation.SendAsync(activity, () => FormDialog.FromForm(TrainingForm.MYBuildForm));
}
else
{
this.HandleSystemMessage(activity);
}
return Request.CreateResponse(HttpStatusCode.OK);
}

MEF and WEB API 2.2

I am trying to inject dependencies into a Web Api Controller.
I created an own IHttpControllerActivator class and replaced the default one in lobalConfiguration.
public class SimpleASPWebAPIContainer : IHttpControllerActivator
{
private readonly CompositionContainer container;
public SimpleASPWebAPIContainer(CompositionContainer compositionContainer)
{
container = compositionContainer;
}
public IHttpController Create(System.Net.Http.HttpRequestMessage request, System.Web.Http.Controllers.HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
if (controllerType != null)
{
var export = container.GetExports(controllerType, null, null).FirstOrDefault();
IHttpController result = null;
if (null != export)
{
result = export.Value as IHttpController;
}
else
{
//result = base.GetControllerInstance(requestContext, controllerType);
//container.ComposeParts(result);
}
return result;
}
else
{
return null;
}
}
public void Dispose()
{
if (container != null)
container.Dispose();
}
}
var apiSimpleContainer = new SimpleASPWebAPIContainer(container);
System.Web.Http.GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), apiSimpleContainer);
But when the client app is calling a controller method the IHttpControllerActivation Create method is not invoked.
Anybody can help me?
It was a very silly mistake.
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
MefConfig.RegisterMef(config);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
AutoMapperConfig.InitAutoMapper();
}
I should have to used the new HttoConfiguration instance to replace default IHttpControllerActivator instead of System.Web.Http.GlobalConfiguration.Configuration.

RegisterRoutes in ASP.NET MVC 4

I have two areas Admin and SecurityGuard. Routing shown below. Displays error:
System.ArgumentException: The route with the name "Admin_default" is already in the family route. Names must be unique routes.
Parameter name: name
RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Main", action = "Index", id = UrlParameter.Optional }
);
AreaRegistration.RegisterAllAreas();
}
Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
AdminAreaRegistration:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new { controller = "Slider|Product" },
namespaces: new[] { "CaterWebsite.Areas.Admin.Controllers" }
);
}
SecurityGuardAreaRegistration:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute("SearchMembership", "SecurityGuard/Membership/index/{searchterm}/{filterby}",
new { controller = "Membership", action = "Index", searchterm = UrlParameter.Optional, filterby = "all" }
);
context.MapRoute("Membership", "SecurityGuard/Membership/{action}/{userName}",
new { controller = "Membership", userName = UrlParameter.Optional }
);
context.MapRoute(
"SecurityGuard_default",
"SecurityGuard/{controller}/{action}/{id}",
new { controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
}
Remove AreaRegistration.RegisterAllAreas(); from your RegisterRoutes method. You are calling it twice.
You have it specified in the right place in your Application_Start method.

How can I change the user while using the Facebook C# sdk on Windows Phone?

I've started using the C# facebook sdk in my WP7 app, and it works, but I can only log in once. I have a class that opens a web browser and loads a facebook login page. I type in my info, and it does what I want it to do. But once I try to log in again, it remembers the info I gave it earlier, and I can't test other facebook accounts. Does anyone know how to clear my old data so I can log in with another account?
You need to perform Logout operation for performing login operation with another account try this code for performing logout.
public partial class LogoutPage : PhoneApplicationPage
{
private Uri navigateUrl;
public FacebookOAuthResult FacebookOAuthResult { get; private set; }
public LogoutPage()
{
var appId = "173963872698818";
string[] extendedPermissions = new[] { "user_about_me", "offline_access" };
var oauth = new FacebookOAuthClient { AppId = appId };
var parameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "display", "wap" } //"popup works, touch not works
};
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
parameters["scope"] = scope.ToString();
}
var loginUrl = oauth.GetLoginUrl(parameters);
var logoutParameters = new Dictionary<string, object>
{
{ "next", loginUrl }
};
//Redirect to the following url.
// https://www.facebook.com/logout.php?next=YOUR_URL&access_token=ACCESS_TOKEN
//this.navigateUrl = oauth.GetLogoutUrl(logoutParameters);
var a = App.Current as App;
string absoluteURI = " https://www.facebook.com/logout.php?next=http://www.fengshuiexplorer.host56.com&access_token=" + a.myToken;
this.navigateUrl = new Uri(absoluteURI);
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
webBrowser1.Navigate(this.navigateUrl);
}
private void webBrowser1_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookOAuthResult result;
if (FacebookOAuthResult.TryParse(e.Uri, out result))
{
this.FacebookOAuthResult = result;
var a = App.Current as App;
a.isLoggedIn = false;
NavigationService.GoBack();
}
else
{
this.FacebookOAuthResult = null;
}
}
}
Or you could try to call below code snippets before you log in again.
await new WebBrowser().ClearCookiesAsync();

Populating ListBox in ASP.NET MVC from SQL CE (C#)

I can't find an example that suits my needs anywhere, so I'm asking you guys.
Im trying to populate a ListBox on my website with content from an SQL CE database.
I used Asp.Net MVC DropDownList Data Binding as an example to create my ListBox.
I have now hit a deadend and could use some help, here is what i got:
Index.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Headline</h2>
<% using (Html.BeginForm())
{ %>
<%= Html.ListBoxFor(x => x.SelectedItemId, new SelectList(Model.Items, "Value", "Text"))%>
<br /><input type="submit" value="Show" style="width: 72px" />
<% } %>
</asp:Content>
HomeController.cs
public ActionResult Index()
{
var model = new ItemsViewModel();
using (SqlCeConnection con = new SqlCeConnection(#"Data Source=|DataDirectory|\RSSdb.sdf;Persist Security Info=False"))
{
con.Open();
string cmdString = string.Format("SELECT Name, ID FROM TableIndex WHERE (Active = N'true')");
using (SqlCeCommand cmd = new SqlCeCommand(cmdString, con))
{
using (SqlCeDataReader dataRead = cmd.ExecuteReader())
{
model = new ItemsViewModel
{
Items = new[]
{
new SelectListItem { Value = "Foo", Text = "Foo" } ,
new SelectListItem { Value = "Bar", Text = "Bar" }
}
};
}
}
}
return View(model);
}
ItemsViewModel.cs
public class ItemsViewModel
{
public string SelectedItemId { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Now what i need is to have the code in HomeController.cs be something like this:
model = new ItemsViewModel
{
Items = new[]
{
While(dataRead.Read())
{
new SelectListItem { Value = dataRead["ID"], Text = dataRead["Name"] };
}
}
};
But this don't work, and i have no idea how else to do it, all help is appreciated.
You've probably realized by now that you can't put a while loop within an array initializer. One approach to solving this would be to create a method which will build the list for you like so:
public IList<SelectListItem> GetSelectListItems()
{
IList<SelectListItem> items = new List<SelectListItem>();
using (SqlCeConnection con = new SqlCeConnection(#"Data Source=|DataDirectory|\RSSdb.sdf;Persist Security Info=False"))
{
con.Open();
string cmdString = "SELECT Name, ID FROM TableIndex WHERE (Active = N'true')";
using (SqlCeCommand cmd = new SqlCeCommand(cmdString, con))
{
using (SqlCeDataReader dataRead = cmd.ExecuteReader())
{
while(dataRead.Read())
{
items.Add(new SelectListItem
{
Value = dataRead["ID"],
Text = dataRead["Name"]
});
}
}
}
}
return items;
}
Then your action could be as simple as:
public ActionResult Index()
{
var model = new ItemsViewModel
{
Items = GetSelectListItems()
};
return View(model);
}