I want to save some variables for future reference so I declared a class Container.cs
public class Container
{
public static String verifierCode;
}
and then I have my HomeController.cs where I update the Container's variables values:
public class HomeController : Controller
{
public ActionResult ValidateTwitterAuth()
{
Container.verifierCode = Request.Query.ElementAt(2).Value;
//do some stuff
}
public String sendTweet(String NewTweet)
{
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(Container.verifierCode, Container.authorizationId);
var user = Tweetinvi.User.GetAuthenticatedUser(userCreds);
user.PublishTweet(NewTweet);
return "sent!";
}
}
It gets updated in the ValidateTwitterAuth with the specific values but when the sendTweet method is called the Container.verifierCode is null.
I obviously tried to debug it but if I add the variable to quickwatch i get that
error CS0103: The name 'Container' does not exist in current context
Also, both the class and the container are in the same namespace.
Any idea/tip why this is happening? I am just trying to declare a global variable which I can access from other classes/controllers.
I apologise if this may sound like a beginner question but I'm just starting to get my hands on asp.net
EDIT: From the answers, my way of handling with the problem was wrong. Therefore I installed the Microsoft.AspNetCore.Session NuGet Package and used it like this:
HttpContext.Session.SetString("verifierCode", Request.Query.ElementAt(2).Value);
HttpContext.Session.SetString("authorizationId", Request.Query.ElementAt(0).Value);
and now it works. Thank you all for the answers!
You can store this data into session instead of class.as per below example
public class HomeController : Controller
{
public ActionResult ValidateTwitterAuth()
{
Session["verifierCode"] = Request.Query.ElementAt(2).Value;
//do some stuff
}
public String sendTweet(String NewTweet)
{
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(Session["verifierCode"], Container.authorizationId);
var user = Tweetinvi.User.GetAuthenticatedUser(userCreds);
user.PublishTweet(NewTweet);
return "sent!";
}
}
i have just change only verify code
Related
I am eventually trying to create a nav menu that can auto matically populate itself with the sites pages. I need to get a list of all the endpoints and store them to a database to be accessed by the logic (this will just be .txt or .json for now).
In my original post here: https://stackoverflow.com/questions/74988601/how-can-i-can-get-a-list-of-razor-pages-in-a-razor-pages-app I was able to get a list of all endpoints with a constructor, but unable to access these variables from anywhere but that specific razor page view. Thanks to Md Farid Uddin Kiron.
I tried simply copying the list to a variable in another class ("endpointStringTest" in the "JSONTest" class):
public class IndexModel : PageModel
{
public readonly IEnumerable<EndpointDataSource> _endpointSources;
public IndexModel(IEnumerable<EndpointDataSource> endpointDataSources)
{
_endpointSources = endpointDataSources;
}
public IEnumerable<RouteEndpoint> EndpointSources { get; set; }
public void OnGet()
{
EndpointSources = _endpointSources
.SelectMany(es => es.Endpoints)
.OfType<RouteEndpoint>();
foreach(var endpointSource in EndpointSources)
{
Console.WriteLine(endpointSource);
Debug.WriteLine(endpointSource.ToString());
JSONTest.endpointStringTest.Add(endpointSource.DisplayName);
}
Console.WriteLine(JSONTest.endpointStringTest);
Debug.WriteLine(JSONTest.endpointStringTest);
}
}
But this results in a null reference. If i understand correctly, this is due to constructors being initialized and deleted before normal classes are initialized? is there a way to work around this?
I also tried turning the above constructor into a regular method, but the variables were always null. I don't fully understand where "endpointDataSources" is getting it's value. It's obviously something to do with being initialized within a constructor, as thats the only time it's not null.
By writing the endpoints to a text file (or theoretically any kind of database) i can simply pass the info via that text file.
Index model: Gets a list of all page paths and then writes them to a text document. Obviously in practice you would want to format this as .json, .xml or to a database etc..
public class IndexModel : PageModel
{
public readonly IEnumerable<EndpointDataSource> _endpointSources;
public IndexModel(IEnumerable<EndpointDataSource> endpointDataSources)
{
_endpointSources = endpointDataSources;
}
public IEnumerable<RouteEndpoint> EndpointSources { get; set; }
public void OnGet()
{
EndpointSources = _endpointSources
.SelectMany(es => es.Endpoints)
.OfType<RouteEndpoint>();
//string filePath = App.enviroment;
StreamWriter writer = new StreamWriter("pagesTest.txt");
foreach (var endpointSource in EndpointSources)
{
Console.WriteLine(endpointSource);
Debug.WriteLine(endpointSource.ToString());
writer.WriteLine(endpointSource.ToString());
}
writer.Close();
}
}
PageListGetter model: this copies the contents of the previously created document and stores them in a variable.
public class PageListsModel : PageModel
{
public string? pageList;
public void OnGet()
{
StreamReader reader = new StreamReader("pagesTest.txt");
pageList = reader.ReadToEnd();
reader.Close();
}
}
I have also tested this on an Azure published version of the site and it works fine. I was concerned the filepaths may not line up or may be inaccessible from a regular model.
I have a question, that I tried to Google but honestly, I don't really know how to search or even ask this particular question.
Let's imagine I have the following:
Controller
[HttpGet]
public virtual ActionResult Summary()
{
var summaryViewModel = new CheckoutSummaryViewModel()
{
Products = ProductViewModel.BuildListFromShoppingCart(GetShoppingCart())
};
return View("_Summary", summaryViewModel);
}
ProductViewModel
public class ProductViewModel
{
public string Name
{
get; set;
}
public static List<ProdutoCheckoutViewModel> BuildListFromShoppingCart(ShoppingCart shoppingCart, IMappingService mappingService)
{
var itemsInCart = new List<ProductViewModel>();
foreach (var item in shoppingCart.ItemsInCart)
{
var itemViewModel = mappingService.Map<Product, ProductViewModel>(item.Product);
itemViewModel.Quantidade = item.Quantity;
itemsInCart.Add(itemViewModel);
}
return itemsInCart;
}
}
This is not production code. Is just so I can explain what I mean.
Is this the correct way of doing this?
Is there a better way than using static for building the list? I really don't want to do it inside the controller.
Passing IMappingService to the method does not look right. But maybe I'm just being picky. Is it the best way?
Another case, where I need to pass Session State to a static helper class.
public static Guid GetCheckoutId(HttpSessionStateBase session)
{
return (Guid)session["checkoutId"];
}
Or, also, sometimes I need to pass as parameter, to helper methods, my "unifOfWork", since I use the repository pattern.
I've come accross this "problem" a lot and I did not find the best way, yet, to do it.
PS: If any of you has a better title for this question, please tell me so I can update it.
Controller
If you use DI, it would look something like this:
public class CheckoutController
{
private readonly ICheckoutService _checkoutService;
public CheckoutController(ICheckoutService checkoutService) =>
_checkoutService = checkoutService;
[HttpGet]
public virtual ActionResult Summary()
{
var shoppingCartData = _checkoutService.GetShoppingCart(Session["..."]);
// The viewmodel here could be returned by your service or the service
// would return all required data and the viewmodel simply transforms that Dto into what is needed by the UI
var summaryViewModel = new CheckoutSummaryViewModel()
{
Products = shoppingCartData
};
return View("_Summary", summaryViewModel);
}
}
This is actually 2 questions in one.
I have an asp.net mvc application where I have to load a list of Modules, its just a simple list with ID, modulename and a class name to render it on the view with font awesome.
My model is like this:
public class Module
{
[Key]
public int Id { get; set; }
public string ModuleName { get; set; }
public string FontAwesomeClass { get; set; }
}
Because the module list is a Partial View that will render some icons on the top navigation bar, I dont want that for each refresh of the app, it goes to the DB, so it must be cached(I am using Azure REDIS Cache, not relevant for the question anyway), so instead of calling the DB context directly from the controller, I am calling a Cache Class that will check if the cache object exists, if not it will retrieve it from DB, if it does, it will return it from cache.
This my solution structure:
http://screencast.com/t/uayPYiHaPCav
Here is my controller Module.cs
public ActionResult GetModules()
{
return View(Cache.Module.GetModules());
}
As you can see the Controller does not have any logic where to get the data from.
Here is the Module.cs (on the Cache Namespace)
public class Module
{
private AppDataContext dbApp = new AppDataContext();
//Load modules from cache or from database
public static List<Models.Module> GetModules()
{
IDatabase cache = Helper.Connection.GetDatabase();
List<Models.Module> listOfModules = (List<Models.Module>)cache.Get("Modules");
if (listOfModules == null)
{
return dbApp.ModuleList.ToList();
}
else
{
return listOfModules;
}
}
}
Here I have a compiler error which I am not sure how to best fix it:
Error CS0120 An object reference is required for the non-static field,
method, or property 'Module.dbApp'
So that was my first question.
The 2nd question is more about the design pattern, do you consider this correct or not? the way I am trying to get the data from Cache, and its actually the Cache class which checks if data is on it or if it has to go to the DB.
First Question: make your private member static
private static AppDataContext dbApp = new AppDataContext();
2nd Question: your cache strategy seems pretty standard. The only thing is that you might want to expire cache data. For example, the cached data can get old and the longer it stays in the cache the older it gets. You might at some point want to expire it and get fresh data again.
Update:
#EstebanV for code sample (this off the top of my head, don't assume that it compiles):
/**
ICachedPersonDao abstracts away the caching mechanism
away from the core of your application
**/
public CachedPersonDao : ICachedPersonDao
{
private IPersonDao personDao = null;
public CachedPersonDao(IPersonDao personDao)
{
this.personDao = personDao;
}
public Person GetPersonById(int id){
bool isInCache = CACHE.SomeFunctionThatChecksInYourCache(id);
if (isInCache)
{
return CACHE.SomeFunctionThatReturnsTheCachedPerson(id);
}
else
{
//Well it's not in the cache so let's get it from the DB.
return this.personDao.GetPersonById(id);
}
}
}
/**
IPersonDao abstracts database communication
away from the core of your application
**/
public class PersonDao : IPersonDao
{
public Person GetPersonById(int id)
{
/** Get the person by id from the DB
through EntityFramework or whatever
**/
}
}
Usage:
In your controller, use ICachedPersonDao if you want to attempt to get from cache or use IPersonDao if you want to get it directly from the database without checking the cache.
Like I said, you should learn Dependency Injection it will help "inject" these dependencies into the classes that uses them.
I say again, this is off the top of my head. It won't compile. It's just to illustrate the concept.
Update
I've managed to create something that is satisfactory. You can see the relevant parts of the code here on PasteBin. If there is there something that I could improve please let me know. I've got a nagging feeling this isn't very efficient.
Clarification
While it certainly seems to work with static dependencies as suggested by d_z, I was hoping, to avoid instantiating objects not utlilized, that I could use something similar to this:
public class HomeController : Controller
{
[Dependency]
protected IBaseData ActionData { get; set; }
public ActionResult Index()
{
return View(ActionData);
}
public ActionResult About()
{
return View(ActionData);
}
}
The data in the IndexData and AboutData instances in reality aren't static. The instance properties are set with data from a database. The DbProvider is injected into these classes.
In the end what I want is to minimize the memory footprint and database accesses.
Original
Let's say we have the following basic controller (with corresponding views):
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
We also have two classes with the same interface:
public class IndexData : IBaseData
{
public string Name { get; set; }
public string Index { get; set; }
public IndexData()
{
Name = "Index";
Index = "This is an Index instance";
}
}
public class AboutData : IBaseData
{
public string Name { get; set; }
public string About { get; set; }
public AboutData()
{
Name = "About";
About = "This is an About instance";
}
}
What I'd like is for Unity to inject an instance of one of these classes, depending on which action is executed, into the corresponding view. I've tried to get my head around how to achieve this but I'm stumped. Is this even possible?
What you are requesting makes little sense. Dependency Injection is about injecting (design time) behavior (a.k.a. services). What you are trying to do however is to inject runtime data. So this is not a task that yout IoC container should handle.
Next the view should be completely ignorant of any dependency injection. The controller should return all data that the view needs from its action method. Make sure that your About and Index action methods return the proper instance.
To register several mappings for a type in Unity you have to create named registration like this:
myContainer.RegisterType<IBaseData, IndexData>("Index");
myContainer.RegisterType<IBaseData, AboutData>("About");
So after this in your actions you can resolve an instance accordingly:
Index:
IBaseData data = myContainer.Resolve<IBaseData>("Index");
About:
IBaseData data = myContainer.Resolve<IBaseData>("About");
Or for static dependencies it works like this:
[Dependency("Index")]
IBaseData data { get; set; }
Take a look here and here for details
I am a new developer and I am running into a problem where I want to assign an existing integer (on the domain) a value that is coming in from a user input from the web. How do I do this? Below is the code from my App solution.
Current error message: Cannot implicitly convert type 'int' to 'AppDomain.MainFrame.Entities'
model snippet: (WebFrame.cs)
namespace AppWeb.Models
{
public class WebFrame
{
...
public int Urgency {get; set;}
...
}
}
contoller snippet: (WebFrameController.cs) - WHERE I NEED HELP. I tried a few different thing but all resulted in the same error.
namespace AppWeb.Controllers
{
public class WebFrameController : Controller
{
...
[HttpPost]
public ActionResult Index(HttpPostedFileBase FileIn, WebFrame webFrameWork)
{
...
if (webFrame.Urgency != 0)
{
//>>> *** THIS IS WHERE I NEED HELP, I'VE TRIED A FEW THINGS TO NO AVAIL, INCLUDING HARDCODING NEEDDONEINDAYS =1*** <<<
//TODO:Assign Urgency from MVC Web App user input to Need Done In Days Value (= NeedDoneInDays) in Domain
Entities NeedDoneInDays = new Entities();
NeedDoneInDays = webFrame.Urgency;
//NeedDoneInDays = 1;
//NeedDoneInDays = Urgency;
}
.... does some processing to get to Log if necessary.
}
...
}
}
Page that has functions that will accept the Urgency Value.
AppDomain.MainFrame.Entities.Reporting.cs.
namespace AppDomain.MainFrame.Entities
{
public class Reporting
{
public static void LogToMainLogAndProcess(System.Web.HttpRequest hReq, System.DateTime StartTime, string projectType, int NeedDoneInDays)
{
//does some processing... logging and storing...
}
public static void LogAndReport(System.Web.HttpRequest hReq, string Department, System.DateTime StartTime, string projectType, int NeedDoneInDays)
{
//does some processing... logging and storing...
}
}
}
Thanks in advance for your help!
You are trying to assign an integer value webFrame.urgency to an object of type Entities, this doesn't make sense, hence the error. Is it that the Entities object has a property for urgency which is an integer ?