Creating a new entry in Azure mobile table - xamarin

Good day
I am currently facing a weird problem with my insert command on my client side I think. I can create new entries in my other models(Tables) easily but in my person model I keep getting a bad request message each time I click create account.
Backend Model:
public class Person : EntityData
{
[StringLength(20)]
public string Name { get; set; }
[StringLength(20)]
public string Surname { get; set; }
[StringLength(150)]
public string Email { get; set; }
[StringLength(15)]
public string Mobile { get; set; }
[StringLength(15)]
public string Work { get; set; }
[StringLength(14)]
public string Password { get; set; }
[StringLength(80)]
public string Company { get; set; }
public virtual City City { get; set; }
}
Client Side Controller:
namespace azuremobile
{
public partial class PersonManager
{
static PersonManager defaultInstance = new PersonManager();
MobileServiceClient client;//Initialize Mobile SDK
IMobileServiceTable<Person> accountTable;
private PersonManager()
{
var handler = new AuthHandler();
//Create our client and pass in Authentication handler
this.client = new MobileServiceClient(
Constants.ApplicationURL, handler);
this.accountTable = client.GetTable<Person>();
}
public static PersonManager DefaultManager
{
get
{
return defaultInstance;
}
private set
{
defaultInstance = value;
}
}
public MobileServiceClient CurrentClient//Provides basic access to azure mobile services
{
get { return client; }
}
public bool IsOfflineEnabled
{
get { return accountTable is Microsoft.WindowsAzure.MobileServices.Sync.IMobileServiceSyncTable<Person>; }
}
public async Task<Person> GetTodoItemsAsync(Expression<Func<Person, bool>> linq)
//public async Task<List<Person>> GetTodoItemsAsync(bool syncItems = false)
{
try
{
// return new List<Person>(await accountTable.ReadAsync());
//List<Person> newUser = await accountTable.Where(linq).Take(1).ToListAsync();
IEnumerable<Person> items = await accountTable
.Where(c => c.Name != null)
.Take(1)
.ToListAsync();
//return newUser.First();
// return await accountTable;
// .Where(c => c.Name != null)
// .Take(1)
// .ToListAsync();
}
catch (MobileServiceInvalidOperationException msioe)
{
Debug.WriteLine(#"Invalid sync operation: {0}", msioe.Message);
}
catch (Exception e)
{
Debug.WriteLine(#"Sync error: {0}", e.Message);
}
return null;
}
public async Task SaveTaskAsync(Person item)
{
// if (item.Id != null)
// await accountTable.InsertAsync(item);
// else
await accountTable.UpdateAsync(item);
}
public async Task CreateTaskAsync(Person item)
{
try
{
await accountTable.InsertAsync(item);
}
catch (MobileServiceInvalidOperationException msioe)
{
Debug.WriteLine(#"INVALID {0}", msioe.Message);
}
catch (Exception e)
{
Debug.WriteLine(#"ERROR {0}", e.Message);
}
}
}
}
Client Side Signup Screen:
public partial class SignupScreen : ContentPage
{
PersonManager manager;
public SignupScreen()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
manager = PersonManager.DefaultManager;
LoginClicked.Clicked += async (object sender, EventArgs e) =>
{
var main = new LoginScreen();
Application.Current.MainPage = main;
Navigation.RemovePage(this);
};
}
async Task CreatedNewUser(Person items)
{
try
{
await manager.CreateTaskAsync(items);
}
catch (MobileServiceInvalidOperationException e)
{
await DisplayAlert("Info", e.Message, "Ok");
}
}
public async void OnSignUp(object sender, EventArgs e)
{
string name = this.nameEntry.Text.Trim();
string surname = this.surnameEntry.Text.Trim();
string email = this.emailEntry.Text.Trim();
string company = this.companyEntry.Text.Trim();
string work = this.workEntry.Text.Trim();
string mobile = this.mobileEntry.Text.Trim();
string password = this.passwordEntry.Text.Trim();
if (string.IsNullOrEmpty(name))
{
await DisplayAlert("Info", "Please fill in your name.", "Ok");
this.nameEntry.PlaceholderColor = this.nameEntry.TextColor = Color.FromHex("#00FF00");
nameEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(surname))
{
await DisplayAlert("Info", "Please fill in your surname.", "Ok");
this.surnameEntry.PlaceholderColor = this.surnameEntry.TextColor = Color.FromHex("#00FF00");
surnameEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(email))
{
await DisplayAlert("Info", "Please fill in your email.", "Ok");
this.emailEntry.PlaceholderColor = this.emailEntry.TextColor = Color.FromHex("#00FF00");
emailEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(company))
{
await DisplayAlert("Info", "Please fill in your company name.", "Ok");
this.companyEntry.PlaceholderColor = this.companyEntry.TextColor = Color.FromHex("#00FF00");
companyEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(mobile))
{
await DisplayAlert("Info", "Please fill in your cellphone number.", "Ok");
this.mobileEntry.PlaceholderColor = this.mobileEntry.TextColor = Color.FromHex("#00FF00");
mobileEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(work))
{
await DisplayAlert("Info", "Please fill in your office number.", "Ok");
this.workEntry.PlaceholderColor = this.workEntry.TextColor = Color.FromHex("#00FF00");
workEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
if (string.IsNullOrEmpty(password))
{
await DisplayAlert("Info", "Please fill in your password.", "Ok");
this.passwordEntry.PlaceholderColor = this.passwordEntry.TextColor = Color.FromHex("#00FF00");
passwordEntry.Focus();
signUpButton.IsEnabled = true;
return;
}
try
{
activityIndicator.IsRunning = true;
validationLabel.IsVisible = true;
signUpButton.IsEnabled = false;
if (!string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(password))
{
var OnAdd = new Person
{
Name = name,
Surname = surname,
Email = email,
Mobile = mobile,
Work = work,
Company = company,
Password = password
};
await CreatedNewUser(OnAdd);
await Navigation.PushAsync(new LoginScreen());
}
else
{
await DisplayAlert("Warning", "Could not create user account.", "Ok");
}
}
catch (Exception)
{
await DisplayAlert("Warning", "Could not create user account, problem with internet connection or server.", "Ok");
activityIndicator.IsRunning = false;
validationLabel.IsVisible = false;
signUpButton.IsEnabled = true;
}
}
}
}

Related

how to add and delete favorites in asp.net core api

I develop a news application with ASP.net API. I want users to be able to add and deleted their favorites articles. I created a Favorites model like this:
public class Favorites{
public String userId {get; set;}
public UserEntity User {get; set;}
public int articleId {get; set; }
public virtual Article article {get; set;}
}
I initialized it with dotnet fluentapi:
modelBuilder.Entity<Favorites>().HasKey(a => new{ a.articleId, a.userId });
this is how the controller looks like :
public class FavoritesController : ControllerBase
{
private readonly DatabaseContext _context;
public FavoritesController(DatabaseContext context)
{
_context = context;
_context.Database.EnsureCreated();
}
// GET: api/Favorites
[HttpGet(Name = nameof(GetAllFavorites))]
public async Task<ActionResult<IEnumerable<FavoriteDTo>>> GetAllFavorites( [FromQuery] NewRoomQueryParameters queryParameter)
{
IQueryable<Favorites> favs = _context.Favorites;
if (!string.IsNullOrEmpty(queryParameter.sortBy))
{
if (typeof(Favorites).GetProperty(queryParameter.sortBy) != null)
{
favs = favs.OrderByCustom(queryParameter.sortBy, queryParameter.SortOrder);
}
}
if (!string.IsNullOrEmpty(queryParameter.userId))
{
favs = favs.Where(p => p.userId == queryParameter.userId);
}
return await favs.Include(a => a.Article)
.ThenInclude(a => a.Author)
.Include(a => a.Article)
.ThenInclude(a => a.Comments)
.Select(x => favoriteToDTo(x)).ToListAsync();
}
// GET: api/Favorites/5
[HttpGet("{id}")]
public async Task<ActionResult<FavoriteDTo>> GetFavorites(int id)
{
IQueryable<Favorites> favs = _context.Favorites;
var favorites = await favs.Include(x => x.Article).FirstOrDefaultAsync(x => x.articleId == id ) ;
if (favorites == null)
{
return NotFound();
}
return favoriteToDTo(favorites);
}
// POST: api/Favorites
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task<ActionResult<FavoriteDTo>> PostFavorites(FavoriteDTo favDTo)
{
var fav = new Favorites
{
articleId = favDTo.articleId,
userId = favDTo.userId
};
_context.Favorites.Add(fav);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (FavoritesExists(fav.articleId))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtAction(nameof(GetFavorites), new { id = fav.articleId }, fav);
}
// DELETE: api/Favorites/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteFavorites(int id)
{
var favorites = await _context.Favorites.FindAsync(id);
if (favorites == null)
{
return NotFound();
}
_context.Favorites.Remove(favorites);
await _context.SaveChangesAsync();
return NoContent();
}
private static FavoriteDTo favoriteToDTo(Favorites favorites) => new FavoriteDTo
{
articleId = favorites.articleId,
Article = favorites.Article,
User = favorites.User,
userId = favorites.userId
};
private bool FavoritesExists(int id)
{
return _context.Favorites.Any(e => e.articleId == id);
}
}
I can add Favorites just fine. But I cannot remove them. Can somebody help me out ? if it is not the good
way to implement this functionality , please I would like to learn how to do it the right way.
It depends on How you want to delete the favorite. If you want to delete the Article from Favorite for a user,
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteFavoritesForUser(int Articleid, string userId)
{
var favorites = await _context.Favorites.FindBy(x=>x.UserId ==userId && x=>x.ArticleId ==Articleid);
if (favorites == null)
{
return NotFound();
}
_context.Favorites.RemoveRange(favorites);
await _context.SaveChangesAsync();
return NoContent();
}
Replace
_context.Favorites.Remove(favorites);
with
_context.Favorites.RemoveRange(favorites);

Xamarin forms monkey chat

I am using monkey chat in my mobile application(Xamrin forms based). While sending a message on IOS, on a real device, I have to click the send button 2 times. First time when I click, it minimizes the keyboard and 2nd time, it sends the message. Please suggest.
How do I send a message on one click?
Here is my send message function
namespace Budocode.ViewModels
{
public class MainChatViewModel : BaseViewModel
{
public ObservableRangeCollection Messages { get; }
ITwilioMessenger twilioMessenger;
string outgoingText = string.Empty;
public string OutGoingText
{
get { return outgoingText; }
set { SetProperty(ref outgoingText, value); }
}
public ICommand SendCommand { get; set; }
public ICommand LocationCommand { get; set; }
public MainChatViewModel()
{
// Initialize with default values
twilioMessenger = DependencyService.Get<ITwilioMessenger>();
Messages = new ObservableRangeCollection<ChatMessage>();
SendCommand = new Command(() =>
{
var message = new ChatMessage
{
Text = OutGoingText,
IsIncoming = false,
ProfileId = "profile" + GlobalSettingsDataSource.Current.SelectedProfileImageId + ".png",
MessageDateTime = DateTime.Now,
FromUser = GlobalSettingsDataSource.Current.SelectedProfile
};
if (string.IsNullOrWhiteSpace(OutGoingText))
return;
Messages.Add(message);
twilioMessenger?.SendMessage(message.Text, message.ProfileId, GlobalSettingsDataSource.Current.SelectedProfile);
OutGoingText = string.Empty;
});
LocationCommand = new Command(async () =>
{
try
{
var local = await CrossGeolocator.Current.GetPositionAsync(TimeSpan.FromSeconds(15));
var map = $"https://maps.googleapis.com/maps/api/staticmap?center={local.Latitude.ToString(CultureInfo.InvariantCulture)},{local.Longitude.ToString(CultureInfo.InvariantCulture)}&zoom=17&size=400x400&maptype=street&markers=color:red%7Clabel:%7C{local.Latitude.ToString(CultureInfo.InvariantCulture)},{local.Longitude.ToString(CultureInfo.InvariantCulture)}&key=";
var message = new ChatMessage
{
Text = "I am here",
AttachementUrl = map,
ProfileId = "profile" + GlobalSettingsDataSource.Current.SelectedProfileImageId + ".png",
IsIncoming = false,
MessageDateTime = DateTime.Now
};
Messages.Add(message);
twilioMessenger?.SendMessage("attach:" + message.AttachementUrl, message.ProfileId, GlobalSettingsDataSource.Current.SelectedProfile);
}
catch (Exception ex)
{
}
});
if (twilioMessenger == null)
return;
twilioMessenger.MessageAdded = (message) =>
{
//if (message.ProfileId == "Icon.png")
Device.BeginInvokeOnMainThread(() =>
{
if (message.FromUser != GlobalSettingsDataSource.Current.SelectedProfile)
{
message.IsIncoming = true;
}
else
{
message.IsIncoming = false;
}
Messages.Add(message);
});
};
}
public async void InitializeMock(string channelName)
{
try
{
var id = CrossDeviceInfo.Current.Id;
var userId = PersistantData.Current.UserAccount.Properties["user_id"];
HttpResponseMessage appResponse = CommonUtility.GetApiContent(
String.Format(ClientConfiguration.TwilioServiceChatHistory, id, GlobalSettingsDataSource.Current.SelectedProfile, channelName));
if (appResponse.IsSuccessStatusCode)
{
var chatContent = await appResponse.Content.ReadAsStringAsync();
List<ChatMessage> chatMsgs = JsonConvert.DeserializeObject<List<ChatMessage>>(chatContent);
Messages.ReplaceRange(chatMsgs);
}
}
catch
{
// ignore if there are any issues with twilio
}
}
}
}

WebAPI:How to read message from HttpResponseMessage class at client side

below is a sample action which is returning HttpResponseMessage and if any error occur then this way web api action returning error message and status code to client side return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);.
[HttpGet, Route("GetAll")]
public HttpResponseMessage GetAllCustomers()
{
IEnumerable<Customer> customers = repository.GetAll();
if (customers == null)
{
var message = string.Format("No customers found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, customers);
}
}
when i am invoking action by http client then i am not getting message in ReasonPhrase property. just tell me what is the right way to read message at client side which is passing like this way return Request.CreateResponse(HttpStatusCode.OK, customers);
here is my client side code
private async void btnFind_Click(object sender, EventArgs e)
{
var fullAddress = baseAddress + "api/customer/GetByID/"+txtFind.Text;
Customer _Customer = null;
using (var client = new HttpClient())
{
using (var response = client.GetAsync(fullAddress).Result)
{
if (response.IsSuccessStatusCode)
{
var customerJsonString = await response.Content.ReadAsStringAsync();
_Customer = JsonConvert.DeserializeObject<Customer>(customerJsonString);
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
}
if (_Customer != null)
{
var _CustList = new List<Customer> { _Customer };
dgCustomers.DataSource = _CustList;
}
}
response.ReasonPhrase not holding the message which i am passing from action. so may be i am not doing things to read message. please tell me what to change in my code to read the message. thanks
i have the job this way.
private async void btnFind_Click(object sender, EventArgs e)
{
var fullAddress = baseAddress + "api/customer/GetByID/"+txtFind.Text;
Customer _Customer = null;
try
{
using (var client = new HttpClient())
{
using (var response = client.GetAsync(fullAddress).Result)
{
if (response.IsSuccessStatusCode)
{
var customerJsonString = await response.Content.ReadAsStringAsync();
_Customer = JsonConvert.DeserializeObject<Customer>(customerJsonString);
}
else
{
//Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
var ErrMsg = JsonConvert.DeserializeObject<dynamic>(response.Content.ReadAsStringAsync().Result);
MessageBox.Show(ErrMsg.Message);
}
}
}
if (_Customer != null)
{
var _CustList = new List<Customer> { _Customer };
dgCustomers.DataSource = _CustList;
}
}
catch (HttpRequestException ex)
{
// catch any exception here
}
}
read error message this way.
var ErrMsg = JsonConvert.DeserializeObject<dynamic>(response.Content.ReadAsStringAsync().Result);

WebAPI: PostAsync with query string does not work

see my sample web api action which take one string type parameter.
[RoutePrefix("api/customer")]
public class CustomerController : ApiController
{
[HttpPost, Route("DeleteCustomer")]
public HttpResponseMessage DeleteProduct(string customerID)
{
HttpResponseMessage response = null;
Customer customer = repository.Get(customerID);
if (customer == null)
{
var message = string.Format("No customer found by the ID {0}", customerID);
HttpError err = new HttpError(message);
response = Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, err);
response.ReasonPhrase = message;
}
else
{
if(repository.Remove(customerID))
{
response = Request.CreateResponse<Customer>(HttpStatusCode.Created, customer);
response.ReasonPhrase = "Customer successfully deleted";
}
else
{
var message = string.Format("Due to some error customer not removed");
HttpError err = new HttpError(message);
response = Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, err);
response.ReasonPhrase = message;
}
}
return response;
}
}
and calling like this below way with http client but not working and giving error Not found
private void btnDelete_Click(object sender, EventArgs e)
{
var uri = new Uri(ConfigurationManager.AppSettings["baseAddress"] + "/api/customer/DeleteCustomer");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("customerID", "CUS01")
});
try
{
using (var client = new HttpClient())
{
using (var response = client.PostAsync(uri, content).Result)
{
if (response.IsSuccessStatusCode)
{
MessageBox.Show(response.ReasonPhrase);
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(response.Content.ReadAsStringAsync().Result);
MessageBox.Show(dict["Message"]);
}
}
}
}
catch (HttpRequestException ex)
{
// catch any exception here
}
}
some one please see my code and tell me where i made the mistake in calling code ? thanks
[RoutePrefix("api/customer")]
public class CustomerController : ApiController
{
[HttpPost, Route("DeleteCustomer")]
public HttpResponseMessage DeleteProduct([FromBody]string customerID)
{
HttpResponseMessage response = null;
Customer customer = repository.Get(customerID);
if (customer == null)
{
var message = string.Format("No customer found by the ID {0}", customerID);
HttpError err = new HttpError(message);
response = Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, err);
response.ReasonPhrase = message;
}
else
{
if(repository.Remove(customerID))
{
response = Request.CreateResponse<Customer>(HttpStatusCode.Created, customer);
response.ReasonPhrase = "Customer successfully deleted";
}
else
{
var message = string.Format("Due to some error customer not removed");
HttpError err = new HttpError(message);
response = Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, err);
response.ReasonPhrase = message;
}
}
return response;
}
}
Could you add [FromBody] keyword in method parameter ?

how can I handle exceptions in MVC3?

I am working in MVC3 Application. I am struggle to handle exceptions in my controller.
Here My Account controller is,
public ActionResult Register(NewRegister model)
{
if (ModelState.IsValid)
{
if (!IsUserLoginExist(model.Email))
{
AccountServiceHelper.CreatePerson(model);
return RedirectToAction("RegistrationConfirmation", "Account");
}
else
{
ModelState.AddModelError("","Email Address already taken.");
}
}
return View(model);
}
After I validate IsUserLoginExist I am just calling the Helper Class i.e. AccountServiceHelper for consuming a web service method like CreatePerson.
My Helper class looks like this:
public static void CreatePerson(NewRegister model)
{
try
{
try
{
var FirstName = model.FristName;
var LastName = model.LastName;
var Email = model.Email;
var Role = model.Role;
var Password = model.Password;
.....
.....
service.CreatePerson(model);
service.close();
}
catch(Exception e)
{
}
}
catch { }
}
My problem is how can I handle Exception in helper class and return to the controller.
One possibility is to handle the exception at your controller:
public static void CreatePerson(NewRegister model)
{
var FirstName = model.FristName;
var LastName = model.LastName;
var Email = model.Email;
var Role = model.Role;
var Password = model.Password;
.....
.....
service.CreatePerson(model);
service.close();
}
and then:
public ActionResult Register(NewRegister model)
{
if (ModelState.IsValid)
{
try
{
if (!IsUserLoginExist(model.Email))
{
AccountServiceHelper.CreatePerson(model);
return RedirectToAction("RegistrationConfirmation", "Account");
}
else
{
ModelState.AddModelError("", "Email Address already taken.");
}
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.Message);
}
}
return View(model);
}
Like others have said, you throw it from your helper class using this method:
public static void CreatePerson(NewRegister model)
{
try
{
var FirstName = model.FristName;
var LastName = model.LastName;
var Email = model.Email;
var Role = model.Role;
var Password = model.Password;
.....
.....
service.CreatePerson(model);
service.close();
}
catch(Exception e)
{
// handle it here if you want to i.e. log
throw e; // bubble it to your controller
}
}
If an exception occurs in your helper class, and you don't specifically catch it in your helper class, it will bubble up to your controller anyway. So if you don't want to handle it in your helper class, there's no need to catch it as it will end up in your controller anyway.
throw it from your helper class

Resources