HTML generation in C# I have a method that generates some HTML, but it looks ugly to me. Maybe there are some better solutions for this?

 public static string GetReview(Quiz quiz)
    {
        StringBuilder sb = new StringBuilder();

        string questionSection = string.Format(
            "&lt;div class=\"alert alert-info\" &gt;" +
                "&lt;strong style='color:#000000'&gt;{0}&lt;/strong&gt;" +
            "&lt;/div&gt;", quiz.Question.GetText());


        string correctAnswer = quiz.Answer.GetText();
        string userAnswer = quiz.UserAnswer?.GetText() ?? string.Empty;

        string answerSection;
        if (correctAnswer == userAnswer) {
            answerSection = string.Format(
                "&lt;p style='margin: 10px 0px 5px 400px;'&gt;" +
                    "Your correct answer:" +
                 "&lt;/p&gt;" +
                 "&lt;div class='alert alert-success review-correct'&gt;" +
                    "&lt;strong&gt;{0}&lt;/strong&gt;" +
                 "&lt;/div&gt;", correctAnswer);
        } else {
            answerSection = string.Format(
                @"&lt;p style='margin: 10px 0px 5px 400px;'&gt;" +
                    "The correct answer was:" +
                 "&lt;/p&gt;" +
                 "&lt;div class='alert alert-success review-correct'&gt;" +
                    "&lt;strong&gt;{0}&lt;/strong&gt;" +
                 "&lt;/div&gt;" +
                 "&lt;br/&gt;" +
                 "You had selected: " +
                 "&lt;span style='color:#a94442'&gt;{1}&lt;/span&gt;", correctAnswer, userAnswer);
        }

        string explanationSection = ForQuiz(quiz);

        sb.AppendFormat("&lt;p&gt;{0}&lt;/p&gt;&lt;p&gt;{1}&lt;/p&gt;&lt;p&gt;{2}&lt;/p&gt;", questionSection, answerSection, explanationSection);

        return sb.ToString();
    }
Before we move to the generation part, let's talk about your html...



&lt;p&gt;
    &lt;!-- questionSection --&gt;
    &lt;div class="alert alert-info" &gt;
        &lt;strong style='color:#000000'&gt;question&lt;/strong&gt;
    &lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;
    &lt;!-- answerSection: correct --&gt;
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;The correct answer was:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;
        &lt;strong&gt;good answer&lt;/strong&gt;
    &lt;/div&gt;
    
    &lt;br/&gt;
    You had selected: &lt;span style='color:#a94442'&gt;bad answer&lt;/span&gt;

    &lt;!-- answerSection: wrong --&gt;
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;Your correct answer:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;&lt;strong&gt;qwe&lt;/strong&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;
    &lt;!-- reviewSection --&gt;
    &lt;!-- ForQuiz(quiz) --&gt;
&lt;/p&gt;





&lt;p&gt; can only nest phrasing content. &lt;div&gt; and &lt;p&gt; both belongs to flow content and palpable content. Therefore, you can't nested these 2 under &lt;p&gt; element. For the definition of a phrasing content consult this answer.
Personally, I would prefer using &lt;p&gt; to separate block of text, instead of using a &lt;br /&gt; to insert a line-break.




    &lt;!-- Question Section --&gt;
    &lt;div class="alert alert-info" &gt;
        &lt;strong style='color:#000000'&gt;question&lt;/strong&gt;
    &lt;/div&gt;

    &lt;!-- Answer Section: correct --&gt;
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;The correct answer was:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;
        &lt;strong&gt;good answer&lt;/strong&gt;
    &lt;/div&gt;
    
    &lt;p&gt;You had selected: &lt;span style='color:#a94442'&gt;bad answer&lt;/span&gt;&lt;/p&gt;

    &lt;!-- Answer Section: wrong --&gt;
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;Your correct answer:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;
        &lt;strong&gt;the answer&lt;/strong&gt;
    &lt;/div&gt;

    &lt;!-- Review Section --&gt;
    &lt;!-- ForQuiz(quiz) --&gt;




As for html generation, I believe, it is better to use a templating engine, such as RazorEngine which allows you to  write C# code within the template itself :

review.cshtml :

@{
    var correctAnswer = Model.Answer.GetText();
    var userAnswer = Model.UserAnswer == null ? Model.UserAnswer.GetText() : string.Empty;
}

&lt;!-- Question Section --&gt;
&lt;div class="alert alert-info"&gt;
    &lt;strong style='color:#000000'&gt;@Model.Question.GetText()&lt;/strong&gt;
&lt;/div&gt;

&lt;!-- Answer Section --&gt;
@if (userAnswer == correctAnswer)
{
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;The correct answer was:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;
        &lt;strong&gt;@correctAnswer&lt;/strong&gt;
    &lt;/div&gt;
    &lt;p&gt;You had selected: &lt;span style='color:#a94442'&gt;@userAnswer&lt;/span&gt;&lt;/p&gt;
}
else
{
    &lt;p style='margin: 10px 0px 5px 400px;'&gt;Your correct answer:&lt;/p&gt;
    &lt;div class='alert alert-success review-correct'&gt;
        &lt;strong&gt;@correctAnswer&lt;/strong&gt;
    &lt;/div&gt;
}

&lt;!-- Review Section --&gt;
&lt;!-- TODO: implement ForQuiz(quiz) in razor syntax... --&gt;


generation code :

public string GetReview(Quiz quiz)
{
    var path = Desktop.GetFile("review.cshtml"); // TODO: fix this path
    var template = File.ReadAllText(path);

    return Engine.Razor.RunCompile(template, path, typeof(Quiz), quiz);
}




EDIT: I noticed you used the null-propagation operator from c# 6. You can also use the new string interpolation to format the html : 

public static string GetReview3(Quiz quiz)
{
    var builder = new StringBuilder();
    builder.Append($@"
        &lt;div class='alert alert-info'&gt;
            &lt;strong style='color:#000000'&gt;{quiz.Question.GetText()}&lt;/strong&gt;
        &lt;/div&gt;
    ");

    string correctAnswer = quiz.Answer.GetText();
    string userAnswer = quiz.UserAnswer?.GetText() ?? string.Empty;
    if (correctAnswer == userAnswer)
    {
        builder.Append($@"
            &lt;p style='margin: 10px 0px 5px 400px;'&gt;The correct answer was:&lt;/p&gt;
            &lt;div class='alert alert-success review-correct'&gt;
                &lt;strong&gt;{correctAnswer}&lt;/strong&gt;
            &lt;/div&gt;
            &lt;p&gt;You had selected: &lt;span style='color:#a94442'&gt;{userAnswer}&lt;/span&gt;&lt;/p&gt;
        ");
    }
    else
    {
        builder.Append($@"
            &lt;p style='margin: 10px 0px 5px 400px;'&gt;Your correct answer:&lt;/p&gt;
            &lt;div class='alert alert-success review-correct'&gt;
                &lt;strong&gt;{correctAnswer}&lt;/strong&gt;
            &lt;/div&gt;
        ");
    }

    builder.Append(ForQuiz(quiz));


    return builder.ToString();
}