This happens because Reputation.SetLike method internally uses SPContext.Current.Web object to get the list. And SPWeb object which you opened could be different from SPContext.Current.Web object.
Example:If you run your code on subsite then SPContext.Current.SPWeb object is subweb but SPWeb object which you open in your code is root site web.
I found a way to resolve it - you need to fake SPcontext.Current context to think that you are actually on root site.
To do this add class below to your project:
public class SPContextFaker:IDisposable
{
private SPContext _oldSPContext;
private HttpContext httpContext;
public SPContextFaker(HttpContext context, SPContext newSPContext)
{
_oldSPContext = (SPContext)context.Items["DefaultSPContext"];
context.Items["DefaultSPContext"] = newSPContext;
httpContext = context;
}
public void Dispose()
{
httpContext.Items["DefaultSPContext"] = _oldSPContext;
}
}
Then use it like this:
using(var site = new SPSite(SPContext.Current.Site.Url))
using(var web = site.OpenWeb())
using(new SPContextFaker(HttpContext.Current, SPContext.GetContext(web)))
{
SPList posts = web.Lists["Posts"];
string guid = posts.ID.ToString();
Reputation.SetLike(guid, 1, true);
}
You may ask how i came up with this code. The answer is simple - i've investigated Microsoft.SharePoint.dll using reflection and found how SPContext.Current property works.
I want to mention that above code will work only if you have HttpContext.Current != null which is true for web pages (but not true for example for event receivers and console applications).