เรียก UrlHelper ในรุ่นต่างๆใน ASP.NET MVC


159

ฉันต้องการสร้าง URL ในรูปแบบใน ASP.NET MVC ฉันต้องการเรียกบางอย่างเช่น UrlHelper.Action () ซึ่งใช้เส้นทางเพื่อสร้าง URL ฉันไม่รังเกียจที่จะเติมช่องว่างปกติเช่นชื่อโฮสต์แบบแผนและอื่น ๆ

มีวิธีใดบ้างที่ฉันสามารถเรียกใช้ได้ มีวิธีสร้าง UrlHelper หรือไม่?


1
ฉันกำลังคิดเกี่ยวกับเรื่องนี้ แต่โปรดทราบว่า Url.Action จะสร้าง URL ที่เกี่ยวข้อง ตรวจสอบให้แน่ใจว่าเป็นสิ่งที่คุณต้องการ
Vivian River

คำตอบ:


277

เคล็ดลับที่มีประโยชน์ในแอปพลิเคชัน ASP.NET ใด ๆ คุณสามารถรับการอ้างอิงของ HttpContext ปัจจุบัน

HttpContext.Current

ซึ่งได้มาจาก System.Web ดังนั้นสิ่งต่อไปนี้จะใช้ได้ทุกที่ในแอปพลิเคชัน ASP.NET MVC:

UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info

ตัวอย่าง:

public class MyModel
{
    public int ID { get; private set; }
    public string Link
    {
        get
        {
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
            return url.Action("ViewAction", "MyModelController", new { id = this.ID });
        }
    }

    public MyModel(int id)
    {
        this.ID = id;
    }
}

การเรียกLinkคุณสมบัติบนวัตถุ MyModel ที่สร้างขึ้นจะส่งคืน Url ที่ถูกต้องเพื่อดูแบบจำลองตามเส้นทางใน Global.asax


คุณแน่ใจหรือว่ามี HttpContext.Current.Request.RequestContext HttpContext.Current.Request ดูเหมือนว่าจะไม่มี RequestContext
pupeno

1
นั่นเป็นสิ่งที่แปลก ฉันเพิ่งทดสอบโซลูชันนี้และทำงานได้อย่างสมบูรณ์ ฉันใช้ ASP.NET MVC 2 ดูตัวอย่าง 2 แต่ฉันคิดว่าวิธีนี้ใช้ได้กับทุกรุ่น ไม่แน่ใจว่าทำไมมันไม่ทำงานสำหรับคุณ คุณกำลังสร้างชั้นเรียนนอกโครงการ MVC หรือไม่? ตรวจสอบให้แน่ใจว่ามีusingสำหรับทั้งคู่System.WebและSystem.Web.Mvc
โอมาร์

ฉันอยู่ในโครงการ ASP.NET MVC 1 ฉันคิดถึงการใช้ที่หายไป แต่ฉันมีทั้งคู่
pupeno

ไม่แน่ใจจริงๆว่าทำไมมันไม่แสดง หากใครก็ตามสามารถยืนยันได้ว่าสิ่งนี้ไม่มีอยู่ใน ASP.NET MVC 1 ที่ยอดเยี่ยม ฉันมีเพียงเครื่องเดียวที่ติดตั้ง VS2010 และ MVC 2 หากคุณสนใจ MVC RC 2 haacked.com/archive/2009/12/16/aspnetmvc-2-rc.aspx
Omar

6
โปรดทราบว่า Request.RequestContex รองรับใน. NET4 +
h - n -

64

ฉันชอบคำตอบของโอมาร์ แต่นั่นไม่ได้ผลสำหรับฉัน สำหรับบันทึกนี้เป็นคำตอบที่ฉันใช้ตอนนี้:

var httpContext = HttpContext.Current;

if (httpContext == null) {
  var request = new HttpRequest("/", "http://example.com", "");
  var response = new HttpResponse(new StringWriter());
  httpContext = new HttpContext(request, response);
}

var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);

return new UrlHelper(requestContext);

มันมี URL ของเว็บไซต์ของฉัน ที่นั่นฉันลบมัน
pupeno

4
พิจารณาว่าคลาส UrlHelper อาศัยบริบทคำขอ (และบริบท HTTP) การสร้างวัตถุบริบทเหล่านั้นด้วยตนเองอาจให้ผลลัพธ์ที่ไม่คาดคิด หาก HttpContext.Current เป็นโมฆะและคุณใช้วิธีนี้ฉันจะดำเนินการต่อด้วยความระมัดระวัง
ฌอน

4
ระวังคำตอบนี้ - ผลลัพธ์ RequestContext ที่เป็นผลลัพธ์ใน UrlHelper ที่ส่งคืนสตริงว่างเสมอ
gknicker

47

UrlHelper สามารถสร้างขึ้นจากภายในการดำเนินการควบคุมด้วยต่อไปนี้:

 var url = new UrlHelper(this.ControllerContext.RequestContext);
 url.Action(...);

ด้านนอกของคอนโทรลเลอร์สามารถสร้าง UrlHelper ได้โดยสร้าง RequestContext จาก RouteTable.Routes RouteData

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));

(ตามคำตอบของ Brian โดยมีการแก้ไขโค้ดเล็กน้อย)


2
แต่ฉันไม่มีคอนโทรลเลอร์ในโมเดล
pupeno

ตกลงฉันขอโทษฉันไม่แน่ใจว่ารหัสถูกดำเนินการตรงไหน ให้ฉันดู ...
นาธานเทย์เลอร์

2
ไม่จำเป็นต้องสร้างบริบทคำขอใหม่:var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7

Nice @ bradlis7 นั่น MVC 5 หรือเปล่า
Nathan Taylor

1
ไม่ทำงานเพราะthis.ControllerContext.RequestContextเป็นHttpRequestContextและสร้างของคาดว่าUrlHelper RequestContextทั้งสองคลาสนั้นไม่เกี่ยวข้องกัน
Florian Winter

8

ใช่คุณสามารถยกตัวอย่างได้ คุณสามารถทำสิ่งที่ชอบ:

var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
   new RequestContext(ctx,
   RouteTable.Routes.GetRouteData(ctx));

RouteTable.Routesเป็นคุณสมบัติคงที่ดังนั้นคุณควรตกลงที่นั่น ในการรับการHttpContextBaseอ้างอิงHttpContextWrapperใช้การอ้างอิงHttpContextและHttpContextส่งสิ่งนั้น


สิ่งนี้จะไม่ทำงานแม้ว่าจะอยู่ใกล้มาก ดูคำตอบของฉันด้านล่าง
นาธานเทย์เลอร์


0

ฉันพยายามทำสิ่งที่คล้ายกันจากภายในหน้า (นอกตัวควบคุม)

UrlHelper ไม่อนุญาตให้ฉันสร้างมันได้อย่างง่ายดายเหมือนคำตอบของ Pablos แต่ฉันจำได้ว่าเคล็ดลับเก่าแก่ที่มีประสิทธิภาพในการทำสิ่งเดียวกัน:

string ResolveUrl(string pathWithTilde)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.