Popular Posts
Activate IIS GIZP compress 1. Set metabase editable for editing. 2. Add a new extension for gzip. 3. Edit the file c:\windows\system32\inetsrv\MetaBase.xml Add file... Sublime Text hotkeys 編輯 Ctrl + X 刪除行 Ctrl + Enter 插入下一行 Ctrl + Shift + Enter 插入前一行 Ctrl + Shift + ↑ 往上移動一行 C... Tomcat GET encoding edit server.xml : <Connector     URIEncoding="UTF-8"     connectionTimeout="20000"     port="8080"     prot...
Stats
Showing posts with label .net mvc. Show all posts
Showing posts with label .net mvc. Show all posts
Output a file like url via routing
Prepare a binary output action for file output
[RoutePrefix("images")]
public class ImageController : Controller
{
    // GET: ~/images/profile.png
    // GET: ~/images/1873429732.jpg
    [HttpGet]
    [Route("{name}.{ext}")]
    public ActionResult ReadImage(string name, string ext)
    {
        if (System.IO.File.Exists(Server.MapPath(string.Format("~/uploads/{0}.{1}", name, ext))))
        {
            byte[] data = System.IO.File.ReadAllBytes(Server.MapPath(string.Format("~/uploads/{0}.{1}", name, ext)));
            string contentType = MimeMapping.GetMimeMapping(System.IO.Path.GetFileName(string.Format("{0}.{1}", name, ext)));
            return File(data, contentType);
        }
        else
        {
            return new HttpStatusCodeResult(404);
        }
    }
}

Then try test it, but respone 404 not found.




Add runAllManagedModulesForAllRequests="true" on modules section.


<?xml version="1.0" encoding="utf-8"?>
<configuration>
  ...
  <system.webServer>
    ...
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="ApplicationInsightsWebTracking"/>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
        preCondition="managedHandler"/>
    </modules>
  </system.webServer>
  ...
</configuration>

Then try it again, image rendered success.


ASP.NET MVC 5 Attribute Routing
Enable attribute route
Global.asax
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // Enable attribute route
        RouteTable.Routes.MapMvcAttributeRoutes();

        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}
or
RouteConfig.cs
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
        // Enable attribute route
        routes.MapMvcAttributeRoutes();

        AreaRegistration.RegisterAllAreas();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
Direct route
public class BookController : Controller {

    // Map to 'http://prhythm.com.tw/Pet/10'
    [Route("Pet/{id}")]
    public ActionResult Pet(int? id) {
        return View();
    }

}
Optional paramter
public class BookController : Controller {

    // Optional parameter id
    // Map to 'http://prhythm.com.tw/Pet'
    //     or 'http://prhythm.com.tw/Pet/5'
    [Route("Pet/{id?}")]
    public ActionResult Pet(int? id) {
        return View();
    }

}
Default parameter value
public class BookController : Controller {
    
    // Default value of id
    // Map to 'http://prhythm.com.tw/Pet'
    //     or 'http://prhythm.com.tw/Pet/10'
    [Route("Pet/{id=10}")]
    public ActionResult Pet(int? id) {
        return View();
    }

}
Paramter constrains
public class BookController : Controller {
    
    // Paramters constrains
    [Route("Pet/{id:int}")]
    public ActionResult Pet(int? id) {
        return View();
    }

}
ConstraintDescriptionExample
alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha}
bool Matches a Boolean value. {x:bool}
datetime Matches a DateTime value. {x:datetime}
decimal Matches a decimal value. {x:decimal}
double Matches a 64-bit floating-point value. {x:double}
float Matches a 32-bit floating-point value. {x:float}
guid Matches a GUID value. {x:guid}
int Matches a 32-bit integer value. {x:int}
length Matches a string with the specified length or within a specified range of lengths. {x:length(6)}
{x:length(1,20)}
long Matches a 64-bit integer value. {x:long}
max Matches an integer with a maximum value. {x:max(10)}
maxlength Matches a string with a maximum length. {x:maxlength(10)}
min Matches an integer with a minimum value. {x:min(10)}
minlength Matches a string with a minimum length. {x:minlength(10)}
range Matches an integer within a range of values. {x:range(10,50)}
regex Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}
Route prefix
[RoutePrefix("Booking")]
public class BookController : Controller {

    // Map to 'http://prhythm.com.tw/Booking'
    //     or 'http://prhythm.com.tw/Booking/Pet'
    [Route]    
    [Route("Pet")]
    public ActionResult Pet() {
        return View();
    }

    // Map to 'http://prhythm.com.tw/Booking/Edit'
    [Route("Edit")
    public ActionResult Edit() {
        return View();
    }
}
Override route prefix
[RoutePrefix("Booking")]
public class BookController : Controller {

    // Override route prefix
    // Map to 'http://prhythm.com.tw/Pet'
    [Route("~/Pet")]
    public ActionResult Pet() {
        return View();
    }
}
Default route
[RoutePrefix("Booking")]
[Route("action=pet")]
public class BookController : Controller {

    // Map to 'http://prhythm.com.tw/Booking'
    //     or 'http://prhythm.com.tw/Booking/Pet'
    public ActionResult Pet() {
        return View();
    }

    // Map to 'http://prhythm.com.tw/Booking/Edit'
    public ActionResult Edit() {
        return View();
    }
}
Route area
[RouteArea("Backend")]
[RoutePrefix("News")]
public class NewsController : Controller {

    // Map to 'http://prhythm.com.tw/backend/news'
    public ActionResult Index() {
        return View();
    }

}
[RouteArea("Backend", AreaPrefix = "Admin")]
[RoutePrefix("News")]
public class NewsController : Controller {

    // Map to 'http://prhythm.com.tw/admin/news'
    public ActionResult Index() {
        return View();
    }

}

Reference http://sampathloku.blogspot.tw/2013/11/attribute-routing-with-aspnet-mvc-5.html

Reference http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx

Override Response Content-Type with OutputCache

Response content-type will be set as text/html on OutputCache is assigned, even if there is an assignment inside action.

HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OutputCache(Duration = 60)]
        public ActionResult NavigationScript()
        {
            Response.ContentType = "application/javascript";
            return View();
        }
    }
}
Result

Custom a attribute and change content type after output cache processed.

ResponseHeaderAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Filter
{
    public class ResponseHeaderAttribute : ActionFilterAttribute
    {
        public string ContentType { get; set; }
        public System.Text.Encoding ContentEncoding { get; set; }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (!string.IsNullOrWhiteSpace(ContentType)) filterContext.HttpContext.Response.ContentType = ContentType;
            if (ContentEncoding != null) filterContext.HttpContext.Response.ContentEncoding = ContentEncoding;
        }
    }
}
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Filter;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [OutputCache(Duration = 60, Order = 1)]
        [ResponseHeader(ContentType = "application/javascript", Order = 2)]
        public ActionResult NavigationScript()
        {
            return View();
        }
    }
}
Result
Session State Locks cause pending requests

In some scenario, while there is a long pending request exist, it may cause other request pending because session data is locked by the first request. Here is a example of session lock.

First I have a controller with default session policy

using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult LongTimeout()
        {
            System.Threading.Thread.Sleep(30000);
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ShortTimeout()
        {
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Captcha()
        {
            var captcha = MathCaptcha.Generate();
            Session["captcha"] = captcha.Answer;

            return File(captcha.GetImageData(ImageFormat.Png), "image/png");
        }
    }
}

And then create another controller that make session state readonly

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication2.Controllers
{
    [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
    public class SessionLessController : Controller
    {
        public ActionResult LongTimeout()
        {
            System.Threading.Thread.Sleep(30000);
            return Json(new {code=200 }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ShortTimeout()
        {
            return Json(new { code = 200 }, JsonRequestBehavior.AllowGet);
        }
    }
}

Request is pending because the session of first request is locked

After first request completed, other requests will go on

Request won't be block when session state is set as readonly

CORS in Asp.net MVC Web API v2

Step 1.

Install cors from NeGet

Step 2.

Enable cors in config
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace WebSample
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.EnableCors();
        }
    }
}

Step 3

Add cors attribute to your controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
using WebSample.Models;

namespace WebSample.Controllers.Api
{
    public class JobController : ApiController
    {
        [EnableCors(origins: "*", headers: "*", methods: "GET")]
        public Message Get()
        {
            return new Message
            {
                ID = 2,
                Content = "Job"
            };
        }
    }
}

Step 4

Test x-domain request
Error on RenderAction - No route in the route table matches the supplied values
Application works fine on develop machine and staging server. When deploy to production, there was some route error occurs on RenderAction.
Here is the Rounte config:
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}/{*filePath}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Although the id parameter is not required in this rounting. I've tried use code bellow and error occurs
@{Html.RenderAction("ListPart", "Store");}

@{Html.RenderAction("ListPart", "Store", new { id = UrlParameter.Optional });}
Finally, I add a really value to solve it.
@{Html.RenderAction("ListPart", "Store", new { id = 0 });}
Action results
  • ActionResult

    Encapsulates the result of an action method and is used to perform a framework-level operation on behalf of the action method.
    public ActionResult Index()
    {
        return Show();
    }
    
    public ActionResult Show()
    {
        return View();
    }
    
  • ContentResult

    Represents a user-defined content type that is the result of an action method.
    public ActionResult Index()
    {
        return Content("Represents a user-defined content type that is the result of an action method.", "text/plain", System.Text.Encoding.UTF8);
    }
  • EmptyResult

    Represents a result that does nothing, such as a controller action method that returns nothing.
    public ActionResult Index()
    {
        return new EmptyResult();
    }
  • FileContentResult

    Sends the contents of a binary file to the response.
    public ActionResult Index()
    {
        //return new FileContentResult(Buffer, "application/pdf");
        return File(Buffer, "application/pdf");
    }
  • FilePathResult

    Sends the contents of a file to the response.
    public ActionResult Index()
    {
        return File(Server.MapPath("~/doc/sample.pdf"), "application/pdf");
    }
  • FileStreamResult

    Sends binary content to the response by using a Stream instance.
    public ActionResult Index()
    {
        using (var ms = new System.IO.MemoryStream())
        {
            TempImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            //return new FileStreamResult(ms, "image/png") { FileDownloadName = "logo.png" };
            return File(ms, "image/png", "logo.png");
        }
    }
  • HttpNotFoundResult

    Defines an object that is used to indicate that the requested resource was not found.
    public ActionResult Index()
    {
        return HttpNotFound("Page not fould");
    }
  • HttpStatusCodeResult

    Provides a way to return an action result with a specific HTTP response status code and description.
    public ActionResult Index()
    {
        return new HttpStatusCodeResult(System.Net.HttpStatusCode.Unauthorized);
    }
  • HttpUnauthorizedResult

    Represents the result of an unauthorized HTTP request.
    public ActionResult Index()
    {
        return new HttpUnauthorizedResult("Please sign in");
    }
  • JavaScriptResult

    Sends JavaScript content to the response.
    public ActionResult Index()
    {
        return JavaScript("alert(new Date());");
    }
  • JsonResult

    Represents a class that is used to send JSON-formatted content to the response.
    public ActionResult Index()
    {
        return Json(new { Message = "Represents a class that is used to send JSON-formatted content to the response." });
    }
  • PartialViewResult

    Represents a base class that is used to send a partial view to the response.
    public ActionResult Index()
    {
        return PartialView();
    }
  • RedirectResult

    Controls the processing of application actions by redirecting to a specified URI.
    public ActionResult Index()
    {
        //return Redirect("/Product");  // 302
        return RedirectPermanent("/Product");  // 301
    }
    Redirect and RedirectPermanent
  • RedirectToRouteResult

    Represents a result that performs a redirection by using the specified route values dictionary.
    public ActionResult Index()
    {
        //return RedirectToAction("Show");
        //return RedirectToActionPermanent("Show");
        //return RedirectToRoute(new { action = "Show" });
        return RedirectToRoute(new { action = "Show" });
    }
  • ViewResult

    Represents a class that is used to render a view by using an IView instance that is returned by an IViewEngine object.
    public ActionResult Index()
    {
        return View();
    }
Action attributes
  • AcceptVerbsAttribute

    Represents an attribute that specifies which HTTP verbs an action method will respond to.
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index() { return View(); }
    [AcceptVerbs("get", "post")]
    public ActionResult Index() { return View(); }
  • ActionFilterAttribute

    Represents the base class for filter attributes.
    public class PermissionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
        }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
        }
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);
        }
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
        }
    }
  • ActionMethodSelectorAttribute

    Represents an attribute that is used to influence the selection of an action method.
    public class RequestSourceFilterAttribute : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            throw new NotImplementedException();
        }
    }
  • ActionNameAttribute

    Represents an attribute that is used for the name of an action.
    [ActionName("Substitute")]
    public ActionResult Index() { return View(); }
  • ActionNameSelectorAttribute

    Represents an attribute that affects the selection of an action method.
    public class RequestSourceFilterAttribute : ActionNameSelectorAttribute
    {
        public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
        {
            throw new NotImplementedException();
        }
    }
  • AllowHtmlAttribute

    Allows a request to include HTML markup during model binding by skipping request validation for the property. (It is strongly recommended that your application explicitly check all models where you disable request validation in order to prevent script exploits.)
    [AllowHtml]
    public ActionResult Index() { return View(); }
  • AsyncTimeoutAttribute

    Represents an attribute that is used to set the timeout value, in milliseconds, for an asynchronous method.
    [AsyncTimeout(1000000)] // In milliseconds.
    public ActionResult Index() { return View(); }
  • AuthorizeAttribute

    Represents an attribute that is used to restrict access by callers to an action method.
    [Authorize(Users = "Betty, Johnny", Roles = "Admin, Super User")]
    public ActionResult Index() { return View(); }
    public class ApplicationAuthorizaeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return base.AuthorizeCore(httpContext);
        }
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
        }
        protected override HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            return base.OnCacheAuthorization(httpContext);
        }
    }
  • ChildActionOnlyAttribute

    Represents an attribute that is used to indicate that an action method should be called only as a child action.
    [ChildActionOnly]
    public ActionResult Index() { return View(); }
    @{Html.RenderAction("Index");}
  • FilterAttribute

    Represents the base class for action and result filter attributes.
    public class BaseFileter : FilterAttribute
    {
        public override bool IsDefaultAttribute()
        {
            return base.IsDefaultAttribute();
        }
        public override bool Match(object obj)
        {
            return base.Match(obj);
        }
    }
  • HandleErrorAttribute

    Represents an attribute that is used to handle an exception that is thrown by an action method.
    [HandleError(Master = "Site", View = "Error", ExceptionType = typeof(NullReferenceException))]
    public ActionResult Index() { return View(); }
  • HttpDeleteAttribute

    Represents an attribute that is used to restrict an action method so that the method handles only HTTP DELETE requests.
    [HttpDelete]
    public ActionResult Index() { return View(); }
  • HttpGetAttribute

    Represents an attribute that is used to restrict an action method so that the method handles only HTTP GET requests.
    [HttpGet]
    public ActionResult Index() { return View(); }
  • HttpPostAttribute

    Represents an attribute that is used to restrict an action method so that the method handles only HTTP POST requests.
    [HttpPost]
    public ActionResult Index() { return View(); }
  • HttpPutAttribute

    Represents an attribute that is used to restrict an action method so that the method handles only HTTP PUT requests.
    [HttpPut]
    public ActionResult Index() { return View(); }
  • NonActionAttribute

    Represents an attribute that is used to indicate that a controller method is not an action method.
    [NonAction]  // Prevent called from url
    public void InnerCall() { Response.Write("Hello InnerCall"); Response.End(); }
  • OutputCacheAttribute

    Represents an attribute that is used to mark an action method whose output will be cached.
    [OutputCache(Duration = 60, VaryByParam = "page")]
    public ActionResult Index() { return View(); }
  • RequireHttpsAttribute

    Represents an attribute that forces an unsecured HTTP request to be re-sent over HTTPS.
    [RequireHttps]
    public ActionResult Index() { return View(); }
  • SessionStateAttribute

    Specifies the session state of the controller.
    [SessionState(System.Web.SessionState.SessionStateBehavior.Required)]
    public ActionResult Index() { return View(); }
  • ValidateInputAttribute

    Represents an attribute that is used to mark action methods whose input must be validated.
    [ValidateInput(false)]
    public ActionResult Index() { return View(); }