ASP.NET MVC 5 實務開發問題蒐羅

2020-06-18

蒐集使用 Asp.net MVC 5 開發所碰到的各式問題 (Trouble) 與處理方式 (Workaround)。

實作 & 開發筆記

SQLExpress Community Vesion

(localdb)\MSSQLLocalDB
(localDb)\v11.0
.\sqlexpress

使用表單進行字串篩選的問題 (Filter String with String.Contains Wired Situation)

public ActionResult Index(DocDirectory filter)
{
    var dbQuery = db.DocDirectory.Where(i => i.IsActive == true);

    // filter docNumber
    if (!String.IsNullOrEmpty(filter.DocNumber))
    {
        dbQuery = dbQuery.Where(i => i.DocNumber.Contains(filter.DocNumber));
    }

    // filter owner
    if (!String.IsNullOrEmpty(filter.DocOwner))
    {
        dbQuery = dbQuery.Where(i => i.DocOwner.Contains(filter.DocOwner));
    }

    // filter title
    // 這邊字串比較有問題,轉成 List 再進行比較就恢復了,暫時無解。推測可能是 IQueryable 的問題?
    var result = dbQuery.ToList();
    if (!String.IsNullOrEmpty(filter.DocTitle))
    {
        result = result.Where(i => i.DocTitle.Contains(filter.DocTitle)).ToList();
    }

    ViewBag.filteTitle = filter.DocTitle;
    return View(result);
}

如何重複使用 Razor Helper

/App_Code/RazorHelper.cshtml

@helper HelperName(string str)
{
    ...
}

如 View 中呼叫 /View/Index.cshtml

<p>
    @RazorHelper.HelperName(str)
</p>

MSDN - 在 ASP.NET Web Pages (Razor)網站中建立和使用 Helper

如能讓 Action 支援回應 CROS

/Filters/AllowCORSAttribute.cs

public class AllowCORSAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);
    }
}

/Controllers/HomeController.cs

[AllowCROS]
public ActionResult Index(string code = null)
{
    ...
}

MVC 調用 Process / Python script

using System.Diagnostics;

public ActionResult Trigger()
{
  String Command = "python C:\\Pytools\\create.py";
  ProcessStartInfo ProcessInfo;

  // /C 結束後關閉console /K 結束後保留console
  ProcessInfo = new ProcessStartInfo("cmd.exe", "/C " + Command);
  ProcessInfo.CreateNoWindow = true;
  ProcessInfo.UseShellExecute = true;

  var p = Process.Start(ProcessInfo);
  p.Close();
          
  return Content("Success trigger");
}

客製 Html Helper

/Exntensions/HtmlHelperExtensions.cs

using System.Web.Mvc;

namespace DevLab.Extensions
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString Submit(this HtmlHelper htmlHelper, object htmlAttributes = null)
        {
            var tag = new TagBuilder("input");
            tag.Attributes.Add("type", "submit");
            tag.Attributes.Add("value", "送出");

            if (htmlAttributes != null)
            {
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                tag.MergeAttributes(attributes);
            }
            else
            {
                tag.AddCssClass("btn btn-secondary");
            }


            var html = tag.ToString();
            return MvcHtmlString.Create(html);
        }
    }
}

/Views/Web.config

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="DevLab.Extensions" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

如何加入 PartialCLass & DataAnnotations

ASP.NET MVC 如何加入 PartialCLass & DataAnnotations

Enable jquery validation ; 啟用 Client 端驗證


@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<div class="form-group">
    @Html.LabelFor(m => Model.FirstOrDefault().Price, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(m => Model.FirstOrDefault().Price, new { htmlAttributes = new { @class = "form-control", @Value = "" } })
        @Html.ValidationMessageFor(m => Model.FirstOrDefault().Price, "", new { @class = "text-danger" })
    </div>
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

綜合參考資料

MVC

C#