How to upload a profile picture and update it in identity asp.net core 3 - identity

I want to upload a profile picture in the identity user and update it in account management. if there is any post with good examples for asp.net core please give me links.

I did it myself with FileForm Method. First You Have to Add string property in User Class(https://learn.microsoft.com/en-us/aspnet/core/security/authentication/add-user-data?view=aspnetcore-3.0&tabs=visual-studio).
public string Avatar { get; set; }
and then, update the Manage/Index files by following the documentation. Now, How to create the file upload system? I did like the code below. but if i need to change something for security, please don't forget to help.
if (Input.Avatar != null)
{
string existfile = Path.Combine(hostingEnvironment.WebRootPath, "uploads", user.Avatar);
System.IO.File.Delete(existfile);
}
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads", "avatar");
var filePath = Path.Combine(uploads, fileName);
this.Image.CopyTo(new FileStream(filePath, FileMode.Create));
user.Avatar = fileName; // Set the file name
GetUniqueFileName Class after the PostAsync class:
private string GetUniqueName(string fileName)
{
fileName = Path.GetFileName(fileName);
return Path.GetFileNameWithoutExtension(fileName)
+ "_" + Guid.NewGuid().ToString().Substring(0, 4)
+ Path.GetExtension(fileName);
}
You also have to add the IWebHostEnvironment dependency injection and update the cshtml form with multipart/form-data enctype. Don't forget to follow the .net documentation rules also. Good Luck!

Related

ASP.NET Core Read in html file from www root and replace parameters

I am trying to create a printable page that says
Hi, [Member]
We have blah blah....[MemberLocation]
Thanks. Please contact [MemberPhone]
Replacing the [Member] tags with data from the model.
I figured the best way is to save an html on wwwroot.
So I saved the above in member.html on wwwroot/staticfiles/member.html
I am having a hard time reading this file into my code.
I was hoping to do something like
memberString = System.IO.File.ReadAllText("staticfiles/member.html").ToString();
Then do something like
var memberName = model.Name;
memberString = memberString.replace([Member], memberName)
Obviously this isn't working. I can't read the file that way.
I have tried creating a service that reads the file
public class ReturnHTML
{
private readonly IHostEnvironment _env;
public ReturnHTML(IHostEnvironment env)
{
_env = env;
}
public string ReturnHTMLPage()
{
var path = Path.Combine(_env.ContentRootPath, "StaticFiles/member.html");
var htmlString = System.IO.File.ReadAllText(path);
return htmlString.ToString();
}
}
Add this a singleton in my startup.cs
But I can't figure out how to inject this and get this string.
So my question is, what is the best way to create a printable page that I can supply values to?
There are third party stuff out there that create pdf and docs that you can template. But I am not interested in third party tools. Is there any native way of doing this?

Is it possible to get raw HTML from Razor/Blazor components?

I'd like to set up a "mailer/newsletter" using MailKit. My site stack is based off of Blazor web assembly and uses .Razor components.
I'm wondering if there is a way to consume a razor component I've written to output HTML into the MimeMessage object I'm using to generate my email body and what that architecture would look like / the best way to accomplish this?
Similar question (though not Blazor):
Can I use an ASP.Net MVC Razor view to generate an nicely formatted HTML Body as the input for an email sent from the server?
Late answer since I just saw this question: I wrote an alternative system called BlazorTemplater which uses .razor files instead of .cshtml since I had exactly this problem.
You can convert your templates to .razor format and then use BlazorTemplater to render to HTML:
var html = new ComponentRenderer<MyRazorClass>()
.Set(c => c.SomeParameter = someValue)
.Render();
It supports parameters, DI injection and nested components so you should find it useful! It's also much easier to set up and works in Razor Class Libraries too.
I am using Blazor with MailKit here: Google Email Viewer in Server Side Blazor
I use MarkupString to display the email content like this:
#using MimeKit
#using MessageReader
#strError
<div style="padding:2px; vertical-align:top">
<div><i>#MimeKitMessage.Date.ToString()</i></div>
<div><b>From:</b> #MimeKitMessage.From.ToString()</div>
<div><b>To:</b> #MimeKitMessage.To.ToString()</div>
<div><b>Subject:</b> #MimeKitMessage.Subject</div>
<br />
<div>#((MarkupString)#htmlEmail)</div>
</div>
#code {
[Parameter] public Message paramMessage { get; set; }
MimeMessage MimeKitMessage;
string strError = "";
string htmlEmail = "";
protected override void OnInitialized()
{
try
{
if (paramMessage != null)
{
string converted = paramMessage.Raw.Replace('-', '+');
converted = converted.Replace('_', '/');
byte[] decodedByte = Convert.FromBase64String(converted);
using (Stream stream = new MemoryStream(decodedByte))
{
// Convert to MimeKit from GMail
// Load a MimeMessage from a stream
MimeKitMessage = MimeMessage.Load(stream);
// Convert any embedded images
var visitor = new HtmlPreviewVisitor();
MimeKitMessage.Accept(visitor);
htmlEmail = visitor.HtmlBody;
//If the email has attachments we can get them here
//var attachments = visitor.Attachments;
}
}
}
catch (Exception ex)
{
strError = ex.Message;
}
}
}

Google Drive API - Granting Access to Files in a Folder to Service Account

I am using a service account to connect to the Google Drive of a G Suite. I understand that with the available access (scope: https://www.googleapis.com/auth/drive.file) I can only see the files that the service account has created and using the /auth/drive scope (which gives full visibility) requires special Google approval.
I need to be able to expand the service account's visibility to include files in at least 1 folder the user has not created. I can't get this through normal folder sharing as best I can tell.
Does anyone know how to do this?
Edit to include code (written in Apex, which is similar to Java). Still pretty rough, I haven't cleaned it up yet but:
private static String buildAuthBody(Google_Drive_Integration__mdt mdt) {
//Builds and encodes the JWT header
String bodyHeader = '{"alg":"RS256","typ":"JWT"}';
String encodedHeader = encode(bodyHeader);
//Builds and encodes the JWT Claim Set. See googleAuth body
googleAuth ga = new googleAuth(mdt);
String claimSetString = JSON.serialize(ga);
String encodedClaimSet = encode(claimSetString);
//Builds out necessary pieces for Crypt.sign(algorithmName, input, privateKey). Input = body
String signatureBody = encodedHeader + '.' + encodedClaimSet;
signatureBody = signatureBody.replaceAll('=','');
String encodedSignatureBody = EncodingUtil.urlEncode(signatureBody,'UTF-8');
Blob signatureBodyBlob = Blob.valueOf(encodedSignatureBody);
Blob key = EncodingUtil.base64Decode(mdt.Service_Account_Private_Key__c); //Must be decoded to pass into method w/o error
//Builds the signature
Blob signatureBlob = Crypto.sign('RSA-SHA256', signatureBodyBlob , key);
String encodedSignature = encodeBlob(signatureBlob);
//Sets grant type
String grantType = EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer', 'UTF-8');
//Sets body and debugs to rebuild body
System.debug('grant type: grant_type=' + grantType);
System.debug('&assertion=');
System.debug('encoded header: '+encodedHeader);
System.debug('encoded claim set: '+encodedClaimSet);
System.debug('encoded signature: '+encodedSignature);
//Build and return the body
String body = 'grant_type=' + grantType;
body += '&assertion=';
body += signatureBody;
body += '.' + encodedSignature;
return body;
}
class googleAuth {
public String iss; //'test-google-drive#sapient-flare-252622.iam.gserviceaccount.com';
public String scope = 'https://www.googleapis.com/auth/drive';
public String aud = 'https://www.googleapis.com/oauth2/v4/token';
public Long exp;
public Long iat;
googleAuth(Google_Drive_Integration__mdt mdt) {
DateTime dt = DateTime.now();
iat = dt.getTime() / 1000;
exp = iat + 3600;
iss = mdt.Service_Account_User_Email__c;
}
}
private static String encode(String str) {
Blob b = Blob.valueOf(str);
String ret = EncodingUtil.base64Encode(b);
ret = EncodingUtil.urlEncode(ret, 'UTF-8');
return ret;
}
private static String encodeBlob(Blob b) {
String ret = EncodingUtil.base64Encode(b);
ret = EncodingUtil.urlEncode(ret, 'UTF-8');
return ret;
}
I think you are misunderstanding things about service accounts and about scopes.
Scopes define the amount of access a user has granted to your application. In this case the user is the service account. Using scope: https://www.googleapis.com/auth/drive.file with a service account doesn't make much sense really as you the developer own the service account and there by own its drive account. so really just give it full access using scope: https://www.googleapis.com/auth/drive there is no real reason for you to limit it. If you had a normal application using Oauth2 you would only request the access you need to the users drive account.
I need to be able to expand the service account's visibility to include files in at least 1 folder the user has not created. I can't get this through normal folder sharing as best I can tell.
I am not sure i understand this. Assuming that when you say "user" you mean the service account. I am going to assume this folder is part of your gsuite system. In which case you simply need to have your Gsuite admin set up domain wide delegation to the service account and it will have access. This is a way of granting the service account permissions to access data on your gsuite account kind of like adding a new user to the system.

How to serialize an object in windows phone 7

How to convert an object to JSON data in windows phone. In web application I have used following code
JavaScriptSerializer serializer = new JavaScriptSerializer();
string stringData = serializer.Serialize(object);
I want to get the same output as that of the above code in windows phone 7.
JavaScriptSerializer is not supported on Windows Phone. An alternative is to use JSON.NET (you can add it via NuGet).
The code will then look like this:
string stringData = JsonConvert.SerializeObject(object);
firrst you need to download Newtonsoft.Json dll for parse web serevice
Just follow bellow step
Step1: Add Service References by right click on add References.
Step2: Now put your web service link on Service References and press go button, And also add Namespace of service Reference
Step3: Now add using Newtonsoft.Json.Linq; name space in your .cs file
Step4: Now add bellow code in your cs file
WhatsupServices.WhatsUpServiceSoapClient ws = new WhatsupServices.WhatsUpServiceSoapClient();
ws.ContactUsJSONCompleted += ws_ContactUsJSONCompleted;
ws.ContactUsJSONAsync(txtContactUsName.Text, txtContactUsPhone.Text, txtContactUsEmail.Text, txtContactUsComment.Text);
step6: now genrate your resopnce method
void ws_ContactUsJSONCompleted(object sender, dynamic e)
{
if (e.Error != null)
{
MessageBox.Show(LogIn.NetworkBusyMsg, LogIn.MsgHdr, MessageBoxButton.OK);
busyIndicator.IsRunning = false;
}
else
{
busyIndicator.IsRunning = false;
string Result = e.Result;
JObject obj = JObject.Parse(Result);
string ResultCode = (string)obj["ResultCode"];
string ResponceMessage = (string)obj["ResponseMessage"];
if (ResultCode == "1")
{
MessageBox.Show("Thank you for your message. We'll get back to you soon.", LogIn.MsgHdr, MessageBoxButton.OK);
NavigationService.GoBack();
}
else
{
}
}
}
Hope it will help you.
If any query than comment here.I wll help you

Restlet POST Form to send to client resource via JSON

I am getting a 415 Error when sending a form entry to another client resource via JSON. The target URI in my code below ("/message") works when not using the form (i.e. hit "/message" with a test mock object).
Here is my code to get the values of the form and do the post to the target resource. Am I missing something that needs to be done?
I am using the following:
Restlet: 2.1 RC5
GAE: 1.6.1
Form Restlet:
#Post
public void handlePost(Representation entity) {
final Form webForm = new Form(entity);
MessageEntity newMessage = new MessageEntity();
String subject = webForm.getFirstValue("subject");
String sendto = webForm.getFirstValue("email");
String message = webForm.getFirstValue("message");
newMessage.setCategoryID(subject);
newMessage.setAccountID(sendto);
newMessage.setMessageText(message);
ClientResource cr = new ClientResource(getRootRef()+ "/message");
cr.post(newMessage, MediaType.APPLICATION_JSON);
}
Target Resource ("/message")
#Post("json")
public void HandleRequest(MessageEntity messageEntity) {
// Logic here
}
Please let me know if you need more information
Thanks!
I have code that is very similar to yours that works fine. I am also running similar versions of Restlet and GAE. First question I have is are there other #Post methods in your Target Resource as sometimes the ordering matters.
Here are two versions of code that I have that work....
1)
public Representation postHandler() {
Reference commitsRef = new Reference(Consts.RESOURCE_BASE + "commitments/");
ClientResource commitsResource = new ClientResource(getContext(), commitsRef);
....
Representation commitsRep = commitsResource.post(commitForm);
That is posting a form to a Target resource that handles both #Post("json") and #Post("form")
2)
public Representation doPostFromGet() {
Reference takeActRef = new Reference(Consts.RESOURCE_BASE + "commitment/"
+ commitmentId + "/userActs/");
ClientResource takeActResource = new ClientResource(getContext(), takeActRef);
...
Representation takeActRep = takeActResource.post(newAct);
That is posting a Java object to a form that uses what I call the "Peierls magic". See:
http://tembrel.blogspot.com/2012/03/converting-forms-in-restlet-to-pojos.html
It allows you to have one post() in the Target and accept both forms and pojos.
On a minor note, if you are doing a post to add a new message, should the url be "/messages/" (plural) - and perhaps there is a typo somewhere? (An unlikely possibility, but I thought I would mention it).
Good luck,
RB