cdub
cdub

Reputation: 25751

Parse an email address string in C# to MailAddress object

I have a C# backend code that receives a POST request from the client side code in TypeScript.

The JSON is done for the POST with JSON.stringify(objectOfData);

In the C# code I am getting an exception when I try to use the object like so:

// Passed into this function is InboundObjectDTO inboundObject

// inboundObject.Email in debugger is like so: "\"[email protected]\""

var message = new MailMessageDTO
{
    Subject = "My Subject",
    MailAddresses = new List<MailAddress>()
};

message.MailAddresses.Add(new MailAddress(inboundObject.Email));

Am I supposed to deserialize the object somehow before hand? I have 3 strings in the object: email, message, and name.

The last line of code above gives me "An invalid character in MailAddresses exception." I am guessing it needs to have all the extra quotes and such removed in a proper way.

Upvotes: 0

Views: 490

Answers (2)

Yiyi You
Yiyi You

Reputation: 18239

If you are posting json data to controller action,you can use [FromBody],[FromBody] will get values from the request body:

public IActionResult Index([FromBody]inboundObject inboundObject)
{
    ...
}

Or you can use JsonConvert.DeserializeObject to deserialize the the JSON to specified .NET type:

message.MailAddresses.Add(new MailAddress(JsonConvert.DeserializeObject<string>(inboundObject.Email)));

Upvotes: 0

Chris Schaller
Chris Schaller

Reputation: 16777

As OP had originally postulated, the issue is the quotes around the email address, all we need to do is remove those quotes. This process is referred to as Sanitizing the input.

The original methodology was hard to follow and the exception information posted was ambiguous, this solution shows how to sanitise the input and return more relevant information with the exception.

The example you have pasted ""[email protected]"" would not fail in your original code that included the santize logic, if you had simply used the result of the sanitize step!

You should wrap the code block in a try-catch so you can capture the exception and output the specific string value that has failed:

string email = inboundObject.Email;
MailMessageDTO message = null;
try
{
    // sanitized the email, removed known invalid characters
    email = email.Replace("\"", "");

    // construct the payload object
    message = new MailMessageDTO
    {
        Subject = "My Subject",
        MailAddresses = new List<MailAddress>()
    };
    message.MailAddresses.Add(new MailAddress(email));
}
catch (Exception ex)
{
    throw new ApplicationException($"Failed to construct MailMessage for email: {email}", ex);
}

Now when this fails, we have more information to work with inside the exception, infact this situation itself probably warrants it's own separate reusable method:

public MailAddress SanitizeEmail(string emailAddress)
{
    string email = emailAddress;
    try
    {
        // sanitized the email, removed known invalid characters
        email = email.Replace("\"", "");
        
        // TODO: add other rules an replacement cases as you find them

        return new MailAddress(email);
    }
    catch (Exception ex)
    {
        throw new ApplicationException($"Failed to sanitize email address: '{email}' [original input: '{emailAddress ?? "NULL" }']", ex);
    }
}

You could call this using:

message.MailAddresses.Add(SanitizeEmail(email));

Update

OP's original code included references and test conditions that are no longer in the posted code, this response has only been marginally updated to reflect those changes

Upvotes: 1

Related Questions