How to detect which user clicked the link MVC3 membership - database

When user clicks the link this method takes the user id and other data and writes it to the database. I can't seem to find a way to track what is the user id since the id is automatically generated.
I am using membership base separately from my base. In order to find userID I was trying to compare UserName strings. I get this error: "An unhandled exception was generated during the execution of the current web request." Also "Cannot create an abstract class."
Is there a better way to compare two strings form the two databases? Or is there a better way? This is my first time using lambda expressions.
I tried using Single() and First() instead of Where(), but I still get the same error.
[HttpPost]
public ActionResult AddToList(Review review, int id, HttpContextBase context)
{
try
{
if (ModelState.IsValid)
{
//User user = new User();
//user.UserID = db.Users.Where(c => c.UserName == context.User.Identity.Name);
User user = new User();
Movie movie = db.Movies.Find(id);
review.MovieID = movie.MovieID;
string username = context.User.Identity.Name;
user = (User)db.Users.Where(p => p.UserName.Equals(username));
review.UserID = user.UserID;
db.Reviews.Add(review);
db.SaveChanges();
return RedirectToAction("Index");
};
}
catch (DataException)
{
//Log the error (add a variable name after DataException)
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(review);
}

you're problem is likely this line:
user = (User)db.Users.Where(p => p.UserName.Equals(username));
the Where() extension method returns an IEnumerable, not a single instance, so your implicit cast will fail every time. what you're looking for is either First() or FirstOrDefault(). First() will throw an exception if there is no match though, while FirstOrDefault()will return a null if no match is found. the line should be :
user = db.Users.First(p => p.UserName.Equals(username));
you probably have bigger problems than that, but this is the cause of your current error.
EDIT
upon further looking at your code, you're asking for a HttpContextBase in your action result call. you never use it, and it's probably the cause of the Cannot create an abstract class exception. remove that parameter and see if you get any different results.

Related

System.QueryException: Record Currently Unavailable

This exception usually happens when a batch is being run or alerts are coming into our Salesforce instance too quickly. When inserting a case, we try to lock down the contact and account associated with the case before inserting the case to prevent the 'UNABLE_TO_LOCK_ROW' exception from happening.
Here is the exact exception:
'System.QueryException: Record Currently Unavailable: The record you are attempting to edit, or one of its related records, is currently being modified by another user. Please try again.'
Class.Utility.DoCaseInsertion: line 98, column 1
I've done a lot of research on the 'UNABLE_TO_LOCK_ROW' exception and 'Record Currently Unavailable' exception and I can't seem to find a great solution to this issue.
What I've tried to accomplish is a loop to attempt the insert 10 times, but I'm still getting the 'Record Currently Unavailable' exception. Does anyone else have a suggestion for this?
Below is the code:
Public static void DoCaseInsertion(case myCase) {
try
{
insert myCase;
}
catch (System.DmlException ex)
{
boolean repeat = true;
integer cnt = 0;
while (repeat && cnt < 10)
{
try
{
repeat = false;
List<Contact> contactList = [select id from Contact where id =: myCase.ContactId for update]; // Added for related contact to overcome the 'UNABLE_TO_LOCK_ROW issues'
List<Account> accountList = [select id from Account where id =: myCase.AccountId for update]; // Added for related account to overcome the 'UNABLE_TO_LOCK_ROW issues'
insert myCase;
}
catch (System.DmlException e)
{
repeat = true;
cnt++;
}
}
}
}
This basically happens when there is a conflicting modification being done by other user/process on a particular record that you are trying to access. Mostly it will happen when anykind of batch process is running in the background and locked the particular record you are trying to access(in your case Account). To get rid of this problem, you would need to check if there are any scheduled apex classes running in the background on Accounts/Cases and see if there is anything you can do to optimize the code to avoid conflicting behavior.

Does CRM context allow for structuring code in a non-nested way?

I'm building a Silverlight Web Resource which is intended to integrate into a form, and it needs to know all of the following information:
id of the current user
id of teams current user belongs to
id of current user's security roles
I'm working in an early-bound kind of way, added a Service Reference to the OData endpoint (http://server/org/XRMservices/2011/OrganizationData.svc) which in turn provides me with the context (let's name it cmtestcontext, which is its actual name in code).
I access data through this class (I didn't create it, I just googled it out of the net some time ago: this is a stripped-down, keep-it-short version)
public class QueryInterface
{
//NOTE: ServiceReference1 is the name of the OData service reference
//Add Service Reference -> point to CRM OData url
public ServiceReference1.cmtextcontext CrmContext;
public QueryInterface()
{
var crmServerUrl = (string)GetContext().Invoke("getServerUrl");
if (crmServerUrl.EndsWith("/")) crmServerUrl = crmServerUrl.Substring(0, crmServerUrl.Length - 1);
Uri ODataUri = new Uri(crmServerUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
CrmContext = new cmtestContext(ODataUri) { IgnoreMissingProperties = true };
}
}
The class allows me to sort of fetch in one line, as follows (actual code snippet enveloped in a dummy method to make it copy-pastable):
void RetrieveAllInformationFromCRM()
{
QueryInterface qi = new QueryInterface();
List<Guid> allData = new List<Guid>();
//NOTE: STEP 1 - USER ID
//NOTE: Since this is a web resource, I can cheat and use Xrm.Page.context.getUserId()
//NOTE: Remove the extra '{}' from the result for it to be parsed!
allData.Add(new Guid(qi.GetContext().Invoke("getUserId").ToString().Substring(1,36)));
//NOTE: STEP 2a - TEAM MEMBERSHIP FOR USER
//NOTE: TeamMembership entity links users to teams in a N:N relationship
qi.crmContext.TeamMembershipSet.BeginExecute(new AsyncCallback((result) =>
{
var teamMemberships = qi.crmContext.TeamMembershipSet.EndExecute(result)
.Where(tm => tm.TeamId.HasValue && (tm.SystemUserId ?? Guid.Empty) == userId)
.Select(tm => tm.TeamId.Value);
//NOTE: STEP 2b - TEAMS RELATED TO TEAMMEMBERSHIPS
qi.crmContext.TeamSet.BeginExecute(new AsyncCallback((result2) =>
{
var teamDetails = qi.crmContext.TeamSet.EndExecute(result2)
.Where(t => teamMemberships.Contains(t.TeamId));
foreach (var team in teamDetails)
allData.Add(team.TeamId);
//NOTE: FINAL STEP - allData is filled and ready to be used.
}), null);
}), null);
}
In the code above, my FINAL STEP picks up allData and processes it, and the flow goes on. My concern is, if/when I'll need to modify this "reader" method I'll have to cut and paste the "final" code around to ensure it's placed after all the reads. I'd like it way better if I could just make the reads follow one another, so I could do this:
void MyReaderMethod()
{
ReadEverything();
ProcessData();
}
Basically, can you just wait for a request to finish ? Hanging UI is a non-issue, I'd just wrap the code in a BackgroundWorker along with a "Please Wait" splash.
The nicest (IMO) is to convert the Async method calls (a requirement of Silverlight) into Task based calls.
With tasks you can easily seperate the query from the result action.
Then using the Async BCL's (via nuget) you can use async/await (if you are not using VS2012, then Tasks are still nicer to work with, you will just have to use continuations)
This example is for late bound, but you can modify it for your needs
public Task<OrganizationResponse> ExecuteAsync(OrganizationRequest request)
{
return Task.Factory.FromAsync<OrganizationResponse>(
(callback, state) => Begin(() => service.BeginExecute(request, callback, state)),
service.EndExecute,
null);
}
Then you can use it like
async void MyReaderMethod()
{
//TODO:wrap in try/catch
var result = await ExecuteAsync( ... );
ProcessData(result);
}
Or for VS 2010
void MyReaderMethod()
{
ExecuteAsync( ... ).ContinueWith(task =>{
//TODO: Error handling
ProcessData(task.Result);
});
}

How to know a operations of Google AppEngine datastore are complete

I'm execute method Datastore.delete(key) form my GWT web application, AsyncCallback had call onSuccess() method .Them i refresh http://localhost:8888/_ah/admin immediately , the Entity i intent to delete still exist. Smilar to, I refresh my GWT web application immediately the item i intent to delete still show on web page.Note the the onSuccess() had been call.
So, how can i know when the Entity already deleted ?
public void deleteALocation(int removedIndex,String symbol ){
if(Window.confirm("Sure ?")){
System.out.println("XXXXXX " +symbol);
loCalservice.deletoALocation(symbol, callback_delete_location);
}
}
public AsyncCallback<String> callback_delete_location = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
Window.alert(caught.getMessage());
}
public void onSuccess(String result) {
// TODO Auto-generated method stub
int removedIndex = ArryList_Location.indexOf(result);
ArryList_Location.remove(removedIndex);
LocationTable.removeRow(removedIndex + 1);
//Window.alert(result+"!!!");
}
};
SERver :
public String deletoALocation(String name) {
// TODO Auto-generated method stub
Transaction tx = Datastore.beginTransaction();
Key key = Datastore.createKey(Location.class,name);
Datastore.delete(tx,key);
tx.commit();
return name;
}
Sorry i'm not good at english :-)
According to the docs
Returns the Key object (if one model instance is given) or a list of Key objects (if a list of instances is given) that correspond with the stored model instances.
If you need an example of a working delete function, this might help. Line 108
class DeletePost(BaseHandler):
def get(self, post_id):
iden = int(post_id)
post = db.get(db.Key.from_path('Posts', iden))
db.delete(post)
return webapp2.redirect('/')
How do you check the existence of the entity? Via a query?
Queries on HRD are eventually consistent, meaning that if you add/delete/change an entity then immediately query for it you might not see the changes. The reason for this is that when you write (or delete) an entity, GAE asynchronously updates the index and entity in several phases. Since this takes some time it might happen that you don't see the changes immediately.
Linked article discusses ways to mitigate this limitation.

What should be returned from a database insert call?

I've got a datasource that has a bunch of insert functions. Each function takes a list of items that should be inserted into the DB. Each of these items can either be successfully inserted or not. If they are not successfully inserted, I would like to know the reason why.
Are there best practices around what should be returned from a datasource insert function?
Initial thoughts:
Boolean Success: Doesn't give me any reason on failure
Custom Response Object with Boolean Success and String Reason: Can't handle >1 insert response
List of Custom Response Objects: Seems to do what I want...
If it were me, I would setup my API to throw exceptions if a row was not inserted correctly.
Would look something like (demonstrative only):
$dbo = new Database();
foreach ($items as $item) {
try {
$dbo->insert($item);
Log::toLogfile('Row was successfully inserted');
} catch (Exception $e) {
// If an exception failed upon insert, I can log the message and move on
error_log($e->getMessage());
}
}
class Database
{
public function insert(array $item) {
// Here you can add any number of validators
if (empty($item)) {
throw new Exception(sprintf('Invalid $item array (%s)', serialize($item));
}
elseif (!array_key_exists('id', $item)) {
throw new Exception(sprintf('Invalid $item[id] (%s)', serialize(item));
}
// Making a call to php function which returns bool
// No problem, we test for return value and throw exception accordingly
if (!$this->dbo->insert($item)) {
throw new Exception(sprintf('Row was not inserted (%s)', serialize($item));
}
// If we made it this far, we have successfully inserted a row
// And code resumes back up after call to this function was made
}
Throwing exceptions is the best way to get a message back to the calling code, and it forces the calling code to handle the exception. By wrapping our $dbo->insert($item) call within a try / catch block, we can catch the exception, log it, and move onto the next item in the array.
I'd return something like the # of successful inserts, and either throw an exception when one fails or emit a warning, or at least log it to a file, depending on your needs.

Consuming WCF Data Services Service Operator (WebGet) async from Silverlight

Having a lot of problems trying to consume a simple service operator in a WCF Data Service from Silverlight. I've verified the following service operator is working by testing it in the browser:
[WebGet]
public IQueryable<SecurityRole> GetSecurityRolesForUser(string userName) {
string currentUsername = HttpContext.Current.User.Identity.Name;
// if username passed in, verify current user is admin and is getting someone else's permissions
if (!string.IsNullOrEmpty(userName)) {
if (!SecurityHelper.IsUserAdministrator(currentUsername))
throw new DataServiceException(401, Properties.Resources.RequiestDeniedInsufficientPermissions);
} else // else nothing passed in, so get the current user's permissions
userName = currentUsername;
return SecurityHelper.GetUserRoles(userName).AsQueryable<SecurityRole>();
}
However no matter how I try using different methods I've found in various online resources, I've been unable to consume the data. I've tried using the BeginExecute() method on boht the DataServiceContext and DataServiceQuery, but I keep getting errors or no data returned in the EndExecute method. I've got to be doing something simple wrong... here's my SL code:
private void InitUserSecurityRoles() {
MyEntities context = new MyEntities(new Uri("http://localhost:9999/MyService.svc"));
context.BeginExecute<SecurityRole>(new Uri("http://localhost:9999/MyService.svc/GetSecurityRolesForUser"), OnComplete, context);
DataServiceQuery<SecurityRole> query = context.CreateQuery<SecurityRole>("GetSecurityRolesForUser");
query.BeginExecute(OnComplete, query);
}
private void OnComplete(IAsyncResult result) {
OnDemandEntities context = result.AsyncState as OnDemandEntities;
var x = context.EndExecute<SecurityRole>(result);
}
Any tips? I'm at a loss right now on how to properly consume a custom service operator from Silverlight (or even sync using my unit test project) from a OData service. I've also verified via Fiddler that I'm passing along the correct authentication stuff as well, even going to far as explicitly set the credentials. Just to be safe, I even removed the logic from the service operator that does the security trimming.
Got it working thanks to #kaevans (http://blogs.msdn.com/b/kaevans):
private void InitUserSecurityRoles() {
DataServiceContext context = new DataServiceContext(new Uri("http://localhost:9999/MyService.svc"));
context.BeginExecute<SecurityRole>(new Uri("/GetSecurityRolesForUser", UriKind.Relative),
(result) => {
SmartDispatcher.BeginInvoke(
() => {
var roles = context.EndExecute<SecurityRole>(result);
UserSecurityRoles = new List<SecurityRole>();
foreach (var item in roles) {
UserSecurityRoles.Add(item);
}
});
}, null);
}
I had to create the SmartDispatcher because this is happening in a ViewModel. Otherwise I could have just used the static Dispatcher.BeginInvoke(). Couldn't get the roles variable to insert into my UserSecurityRoles (type List) directly for sone reason using various techniques, so I just dropped down to adding it manually (code isn't called often nor is it a collection exceeding more than 10 items max... most are <5).

Resources