I have an endpoint where I can request multiple pieces of data (such as https://example.com/things?ids=1,2,3) that I'm querying using Siesta. I'm trying to figure out the proper behavior of my persistent entity cache if I only have some of the things cached. So, if I have thing 1 and thing 2, but not thing 3 cached, I'd like to return a partial hit and have Siesta also query my server with the original URL. However, my understanding is that if EntityCache.readEntity returns anything, then Siesta assumes that the query was fully fulfilled, and does not continue on to make the network request.
Is there a good way for me to implement a partial hit, or do I need to return nil from readEntity and wait for a response from the server?
Have your cache return the partial content with an Entity.timestamp in the distant past. (It’s fine to use zero.) This will cause the 1,2 partial content to appear immediately on launch and when offline, but loadIfNeeded() will consider that content stale and thus still trigger the request for 1,2,3.
Related
I'm having trouble getting my head around how to use Falcor for a particular use case.
Basically I need to take a few fields from a page and execute server side validation business logic. The page should just display whether the validation was successful or not and if not, the reason.
I could technically use a falcor get query, but they don't seem suited to multi-parameter calls
I could try and use a Falcor 'call', which would allow me to easily pass through multiple parameters, but is not suited to returning transient data.
Is this just a use case that Falcor should not really be used for or am I missing something?
All the data returned by a Falcor server is part of the model, transient or not.
A get is appropriate here because you want to read data. call are appropriate to make black box modifications to the model.
gets are always multi-parameters because you give the entire path of the data which can enclose whatever you want. Let's say we want to validate a URL. We could do something like:
getValue('updateProfileForm.website["http://example.com"].valid')
And that would return true of false depending on the URL. The result can be kept in cache eternally since it will never change (a URL is either always valid or it is not).
If the validation process needs to know the value of multiple fields at once, like password confirmation, you can do something like this:
getValue('updateProfileForm.password["new password"].confirm["new password"].valid')
If the validation depends on something external to the form, like what time it is, include this parameter in the path to maximize cache-ability.
I have a public static/singleton class with IsDataModified() which is affected by change in database, file, type of user, api, etc, processes immidiately, just returns a bool variable.
The frequency of modification of output data varies extremely from a minute to months, so I won't use sliding expiration, instead let duration be MAX or infinite.
But what I'm looking for is
List item
request by browser
MVC filter to check if cache missing or IsDataModified()
Update cache and return
Else return existing cache
I tried extending OutputCache, setting duration to very large number, but once the page is cached the filters are not triggered.
Basically I do not want the duration specified to be the deciding factor as to when cache will expire, rather IsDataModified() should be the deciding factor.
One approach I think is to create a simple filter and use output cache or similar object through code behind, but I could not find OutputCacheAttribute giving a cached viewresult.
Is this possible? Please suggest.
So I have implemented a solution built on top of Redis (memcache is a lot messier). I use an open source Redis Output Cache provider which basically creates a key corresponding to the URL of the page. Whenever the underlying data is changed for one of the pages I remove the value from Redis where the key maches some pattern. (My data sort of has a hierarchy so I delete the cache for more items when it is a piece of data from the parent that is updated).
Using a similar approach of deleting the cached page when the data is updated would probably also work for you. On a side note, I am thinking of trying to change my process so that I have a background service that creates the page when data is updated and replaces the cache so that the first users don't have a slow response after the page is first removed from the cache.
I have a .net application with a Form layer, a DB model layer (entity framework) and a Controller layer between this two layers.
I need to handle this situation:
User presses a button to edit some params
The form needs to request some DB data that represents the current state of those params
Possibly, the user request could be rejected because is N/A to current situation, in this case an error message box should be shown
A modal form is shown, the user changes params and confirm
Changes are made in the DB model
That's pretty simple.
The fact is that, at point 4, we need some of the data we already processed at point 2.
In particular:
at point 2 we request some data to the DB model, that data is likely not to be in cache, so a SQL query is performed
that data is processed by a local LINQ
state of several checkboxes to show in the modal form is returned
at point 4 we need again LINQ processed data
since we came from the Form layer, we do not have that data anymore
therefore data is requested again to the DB model, but this time it's in cache
that data is processed again by local LINQ
Is it worth to re-load and re-process data to maintain the MVC pattern?
I don't know how it works exactly in VB.NET, but if we look at this problem in a pure "MVC" way (at least, how I understand it), something is not right.
In this step, when the click is done, the form call the controller (all action pass by the controller)
The controller then needs to do the validation. If it needs the database to do that, so be it. Then, it redirect the user to a view. (Should it be a message box or another form to enter data)
Here, the user do the change in the form and then click on a button to submit. In this button, you call the controller again (another function/action).
In the controller, you can do the needed validation and insert/update the data in the database via LINQ. Then, you can redirect to the view.
Since a lot of time could have passed between the step 2 and step 4 and that the data could have changed between the 2 calls, I think that doing the request 2 times is ok. Also, since they are 2 different function in the controller, I don't think you have the choice.
That's how I see it, but I can be wrong :)
EDIT
I didn't know that the query to the database were time consuming and that it was an issue.If the absolute goal is to NOT make the user wait twice since time is important in this application, I guess you could store the object that you get at step 2 in memory and retrieve it with the controller (with some kind of helper class). It's like doing the query in the database, but in the memory. If you use the repository pattern, then the programmer who's coding the logic in the controller will not even know that he's querying something else than the database since it's another level of abstraction. You could free the memory right after the step 4.
Oh I'm not 100% sure but the flow pattern in your question does not look right?
The usual procedure is to DISPLAY the DATA and have an edit button there with the dataview
So you may have something like
Function ShowAddressDetails(OwnerId as long) as ActionResult
And your ActionResult is usually a MODEL that is to be passed to the VIEW
maybe (keeping with the address record sample) something like...
Return View(AddressRecordModel)
where the address record is extracted from SQL DB using the OwnerId parameter
And in your VIEW where your EDIT button is,
You have at least two choices,
Those being
1. Reload data from SQL (used where data may have changed since last action)
2. Pass the already loaded Model (Used where the data hasnt changed)
which would mean tha you have either (or both) of the following
Function EditAddressDetails(OwnerId as long) as ActionResult
or
Function EditAddressDetails(Model as AddressRecordModel) as ActionResult
Alternatively you may have "CHILDACTION"s as opposed to "ACTION"'s
Also do not forget the following...
in a HTTP GET request, the model is passed from the CONTROLLER TO the VIEW
in a HTTP POST request the Model is passed from the VIEW to the CONTROLLER
So you should indeed have the model (data)?
Finally if the sequence is ONLY used by ONE user then the data should not have changed between requests UNLESS and EDIT/AMEND/UPDATE request was completed successfully.
I'm creating an ASP.NET MVC 4 web application that displays different data depending on the id number in the query string. It's designed to give users safety information specific to them based on what county they live in, what type of job they have, etc. They don't use a user name to log in, they just click on a link in their email like: http://www.mysite.com?id=123456
In Session_Start of global.asax, I pull down their id from the query string and search for a record that matches through an API call. This returns a bunch of fields in a DataSet which I turn into a DataTable. I then use a foreach loop to loop through the DataTable and use Session.Add(name, value) to create the session variables which I will plug into the view.
It can take up to 10 seconds for the API call to go through, so I want to put up some sort of "Loading..." gif animation until the API call is complete. Once the initial API call is complete I don't have to do any more API calls.
What's the best way to accomplish this?
If you need a loading animation, then you need a rendered HTML page. That means making your API call via AJAX. You can still encapsulate the call in your own view, just call your view with AJAX. Once you're initiating the call with JavaScript, it's trivial to add a loading animation. If you don't use AJAX, there's nothing you can do about it, as the server won't return the response until the view has finished processing.
I am using the Redirect After Post pattern in my ASP.NET MVC application. I have
the following scenario:
User goes to /controller/index where he is asked to fill a form.
Form values are POSTed to /controller/calculate.
The Calculate action performs calculation based on input and instantiates a complex object containing the results of the operation. This object is stored in TempData and user is redirected to /controller/result.
/controller/result retrieves the result from TempData and renders them to the user.
The problem with this approach is that if the user hits F5 while viewing the results in /controller/result the page can no longer be rendered as TempData has been expired and the result object is no longer available.
This behavior is not desired by the users. One possible solution would be instead of redirecting after the POST, just rendering the results view. Now if the user hits F5 he gets a browser dialog asking if he wants to repost the form. This also was not desired.
One possible solution I thought of was to serialize the result object and passing it in the URL before redirecting but AFAIK there are some limitations in the length of a GET request and if the object gets pretty big I might hit this limitation (especially if base64 encoded).
Another possibility would be to use the Session object instead of TempData to persist the results. But before implementing this solution I would like to know if there's a better way of doing it.
UPDATE:
Further investigating the issue I found out that if I re-put the result object in TempData inside the /controller/result action it actually works:
public ActionResult Result()
{
var result = TempData["result"];
TempData["result"] = result;
return View(result);
}
But this feels kind of dirty. Could there be any side effects with this approach (such as switching to out-of-process session providers as currently I use InProc)?
Store it in the Session with some unique key and pass the key as part of the url. Then as long as the session is alive they can use the back/forward button to their heart's content and still have the URL respond properly. Alternatively, you could use the ASP cache, but I'd normally reserve that for objects that are shared among users. Of course, if you used the parameters to the calculation as the key and you found the result in the cache, you could simply re-use it.
I think redirect after post makes much more sense when the resulting Url is meaningfull.
In your case it would mean that all data required for the calculation is in the Url of /controller/result.
/controller/calculate would not do the calculation but /controller/result.
If you can get this done thinks get pretty easy: You hash the values required for the calculation and use it as the key for the cache. If the user refreshes he only hits the cache.
If you cant have a meaningfull url you could post to /controller/index. If the user hits F5 calculation would start again, but a cache with the hash as key would help again.
TempData is generally considered useful for passing messages back to the user not for storing working entities (a user refresh will nuke the contents of TempData).
I don't know of more appropriate place than the session to store this kind of information. I think the general idea is keep session as small as possible though. Personally I usually write some wrappers to add and remove specific objects to session. Cleaning them up manually where possible.
Alternatively you can store in a database in which you purge stale items on a regular basis.
I might adopt a similar idea to a lot of banks on their online banking sites by using one-time keys to verify all POSTs. You can integrate it into a html helper for forms and into your service layer (for example) for verification.
Let's say that you only want to post any instance of a form once. Add a guid to the form. If the form does not post back and the data is committed then you want to invalidate the guid and redirect to the GET action. If say the form was not valid, when the page posts back you need a new (valid) guid there in the form waiting for the next post attempt.
GUIDs are generated as required and added to a table in your DB. As they are invalidated (by POSTS, whether successful or not) they are flagged in the table. You may want to trim the table at 100 rows.. or 1000, depending on how heavy your app will be and how many rendered but not yet posted forms you may have at any one time.
I haven't really fine tuned this design but i think it might work. It wont be as smelly as the TempData and you can still adhere to the PRG pattern.
Remember, with PRG you dont want to send the new data to the GET action in a temp variable of some sort. You want to query it back from the data store, where it's now committed to.
As Michael stated, TempData has a single purpose -> store an object for one trip only and only one trip. As I understand it, TempData is essentially using the same Session object as you might use but it will automatically remove the object from the session on the next trip.
Stick with Session imho rather than push back in to TempData.