Entity not updating in database using Entity Framework 6 - c#

I am creating an API for my Xamarin Android application and I have created this method to update password in the database:
[HttpPut]
[ActionName("updatepassword")]
public HttpResponseMessage updatepassword(string password,string email)
{
user_table user = dbe.user_table
.Where(x => x.email_address == email)
.FirstOrDefault();
user.password_hash = password.GetHashCode();
var response = dbe.SaveChanges();
string finalresponse = "password updated successfully" + response;
return Request.CreateResponse(HttpStatusCode.OK, finalresponse );
}
But when I test it using postman it shows that 0 entities have been affected.
I also tried using
dbe.user_table.AddorUpdate()
but it doesn't work either, please help me.
This is my postman query
http://192.168.10.9:8044/api/account/updatepassword/?password=asad1234&email=asadregards#gmail.com
I have published my API on IIS Server that is why I am using IP Address instead of localhost.

Change your code to this:
var user = dbe.user_table
.Where(x => x.email_address == email)
.FirstOrDefault();
var response=0;
if (user!=null)
{
user.password_hash = password.GetHashCode();
dbe.Entry(user).State = EntityState.Modified;
// Or you can try
//dbe.Entry(user).Property(i => i.password_hash).IsModified = true;
response = dbe.SaveChanges();
}
........
........
And maybe it's a good idea to change you API header too:
[Route("updatepassword/{password}/{email}")]
public IHttpActionResult updatepassword(string password,string email)
{
.........
.......
return response>0 ? Ok():BadRequest();
}

Related

Converting a C# post request snippet in to PHP

I have the snippet in C# and was looking for some advice converting it to PHP.
Basically, what is happening here, I am building somewhat of a middleware site.
A user submits a form named "Basket" and creates a POST request with XML body to this file, which will parse it, create a new URL with parameters which will afterwards be sent to Shopify cart.
Any help is appreciated.
public class DefaultController : ApiController
{
public IHttpActionResult Post()
{
var query = "";
var domain = "https://shop.shopify.io/cart";
try
{
var content = Request.Content.ReadAsFormDataAsync().Result;
var document = XDocument.Parse(content["basket"]);
if (document.Root != null)
{
var products = document.Root.Elements().Select(x => x.Element("productid").Value + ":" + x.Element("amount").Value);
query = string.Join(",", products);
}
}
catch
{ }
if (string.IsNullOrEmpty(query))
return Redirect(domain);
return Redirect($"{domain}?query={query}");
}
}
```

C#: Using Odata with Array Input in API

How do I get Odata working with a List variable?
The following API is not working and giving error.
HttpGet
Error: {"type":"https://tools.ietf.org/html/rfc7231#section-6.5.13","title":"Unsupported Media Type","status":415,"traceId":"00-b0b48a41f445ac4bbcebba902f8cca95-a714db4f4fd0c146-00"}
All my other APIs work,
"http://localhost:4547/api/properties/GetIdentifierPaged"
Controller:
[HttpGet[("[Action]")]
public ActionResult GetIdentifierPaged(List<string> propertyListRequest, ODataQueryOptions<PropertyDto> queryOptions)
{
propertyListRequest.Add("1110200100"); // fake data
var model = _propertyService.GetByPropertyIdentifierPaged(propertyListRequest).ToODataPageResult(queryOptions);
return Ok(model);
}
Service:
public IQueryable<PropertyDto> GetByPropertyIdentifierPaged(List<string> identifiers)
{
var identifiersEnumerable = identifiers.AsEnumerable();
var properties = _dataContext.Property
.Include(x => x.PropertyStatus)
Where(x => identifiersEnumerable.Contains(x.PropertyIdentifier))
return properties;
}
Page Result:
public static PageResult<T> ToODataPageResult<T>(this IQueryable<T> query, ODataQueryOptions<T> queryOptions)
{
var settings = new ODataQuerySettings();
settings.EnsureStableOrdering = false;
var countQuery = (IQueryable<T>)queryOptions.ApplyTo(query, settings, AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.Select | AllowedQueryOptions.OrderBy);
long count = countQuery.Count();
var results = (IQueryable<T>)queryOptions.ApplyTo(query, settings, AllowedQueryOptions.None);
return new PageResult<T>(results, null, count);
}
This problem indicates that there is a problem with your request, but even if you came to respond, there are errors you will receive. You cannot give a value that session is open in response
return new PageResult<T>(**results.ToList()**, null, count);

Razor Engine: URL generation in template of & generates &

I have an ASP.NET Core application which use Identity for user management.
I have a MailProvider which prepares an email to send via smtp for account activation purposes:
// ...
var activationMailViewModel = new ActivationMailViewModel()
{
LastName = user.LastName,
FirstName= user.FirstName,
UserName = userName,
Email = user.Email,
CompanyName = companyName,
Url = url.Action("ConfirmEmail", "Account", new { Area = "", code = token, userId = user.Id }, request.Scheme)
};
// ...
var result = Engine.Razor.RunCompile(new LoadedTemplateSource($"Activation", path), "SendUserAccountCreation" + Guid.NewGuid(), null, activationMailViewModel);
// ...
var mailMessage = new MailMessage(
new MailAddress("kyc#vente-privee.com", "KYC-vente-privee.com"),
new MailAddress(user.Email, userName))
{
Subject = GetGlobalString("ActivationMail_Subject", cultureCode),
BodyEncoding = System.Text.Encoding.UTF8,
SubjectEncoding = System.Text.Encoding.UTF8
};
<p>ACTIVATE MY ACCOUNT</p>
However it seems that the link generated can be interpreted in two different ways due to the transcription of the character & into & in the query string of the url.
http://base.url.net/Account/ConfirmEmail?code=CfDJ8PtYvJr8Ve1GnxXJykedIzKTQDg%2FTXBwV6NmIYMy8Gi7yUbqZagGbZRacKSFrE717h%2FGjmm6l8QA3knPPgxyNnM1vxe3wb6KnFsGtZUOMTas7QhX1MW5dE4cU5sorA99Dz03zV8ldVMOMP5BGfUrts2nNQqbs8dNLPNgupdkNzaWa4q6fM5u9E99CzRcFjAn7nnd57Ht3IIREAqz6lqufFYo469%2BN2VJxmNJJ1p6OAvO6dMJ9M%2Fzdz3xkpBajJbxRw%3D%3D**&**userId=21e4673c-f121-417f-9837-7f5b234f6f01
http://base.url.net/Account/ConfirmEmail?code=CfDJ8PtYvJr8Ve1GnxXJykedIzKTQDg%2FTXBwV6NmIYMy8Gi7yUbqZagGbZRacKSFrE717h%2FGjmm6l8QA3knPPgxyNnM1vxe3wb6KnFsGtZUOMTas7QhX1MW5dE4cU5sorA99Dz03zV8ldVMOMP5BGfUrts2nNQqbs8dNLPNgupdkNzaWa4q6fM5u9E99CzRcFjAn7nnd57Ht3IIREAqz6lqufFYo469%2BN2VJxmNJJ1p6OAvO6dMJ9M%2Fzdz3xkpBajJbxRw%3D%3D**&**userId=21e4673c-f121-417f-9837-7f5b234f6f01
Which can be problematic for the my AccountController:
[Authorize]
public class AccountController : BaseController
{
// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string code, string userId)
{
if (code == null || userId == null)
{
return View("Error");
}
// Rest of the code... not relevant to the question
}
If the browser / mail client interprets & as & then the userId will be set to null and the account / email cannot be confirmed.
For example:
On ProtonMail: the link on which I can click leads to an address which use & in the query string, which is just fine.
On Gmail: & and hence the link does not confirm the email.
However in both email providers, the plain text shows that the url has been generated with the Razor engine is: &.
What is the best strategy so that my users do not end up with a link that does not work.
Seems the issue was about the raw formatting which was not applied to the email.
The answer given here on SO:
When doing e-mails, I use the RazorEngineService in RazorEngine.Templating, e.g. in my case, it looks like this:
using RazorEngine.Templating;
RazorEngineService.Create().RunCompile(html, ...)
Assuming you are using the same assembly, #Html.Raw does NOT exist with this usage. I > was finally able to get raw HTML output by doing this in my e-mails:
#using RazorEngine.Text
#(new RawString(Model.Variable))

Error "405 Method Not Allow" When Calling Put method in Postman with body parameter

I was trying to call the Put method through Postman and always getting error: "405 Method Not Allow" and "Message": "The requested resource does not support http method 'PUT'."
I'm using DocumentDB and C#. Here is my code:
[Route("multilanguage/Resources/{id}/{Language}")]
[HttpPut]
public async Task<IHttpActionResult> UpdateResource(string Id, string Language, string text)
{
client = new DocumentClient(new Uri(EndPoint), AuthKey);
var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);
var query = new SqlQuerySpec("SELECT * FROM MultiLanguage as m where m.id = #pmId",
new SqlParameterCollection(new SqlParameter[] { new SqlParameter { Name = "#pmId", Value = Id } }));
Document doc = client.CreateDocumentQuery<Document>(
collectionLink, query).AsEnumerable().FirstOrDefault();
List<Models.Translations> d = doc.GetPropertyValue<List<Models.Translations>>("Translations");
Models.Translations temp = d.Find(p => p.Language == Language);
temp.Content = text;
temp.LastModified = DateTimeOffset.Now;
temp.ModifiedBy = "admin";
doc.SetPropertyValue("Translations", d);
Document updated = await client.ReplaceDocumentAsync(doc);
return Ok();
}
When I call the Put method throught Postman, I call "http://localhost:XXXX/multilanguage/resources/2/En". "2" and "En" are the first two parameters in my code. And I also specify the "text" parameter value in the Postman request Body with x-www-form-urlencoded type: key = text, value = Test! This put method suppose to update the temp.Content value to "Test!". However, it always failed with the error I mentioned above.
Did I miss anything here?
The 405 error when performing a PUT request to web api is a well known topic. You can find many solutions in this or this SO question.
And for the design of you controller:
PUT are designed to have a body, just like POST and in your case
you should send all parameters in the body instead.
You should create a class which contains the objects you want to send to the server:
public class resourceClass
{
public string Id { get; set; }
public string Language { get; set; }
public string text { get; set; }
}
Then specify the route without the attribute routing and get the object from the request body
[Route("multilanguage/Resources/PutResource")]
[HttpPut]
public async Task<IHttpActionResult> UpdateResource([FromBody] resourceClass obj)
{
client = new DocumentClient(new Uri(EndPoint), AuthKey);
var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);
var query = new SqlQuerySpec("SELECT * FROM MultiLanguage as m where m.id = #pmId",
new SqlParameterCollection(new SqlParameter[] { new SqlParameter { Name = "#pmId", Value = Id } }));
Document doc = client.CreateDocumentQuery<Document>(
collectionLink, query).AsEnumerable().FirstOrDefault();
List<Models.Translations> d = doc.GetPropertyValue<List<Models.Translations>>("Translations");
Models.Translations temp = d.Find(p => p.Language == Language);
temp.Content = text;
temp.LastModified = DateTimeOffset.Now;
temp.ModifiedBy = "admin";
doc.SetPropertyValue("Translations", d);
Document updated = await client.ReplaceDocumentAsync(doc);
return Ok();
}
From the client you could add an object to the PUT request of Content-Type application/json like this
var data = {
Id: clientId,
Language: clientLanguage,
text: clientText
};
Don't forget to stringify the json when adding it to the http request
data: JSON.stringify(data),
The PUT controller will then be reached at "http://localhost:XXXX/multilanguage/resources/putresource".
Check the URL for which you are posting the data, in my case the URL was incorrect because of which I got these errors, also verify that in Body you should select raw and change the Text to JSON if you are passing a JSON as a data.

Braintree test Request.Params always empty

I am implementing webhook test code and I am running into a problem.
After I POST a sample notification to my webhook listener the Params are not in the request:
Request.Params["bt_signature"]
Request.Params["bt_payload"]
So the listener fails.
Below is both my Post Webhook code and Listener code; I'm not sure if I'm using gateway.WebhookTesting.SampleNotification correctly.
POST Test Webhook
private async Task PostTestNotification()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:50709/");
var gateway = config.GetGateway();
// Create sample notification
Dictionary<String, String> sampleNotification = gateway.WebhookTesting.SampleNotification(
WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY, "sub_id_1234"
);
// Convert sample notification to JSON
string payloadJson = JsonConvert.SerializeObject(sampleNotification);
// Create StringContent of json sample notificaiton
var data = new StringContent(payloadJson);
// data looks like this when debugging { "bt_payload":"PG5vdGlmaWNhdGlvbj48dGltZXN0YW1wIHR5cGU9ImRhdGV0aW1lIj4yMDE2LTA1LTI3IDEzOjM2OjEwWjwvdGltZXN0YW1wPjxraW5kPnN1YnNjcmlwdGlvbl9jaGFyZ2VkX3N1Y2Nlc3NmdWxseTwva2luZD48c3ViamVjdD48c3Vic2NyaXB0aW9uPjxpZD5zdWJfaWRfMTIzNDwvaWQ+PHRyYW5zYWN0aW9ucz48dHJhbnNhY3Rpb24+PGlkPnN1Yl9pZF8xMjM0PC9pZD48YW1vdW50PjQ5Ljk5PC9hbW91bnQ+PHN0YXR1cz5zdWJtaXR0ZWRfZm9yX3NldHRsZW1lbnQ8L3N0YXR1cz48ZGlzYnVyc2VtZW50LWRldGFpbHM+PGRpc2J1cnNlbWVudC1kYXRlIHR5cGU9ImRhdGUiPjIwMTMtMDctMDk8L2Rpc2J1cnNlbWVudC1kYXRlPjwvZGlzYnVyc2VtZW50LWRldGFpbHM+PGJpbGxpbmc+PC9iaWxsaW5nPjxjcmVkaXQtY2FyZD48L2NyZWRpdC1jYXJkPjxjdXN0b21lcj48L2N1c3RvbWVyPjxkZXNjcmlwdG9yPjwvZGVzY3JpcHRvcj48c2hpcHBpbmc+PC9zaGlwcGluZz48c3Vic2NyaXB0aW9uPjwvc3Vic2NyaXB0aW9uPjwvdHJhbnNhY3Rpb24+PC90cmFuc2FjdGlvbnM+PGFkZF9vbnMgdHlwZT0iYXJyYXkiPjwvYWRkX29ucz48ZGlzY291bnRzIHR5cGU9ImFycmF5Ij48L2Rpc2NvdW50cz48L3N1YnNjcmlwdGlvbj48L3N1YmplY3Q+PC9ub3RpZmljYXRpb24+\n","bt_signature":"69r68j6hnzjpnq4j|508a7b4b3bbbe15c241c742331acfc5bacf37c54"}
// POST
HttpResponseMessage response = await client.PostAsync("webhooks/accept", data);
// RESPONSE
if (response.IsSuccessStatusCode == true)
{
// SUCCESS CONTENT
string resultJSON = await response.Content.ReadAsStringAsync();
}
else
{
// FAIL CONTENT
dynamic problem = await response.Content.ReadAsStringAsync();
}
}
}
catch (Exception ex)
{
//
Console.WriteLine("Exception: " + ex.Message);
}
}
Webhook LISTENER
// webhooks/accept endpoint
public async Task<ActionResult> accept()
{
try
{
var gateway = config.GetGateway();
if (Request.HttpMethod == "POST")
{
var bt_signature = Request.Params["bt_signature"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
var bt_payload = Request.Params["bt_payload"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
Request.Params["bt_signature"],
Request.Params["bt_payload"]
); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< EXCEPTION WHEN HIT - Value cannot be null, Parameter name: Input >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// ACTION Webhook
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
IsActive = false;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CANCELED " + webhookNotification.Subscription.Id );
}
else if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY)
{
IsActive = true;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CHARGED_SUCCESSFULLY " + webhookNotification.Subscription.Id);
}
// code ommitted for brevity, similar to above checking all 'kind' values
}
}
}
Why are the Braintree Request Params empty?
The problem was in the Webhook endpoint, the Braintree sample code is incorrect, it implies using MVC but developers need to use the Web Api for this, and the sample code will not work.
To get this working I left the Sample Notification POST above unchanged and created a new Webhook listener :
First create a class to receive the two braintree strings from the POST:
public class bt
{
public string bt_payload { get; set; }
public string bt_signature { get; set; }
}
And now create an empty Web Api 2 Controller:
[HttpPost]
[Route("api/webhooks/accept")]
public async Task<IHttpActionResult> accept(bt bt_lot)
{
var gateway = config.GetGateway();
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
bt_lot.bt_signature,
bt_lot.bt_payload
);
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
// take your action here...
}
Im posting all my experiences with Braintree here on SO as there isn't a great deal of help here and I hope it helps others.
I have to say the Braintree Help staff are excellent and always answer questions with very detailed answers that 95% of the time resolved any issues I had, but this issue had me scratching my head as their example didn't work and the help staff assumed like me that the code should work.

Categories