diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index a5a2a28eca4..0f03cea5763 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -755,7 +755,8 @@ func Comment(ctx *middleware.Context, params martini.Params) {
 
 	var ms []string
 	content := ctx.Query("content")
-	if len(content) > 0 {
+	// Fix #321. Allow empty comments, as long as we have attachments.
+	if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 {
 		switch params["action"] {
 		case "new":
 			if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, models.COMMENT, content, nil); err != nil {
@@ -1081,5 +1082,5 @@ func IssueGetAttachment(ctx *middleware.Context, params martini.Params) {
 
 	// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
 	// We must put the name in " manually.
-	ctx.ServeFile(attachment.Path, "\"" + attachment.Name + "\"")
+	ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"")
 }
diff --git a/templates/repo/issue/view.tmpl b/templates/repo/issue/view.tmpl
index 570698975b0..247931c4aaa 100644
--- a/templates/repo/issue/view.tmpl
+++ b/templates/repo/issue/view.tmpl
@@ -72,7 +72,11 @@
                                 <span class="role label label-default pull-right">Owner</span>
                             </div>
                             <div class="panel-body markdown">
+                                {{if len .Content}}
                                 {{str2html .Content}}
+                                {{else}}
+                                <i>No comment entered</i>
+                                {{end}}
                             </div>
                             {{with $attachments := .Attachments}}
                             {{if $attachments}}