I am using MemoryCache in my WCF Rest Service. First time I hit the Database and cache the data in the Memory cache.
I have implemented it successfully. In my project, I have a requirement. I need to check cache key insertion time.
I want to add a condition if cache key is more then 15 minutes, I will again update the cache key.
I know that I can use
policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(15);
If I use this code, it will expire after 15 minutes.
Is there any way to know that when a cachekey insert into cache?
You can encapsulate your data in an object which contains ModificationTime property and cache this object.
class CacheData<T>
{
public DateTime ModificationTime { get; set; }
public T Data { get; set; }
}
You can create an instance of this object, set the time and data properties and cache with a cache key.
Related
I follow some tutorial on web to setup Spring Cache with redis,
my function look like this:
#Cacheable(value = "post-single", key = "#id", unless = "#result.shares < 500")
#GetMapping("/{id}")
public Post getPostByID(#PathVariable String id) throws PostNotFoundException {
log.info("get post with id {}", id);
return postService.getPostByID(id);
}
As I understand, the value inside #Cacheable is the cache name and key is the cache key inside that cache name. I also know Redis is an in-memory key/value store. But now I'm confused about how Spring will store cache name to Redis because looks like Redis only manages key and value, not cache name.
Looking for anyone who can explain to me.
Thanks in advance
Spring uses cache name as the key prefix when storing your data. For example, when you call your endpoint with id=1 you will see in Redis this key
post-single::1
You can customize the prefix format through CacheKeyPrefix class.
I have a multi-tenant system where each tenant shares the same instance of the codebase, but has their own databases.
I'm using RavenDB for persistence, with a standard c# facade/BLL backend wrapped with Asp.net WebAPI, and I'm finding that at every lower level operation (deep within my business logic classes) that touch the datbase, I need to pass in an identifier so that my RavenDb client session knows which database to operate against.
When the user authenticates, I resolve the appropriate database identifer, store it in the session manager. Every call against the Web API layer passes in a session ID which resolves the database ID in the backend, which is then used to pass into every single facade/BLL call.
All my dependencies are handled via an IoC container at the WebAPI level, but i can't pass in the database ID at this phase because it can be different for every user that is logged in.
this, of course is getting tedious.
can someone give me some guidance as to what I can do to alleviate this? Maybe perhaps some sort of policy injection/AOP solution?
a rough sample of my backend code looks like..
public class WidgetService()
{
private WidgetBLL _widgetBLL;
private ISessionManager _sessionManager;
public WidgetService(WidgetBLL _widgetBLL, ISessionManager sessionManager)
{
_widgetBLL = widgetBLL;
_sessionManager = sessionManager
}
public Widget getWidget(string sessionId, string widgetId)
{
string DbId = sessionManager.ResolveDbId(sessionId)
return _widgetBLL.GetWidget(string dbId, string widgetId);
}
}
public class WidgetManager()
{
public GetWidget(string dbId, string widgetId)
{
using (IDocumentSession session = documentStore.OpenSession(dbId)
{
var widget = session.load<Widget>(widgetid);
}
return widget;
}
}
the DBID is the identifier for that particular tenant that this particular user is a member of.
You need to change how you are using the session.
Instead of opening and closing the session yourself, do that in the IoC code.
Then you pass a session that is already opened for the right db.
All of my data contract objects in my service inherit from BaseMessage...
[DataContract(Name = "BaseMessage", Namespace = "http://www..."]
public class BaseMessage
{
[DataMember]
public Guid MessageId { get; set; }
}
I am familiar with using Message Inspectors to look at the actual SOAP payload that goes across the wire. However, what I want to do is to somehow hook into the message pipeline to do the following:
Look at an incoming message and read out of it the MessageId field ideally without searching the whole string message object for a string match - unless there is a fast way to do this.
Extract out of a message the MessageId with a view to creating a header inside the message containing the MessageId. Again I dont really want to search the whole message for the a string match.
I am familiar with using IClientMessageInspector and IDispatchMessageInspector to look at the messages, but I think at this point in the pipeline I dont have access to the actual object to access its fields.
Thanks
If you want to determine what members go in the body of the message versus its headers, you need a message contract.
I am trying to build a WCF DataService on top of a Code Only DbContext. However as soon as I add the first DbSet property to my DbContext I get "Request Error" when accessing the .svc.
All I need to get the error is to have this DbContext:
public class JukeboxContext : DbContext
{
public DbSet<Song> Songs { get; set; }
}
and then do a basic WCF DataService based on it, and the error happens when i run the service.
Any ideas on what I need to do?
Turnes out the exception means that it can't resolve which field is the primary key.
The easy way to go is to name it ID or ID - otherwise the DataServiceKey attribute will let you use composite keys
I am building a digital signage application and i need to allow my users to upload large images/videos. I have looked at the streaming mode to allow upload and download of the file, which seems to be the way to go. My problem is though that i need to figure out the proper approach to uploading. I need to put an entry into my database, then upload the file to a specific folder on the server (each customer has his own folder, whre the file needs to be placed). My problem is that it doesnt seem possible to send more information along with the file, than the stream to upload. All i need is some metadata, name of file and customer id. Anyone has a working example of this or point me in the right direction...
Sincerely
/Brian
Well, you're not saying what you've tried and how it failed, but here's a basic outline of how we're doing it:
[ServiceContract]
public interface IMyStreamingService
{
[OperationContract]
void Upload(FileUploadRequest request);
}
[MessageContract]
public class FileUploadRequest
{
[MessageHeader(MustUnderstand = true)]
public string Path;
[MessageBodyMember(Order = 1)]
public Stream FileData;
public FileUploadRequest(string path, Stream fileData)
{
this.Path = path;
this.FileData = fileData;
}
}
I have answered similar question few days ago. You have to declare operation which accepts and returns message contracts. You have to create message contracts. For streaming contract can contain only single body member which is of type Stream. Other contract members must to be declared as headers. Linked question contains full example for downloading. You just need to do the same for uploading.