Can I display contents of Application or Cache objects using Glimpse in an MVC project? - asp.net-mvc-3

The ASP.NET WebForms trace output has a section for Application State. Is it possible to see the same using Glimpse?
In my home controller's Index() method, I tried adding some test values, but I don't see the output in any of the Glimpse tabs.
ControllerContext.HttpContext.Application.Add("TEST1", "VALUE1");
ControllerContext.HttpContext.Cache.Insert("TEST2", "VALUE2");
I didn't see anything in the documentation either.

I don't think that there is an out-of-the-box support for this, but it would be trivial to write a plugin that will show this information.
For example to show everything that's stored in the ApplicationState you could write the following plugin:
[Glimpse.Core.Extensibility.GlimpsePluginAttribute]
public class ApplicationStateGlimpsePlugin : IGlimpsePlugin
{
public object GetData(HttpContextBase context)
{
var data = new List<object[]> { new[] { "Key", "Value" } };
foreach (string key in context.Application.Keys)
{
data.Add(new object[] { key, context.Application[key] });
}
return data;
}
public void SetupInit()
{
}
public string Name
{
get { return "ApplicationState"; }
}
}
and then you get the desired result:
and to list everything that's stored into the cache:
[Glimpse.Core.Extensibility.GlimpsePluginAttribute]
public class ApplicationCacheGlimpsePlugin : IGlimpsePlugin
{
public object GetData(HttpContextBase context)
{
var data = new List<object[]> { new[] { "Key", "Value" } };
foreach (DictionaryEntry item in context.Cache)
{
data.Add(new object[] { item.Key, item.Value });
}
return data;
}
public void SetupInit()
{
}
public string Name
{
get { return "ApplicationCache"; }
}
}

Related

ASP.NET Core - Session not getting saved

I'm trying to save my session in ASP.NET Core, but it is not getting saved.
I have looked at other answers, suggesting to change CookiePolicyOptions and nothing has worked so far. I have another project with the exact same code (presumably), and it works there but not in this project.
In my controller I have:
[HttpPost]
public IActionResult AddToPlan(int mealId)
{
PlanCart planCart = GetPlanCart();
planCart.AddItem(mealId);
SavePlanCart(planCart);
// ALWAYS 1
var y = planCart.returnList();
foreach (var x in y)
{
var z = x; // For debug purposes
}
return RedirectToAction("Index");
}
private PlanCart GetPlanCart()
{
PlanCart planCart = HttpContext.Session.GetJson<PlanCart>("PlanCart") ?? new PlanCart();
return planCart;
}
private void SavePlanCart(PlanCart planCart)
{
HttpContext.Session.SetJson("PlanCart", planCart);
}
I have a class with extension methods:
public static class SessionsExtensions
{
public static void SetJson(this ISession session, string key, object value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T GetJson<T>(this ISession session, string key)
{
var sessionData = session.GetString(key);
return sessionData == null
? default(T) : JsonConvert.DeserializeObject<T>(sessionData);
}
}
Startup class:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseCookiePolicy();
}
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMemoryCache();
I have checked my session. The session DOES exist but every time the count of the PlanCartList is 1 and previous items are lost.
If anybody could help me it would be very much appreciated because I'm losing my mind here!

How to working with data from client side using Observables

I am using the Grid of Kendo (Angular 2) for Add/Edit/Delete a Row in the grid:
http://www.telerik.com/kendo-angular-ui/components/grid/editing/
In the original Code, the data is obtained from a rest service like this:
private fetch(action: string = "", data?: Product): Observable<Product[]> {
return this.jsonp
.get(`http://demos.telerik.com/kendo-ui/service/Products/${action}? callback=JSONP_CALLBACK${this.serializeModels(data)}`)
.map(response => response.json());
}
But, I want to work with a array for add/edit/delete rows in memory. Next, I want to do click in the button submit and send the data (with all my changes) to the server.
My solution for this is like this:
https://gist.github.com/joedayz/9e318a47d06a7a8c2170017eb133a87e
Overview:
I declare an array:
private view: Array = [{ProductID: 1, ProductName: "pelotas", Discontinued: undefined, UnitsInStock: 80}];
and override the fetch method like this:
private fetch(action: string = "", data?: Product): Observable<Product[]> {
/*return this.jsonp
.get(`http://demos.telerik.com/kendo-ui/service/Products/${action}?callback=JSONP_CALLBACK${this.serializeModels(data)}`)
.map(response => response.json());*/
debugger;
if(action=="create"){
var product : Product = new Product(-1, data.ProductName, data.Discontinued, data.UnitsInStock);
this.view.push(product);
}else if(action=="update"){
var indice = this.view.indexOf(data);
if(indice>=0)
this.view[indice] = (JSON.parse(JSON.stringify(data)));
}else if(action=="destroy"){
var indice = this.view.indexOf(data);
if(indice>=0)
this.view.splice(indice, 1);
}
return Observable.of(this.view);
}
My Question is: Exists some way of communicate the create/update/delete of items in my array of a simple or reactive form to my grid?
As you are using in-memory array you do not need to use Observables. The Grid component is already bound to the array, thus it is just necessary to manipulate the data. For example:
export class AppComponent {
public dataItem: Product;
#ViewChild(GridEditFormComponent) protected editFormComponent: GridEditFormComponent;
private view: Array<Product> = [{ ProductID: 1, ProductName: "pelotas", Discontinued: undefined, UnitsInStock: 80 }];
public onEdit(dataItem: any): void {
this.dataItem = Object.assign({}, dataItem);
}
public onCancel(): void {
this.dataItem = undefined;
}
public addProduct(): void {
this.editFormComponent.addProduct();
}
public onSave(product: Product): void {
if (product.ProductID === undefined) {
this.createProduct(product);
} else {
this.saveProducts(product);
}
}
public onDelete(e: Product): void {
this.deleteProduct(e);
}
public saveProducts(data: Product): void {
var index = this.view.findIndex(x => x.ProductID === data.ProductID);
if (index !== -1) {
this.view = [
...this.view.slice(0, index),
data,
...this.view.slice(index + 1)
];
}
}
public createProduct(data: Product): void {
this.view = [...this.view, data];
}
public deleteProduct(data: Product): void {
this.view = this.view.filter(x => x.ProductID !== data.ProductID);
}
}

$select on navigation property / WebApi 2.0 / OData 4

Given the following simple OData 4 controller (please see below), how do I $select just the cities?
http://localhost//api/Customers?$select=Location
Gives me:
{
"#odata.context":"http://localhost/api/$metadata#Customers(Location)","value":[
{
"Location":{
"Country":"Ireland","City":"Sligo"
}
},{
"Location":{
"Country":"Finland","City":"Helsinki"
}
}
]
}
But I don't know how to drill down one deeper so that I just get the cities. Is this even possible?
public class CustomersController : ODataController
{
private List<Customer> customers = new List<Customer>()
{
new Customer
{
CustomerId = 1,
Location = new Address
{
City = "Sligo",
Country = "Ireland"
}
},
new Customer
{
CustomerId = 2,
Location = new Address
{
City = "Helsinki",
Country = "Finland"
}
}
};
[EnableQuery]
public List<Customer> Get()
{
return customers;
}
}
The grammar for $select does not allow a path expression like Location/City. Your best bet is to define an OData function bound to the Customers entity set. E.g.,
[HttpGet]
public IEnumerable<string> GetCities()
{
return customers.Select(c => c.Location.City);
}
And invoke it as follows:
GET http://localhost/api/Customers/ServiceNamespace.GetCities

Storing ActionLink in model or RouteValueDictionary in model

I wish to store an action link in the model.
Something like
public MvcHtmlString ActionLink_New
{
get { return Html.ActionLink("new", "Edit", "News", new { Area = "Admin" }, null); }
}
It appears the model needs a webviewpage context.
Failing that, I thought I would store just the route values.
public RouteValueDictionary[] RouteValue_New
{
get { return new RouteValueDictionary[] { Area = "Admin" }; }
}
//View
#Html.ActionLink("new", "Edit", "News", Model.RouteValue_New, null)
The Area in the property is red. Is either or both scenario achievable. What do i need to add to get this to work, thanks.
try this
public object RouteValue_New
{
get {
return new { Area = "Admin" };
}
}

Changing ASP.NET MVC 3 folder structure

I am interested in changing the structure folder. I have read many articles, but I have not found the solution.
I want to do so to distribute the files and folders on thematic folders. I have created a base class BaseViewEngine from RazorViewEngine
public class BaseViewEngine : RazorViewEngine
{
public BaseViewEngine()
{
MasterLocationFormats = new[]
{
"~/Themes/My/master.cshtml"
};
ViewLocationFormats = new[]
{
"~/Modules/{1}/{0}.cshtml"
};
PartialViewLocationFormats = new[]
{
"~/Blocks/{0}.cshtml"
};
}
}
But it is not working.
Update
Control is primitive. Only for test
public class HomeController : Controller
{
public ActionResult Index()
{
var test = new Test { Text = "Hello" };
return View(test);
}
}
And View
#model DemoModules.Test
<h2>Index</h2>
But when I run project. I Get error
CS0103: The name of the 'model' does
not exist in the current context
About structure folder, see the source of subject matter
You don't really have to implement a new engine to change the paths, you can just register them as you want:
private static void RegisterViewEngines(ICollection<IViewEngine> engines)
{
engines.Clear();
engines.Add(new RazorViewEngine
{
MasterLocationFormats = new[] { "~/Themes/My/master.cshtml" },
ViewLocationFormats = new[] { "~/Modules/{1}/{0}.cshtml" },
PartialViewLocationFormats = new[] { "~/Blocks/{0}.cshtml" },
});
}
protected void Application_Start()
{
RegisterViewEngines(ViewEngines.Engines);
}
For reference, the default paths are as follows (not including Areas):
ViewLocationFormats = new [] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
MasterLocationFormats = new [] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = new [] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
Check out this post: http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx
Hope this helps.
Take a look at the web.config file in the default Views folder. There's some stuff in there that is required for Razor views to work - particularly the base class for views and the namespaces that will be used to compile the view.

Resources