Asp.net Core 1.0 TagBuilder Append give Microsoft.Extensions.Internal.BufferedHtmlContent result - tag-helpers

I am trying to make <pager> tag helper and using TagBuilder.InnerHtml.Append in asp.net core 1.0 but the output generates Microsoft.Extensions.Internal.BufferedHtmlContent.
PagerTagHelper class Process method is shown below that creating li tags in main ul and append a tag in each li tag
public override void Process(TagHelperContext context, TagHelperOutput output)
{
int totalPages, currentPage;
var url = context.AllAttributes["link-url"];
output.TagName = "div";
output.PreContent.SetContent("<ul class=\"link-list\">");
var items = new StringBuilder();
for (var i = 1; i <= totalPages; i++)
{
// Creating li TagBuilder
var li = new TagBuilder("li");
// Creating a TagBuilder
TagBuilder a = new TagBuilder("a");
a.MergeAttribute("href", $"{url}?page={i}");
a.MergeAttribute("title", $"Click to go to page {i}");
a.InnerHtml.Append(i.ToString());
if (i == currentPage)
{
a.AddCssClass("active");
}
li.InnerHtml.Append(a.InnerHtml.ToString());
items.AppendLine(li.InnerHtml.ToString());
}
output.Content.SetContent(items.ToString());
output.PostContent.SetContent("</ul>");
output.Attributes.Clear();
output.Attributes.Add("class", "pager");
}
And the result of pager TagHelper output:
<ul class="link-list">
Microsoft.Extensions.Internal.BufferedHtmlContent
Microsoft.Extensions.Internal.BufferedHtmlContent...
</ul>

var ul = new TagBuilder("ul");
foreach (var item in links)
{
var li = new TagBuilder("li");
var a = new TagBuilder("a");
a.MergeAttribute("href", item.Attributes["href"].Value);
a.InnerHtml.Append(item.InnerText);
li.AddCssClass("test");
li.InnerHtml.AppendHtml(a);
ul.InnerHtml.AppendHtml(li);
}
output.Content.SetHtmlContent(ul);

Related

Loading a menu structure on every razor page in asp .NET Core

After user authentication I'm supposed to change the user menu based on the roles of the user.
To do this, I created a service which fetched the menu the user is expected to see:
public List<MenuStructure> LoadCompleteMenuRole(string role)
{
List<MenuStructure> resultList = null;
var menuHeaders = LoadMenuHeadersForTheGivenRole(role);
if (menuHeaders != null && menuHeaders.Count > 0)
{
resultList = new List<MenuStructure>();
foreach (var menuHeader in menuHeaders)
{
var menuStructure = new MenuStructure
{
MenuName = menuHeader.HeaderName,
Caption = menuHeader.Caption
};
var menuDetails = LoadMenuDetailsForTheGivenHeader(menuHeader.Id);
if (menuDetails != null && menuDetails.Count > 0)
{
menuStructure.MenuElements = new List<MenuElement>();
foreach (var menuDetail in menuDetails)
{
var menuElement = new MenuElement
{
ElementName = menuDetail.DetailName,
ElementCaption = menuDetail.Caption,
Destination = menuDetail.Destination
};
menuStructure.MenuElements.Add(menuElement);
}
}
resultList.Add(menuStructure);
}
}
return resultList;
}
My problem? Where do I implement the service so the menus get loaded in every razor page I create?

How to upload only first image from multiple selection?

I have this ActionResult what it does it upload multiple image to database. But i need another action that will upload only first picture to another table.
[HttpPost]
public ActionResult Add(Ads ads, IEnumerable<HttpPostedFileBase> images)
{
//Ensure model state is valid
if (ModelState.IsValid)
{
if(images != null) {
var imageList = new List<AdsImage>();
foreach (var image in images)
{
using (var br = new BinaryReader(image.InputStream))
{
var data = br.ReadBytes(image.ContentLength);
var img = new AdsImage { Id = ads.Id };
img.ImageData = data;
}
}
ads.AdsImage = imageList;
}
for example if I select photo 1 and 2 only 1 will be upload to database.
Appreciate for any helps. Thank you.
Use following code which will upload only first image
[HttpPost]
public ActionResult Add(Ads ads, IEnumerable<HttpPostedFileBase> images)
{
//Ensure model state is valid
if (ModelState.IsValid)
{
if (images != null)
{
var imageList = new List<AdsImage>();
var image = images.First();
using (var br = new BinaryReader(image.InputStream))
{
var data = br.ReadBytes(image.ContentLength);
var img = new AdsImage { Id = ads.Id };
img.ImageData = data;
}
ads.AdsImage = imageList;
}
}
}

Get list of roles of the secure page

How I can get list of the access roles for the secure page on the login page?
// Parse original url
var originalUrl = FormsAuthentication.GetRedirectUrl(User.Identity.Name, false);
var originalUrlArray = originalUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var pathToWebConfig = "~";
for (int i = 0; i < originalUrlArray.Length - 1; i++) {
pathToWebConfig += "/" + originalUrlArray[i];
}
var locationName = originalUrlArray[originalUrlArray.Length - 1];
// Get web config
var remoteWebConfig = (System.Configuration.Configuration)WebConfigurationManager.OpenWebConfiguration(pathToWebConfig);
// Find authorization section
AuthorizationSection authorizationSection = new AuthorizationSection();
foreach (ConfigurationLocation location in remoteWebConfig.Locations) {
if (location.Path.Equals(locationName)) {
authorizationSection = (AuthorizationSection)location.OpenConfiguration().GetSection("system.web/authorization");
break;
}
}
// Get roles
var listOfRoles = new List<string>();
foreach (AuthorizationRule rule in authorizationSection.Rules) {
if (rule.Action != AuthorizationRuleAction.Allow) {
continue;
}
foreach (var role in rule.Roles) {
listOfRoles.Add(role);
}
}

How to read the Dynamic form Child data in Flex?

i created a form dynamically by adding each component in action script,
now i want to get back the text/data entered in to that each component dynamically?
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
break;
}
myform.addChild(fm);
}
}
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in formItems)
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
<mx:Form id="myform" cornerRadius="5" borderColor="#B7BABC" borderStyle="solid" width="100%" height="100%" />
<mx:HBox width="100%" height="100%" >
<mx:Spacer width="120"/>
<mx:Button label=" Save " id="saveBtn" click="saveToDb()" />
</mx:HBox>
You're creating the input components in ActionScript, but based on this code you are not creating them dynamically; you're just hard coding them. With your given sample, you'll know the components you are creating at compile time.
You'll need to store a reference to the form items you create; make them public variables instead of 'var' local variables. Kind of like this:
protected var ti:TextInput ;
protected var ta:TextArea ;
protected var df:DateField;
Then in your creation method, do something like this:
ti = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
ta = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
df = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
myform.addChild(fm);
Then when you need to access them, just do something like this:
private function getMyformData()
{
ti.text;
ta.text;
}
If you're generating the form components at run time based on data, then store then form elements in an array of some sort.
You could also work something out by looping over all children of your container, although that wouldn't be my first approach.
Since poster posted more complete code; here are some additions. I added the protected array of all form items and in each 'switch' block; the new input element is pushed onto the array.
<mx:Script>
protected var itemsArray : Array = new Array();
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
itemsArray.push(ti)
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
itemsArray.push(ta)
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
itemsArray.push(mycb)
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
itemsArray.push(df)
break;
}
myform.addChild(fm);
}
}
The sateToDb method will change to be something like this:
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in itemsArray )
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
Edited Response:
OK, I think I see the issue.
You're adding your data controls to FormItems and adding those to the Form. But then you're iterating over the Form's children and as if they were the data controls and not FormItems.
Without commenting on the rest of the code, have a look at what this updated function is doing to retrieve the data controls:
private function saveToDb():void
{
var formItems:Array = myform.getChildren();
for each (var item:FormItem in formItems)
{
var itemChildren:Array = item.getChildren();
for each (var control:UIComponent in itemChildren)
{
if (control is TextInput)
{
var text:String = Object(item).text;
Alert.show("TextInput");
}
else if (control is DateField)
{
var date:Date = DateField(item).selectedDate;
Alert.show("Date");
}
}
}
You can delete the formItemArray variable too, it's not needed since we're getting the list of children from the Form and FormItems.
Original response:
If you keep a reference to each of the dynamic form items in an Array you can iterate over each of them in your getMyFormData() function.
e.g.
protected var formItems:Array = new Array();
// Other class stuff here...
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
formItems.push(ti); // Add item to array.
fm.addChild(ti);
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
formItems.push(ta); // Add item to array.
fm.addChild(ta);
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
formItems.push(df); // Add item to array.
fm.addChild(df);
myform.addChild(fm);
<mx:button click="getMyformData()"/>
private function getMyformData()
{
//How to get the myform Data dynamically here after validations... ? &
for each (var item:UIComponent in formItems)
{
if (item is TextInput || item is TextArea)
{
// Cast to Object to access the 'text' property without the compiler complaining.
var text:String = Object(item).text;
// Do something with the text...
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
// Do something with the date...
}
// Insert additional type checks as needed.
}
}
You'll have to work out what to do with the data on your own though :)
If you are using a separate list make sure you clear out the formItems array when you're done with it so you don't have references to the items keeping them in memory unnecessarily.
Instead of keeping a separate array of form items you could also iterate over the children in the fm container. You might have to make some assumptions about the children you'd be accessing but it looks like you have control over all of the children being added so that's no problem.
I hope that helps...
:)

how could I retrive all available themes name programmatically

I want to retrieve all theme names programmatically.
here is code. it should help you.
string dirPath = Server.MapPath( HttpRuntime.AspClientScriptVirtualPath + #"/App_Themes");
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(dirPath);
List<string> result = new List<string>();
if (di.Exists)
{
foreach (System.IO.DirectoryInfo dir in di.GetDirectories())
{
list.Add(dir.Name);
}
}
return result;
Copied from Source
public static string[] GetThemes() {
if (HttpContext.Current.Cache["SiteThemes"] != null) {
return (string[])HttpContext.Current.Cache["SiteThemes"];
} else {
string themesDirPath = HttpContext.Current.Server.MapPath("~/App_Themes");
string[] themes = Directory.GetDirectories(themesDirPath);
for (int i = 0; i <= themes.Length - 1; i++) {
themes[i] = Path.GetFileName(themes[i]);
}
// cache the array
CacheDependency dep = new CacheDependency(themesDirPath);
HttpContext.Current.Cache.Insert("SiteThemes", themes, dep);
return themes;
}
}

Resources