2011-11-08 22 views
3

當我第一次遇到這個問題時,我把它作爲旁邊帶來Previous Question,我不能在我的應用程序,因爲有太多的JavaScript, CSS和圖像踢,可能會加劇這個問題。IE9意外的行爲與MVC,IMG標籤,Url.Action和TempData

現在我已經做了一個非常簡單的MVC應用程序沒有javascipt的,沒有CSS,沒有其他的圖像,似乎IE9叫我Url.Action兩次(小提琴手確認),但Chrome和Firefox都做我的期望。

該應用程序很簡單,它包含一個模型,該模型具有一個屬性和一個返回(MSChart圖像的)內存流的方法。視圖顯示圖像和顏色選擇器,當視圖發佈到控制器時,控制器爲圖表設置顏色並創建視圖。通過調用控制器RenderChart通過Url.Action的動作顯示圖表圖像,MemoryStream通過TempData從視圖傳遞到RenderImage動作。這適用於GET,但是當它是POST時,IE9總是請求RenderChart兩次,第二次,TempData已被刪除。這個問題可以通過在RenderChart行動中「重置」TempData(註釋掉)來解決,但這非常容易解決,因此顯然不是您所信任的答案。

我不是在尋找替代品我已經有其他替代品了,但是......任何人都可以解釋這種行爲?

這裏的模型

public class ChartModel 
    { 
     public ChartModel() 
     { 
      this.ChartColor = Color.Green; 
     } 
     public ChartModel(Color color) 
     { 
      this.ChartColor = color; 
     } 
     public Color ChartColor { get; set; } 
     public MemoryStream Chart() 
     { 
      Chart chart = new Chart(); 
      chart.Height = 250; 
      chart.Width = 450; 
      chart.ImageType = ChartImageType.Jpeg; 
      chart.RenderType = RenderType.BinaryStreaming; 
      chart.BackColor=ChartColor; 

      chart.BorderlineDashStyle = ChartDashStyle.Solid; 
      chart.BackGradientStyle = GradientStyle.TopBottom; 
      chart.BorderlineWidth = 2; 
      chart.BorderlineColor = Color.Blue; 
      chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss; 
      ChartArea ca = chart.ChartAreas.Add("Default"); 
      ca.BackColor = Color.Transparent; 
      ca.AxisX.IsMarginVisible = false; 

      Series series = chart.Series.Add("Browser/Gets"); 
      series.ChartType = SeriesChartType.Bar; 
      string[] browsers = new string[]{"IE9","Chrome","FireFox"}; 
      int[] gets = new int[]{2,1,1}; 
      series.Points.DataBindXY(browsers, gets); 

      using (MemoryStream memStream = new MemoryStream()) 
      { 
       chart.SaveImage(memStream, ChartImageFormat.Jpeg); 
       return memStream; 
      } 
     } 
    } 

這裏的景色

@model TestChart.Models.ChartModel   
@{ 
    ViewBag.Title = "Chart"; 
} 
<h2>Chart</h2> 
@using (Html.BeginForm("Index", "Chart")) 
{ 
    @Html.DropDownListFor(m => m.ChartColor, new SelectList(Enum.GetNames(typeof(System.Drawing.KnownColor)))) 
    <br /> 
    <div> 
     <div> 
      <br /> 
      @{TempData["Chart"] = Model.Chart(); 
      } 
      <img alt="Chart" src="@Url.Action("RenderChart", "Chart")" /> 
     </div> 
    </div> 
    <input type="submit" value="Post" /> 
} 

而這裏的控制器

public class ChartController : Controller 
    { 
     public ActionResult Index(string colorName = "White") 
     { 
      ChartModel model; 
      model = new ChartModel(Color.FromName(colorName)); 
      return View(model); 
     } 

     [HttpPost] 
     public ActionResult Index(ChartModel model) 
     { 
      return RedirectToAction("Index", new { colorName = model.ChartColor.Name }); 
     } 

     public FileContentResult RenderChart() 
     { 
      MemoryStream ms = TempData["Chart"] as MemoryStream; 
      // TempData["Chart"] = ms; //uncomment this line to get IE9 to work - odd indeed 
      return File(ms.ToArray(), "image/jpeg"); 
     } 
    } 

而生成的HTML看起來像......(顏色列表截斷)

<form action="/Chart" method="post"> 
<select data-val="true" data-val-required="The ChartColor field is required." id="ChartColor" name="ChartColor"> <option>ActiveBorder</option> 
: 
<option>MenuHighlight</option> 
</select> <br /> 
    <div> 
     <div> 
      <br /> 
      <img alt="Chart" src="/Chart/RenderChart" /> 
     </div> 
    </div> 
    <input type="submit" value="Post" /> 
</form> 
</body> 
</html> 

而且提琴手輸出看起來像這樣 Fiddler 提琴手時,它的工作原理(在兼容模式) Fiddler working

提琴手頭 - 工程確定

GET /Chart/Index/WindowFrame HTTP/1.1 
Accept: text/html, application/xhtml+xml, */* 
Referer: http://localhost:54307/Chart/Index/Menu 
Accept-Language: zh,es;q=0.9,en-GB;q=0.7,de-DE;q=0.6,fr-FR;q=0.4,nl;q=0.3,fr-CA;q=0.1 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 
Accept-Encoding: gzip, deflate 
Host: localhost:54307 
Connection: Keep-Alive 
Pragma: no-cache 
Cookie: ASP.NET_SessionId=biv2pyhxucudsg3aqsvv3jbs 

GET /Chart/RenderChart HTTP/1.1 
Accept: image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5 
Referer: http://localhost:54307/Chart/Index/WindowFrame 
Accept-Language: zh,es;q=0.9,en-GB;q=0.7,de-DE;q=0.6,fr-FR;q=0.4,nl;q=0.3,fr-CA;q=0.1 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 
Accept-Encoding: gzip, deflate 
Host: localhost:54307 
Connection: Keep-Alive 
Cookie: ASP.NET_SessionId=biv2pyhxucudsg3aqsvv3jbs 

提琴手頭故障

GET /Chart/Index/Transparent HTTP/1.1 
Accept: text/html, application/xhtml+xml, */* 
Referer: http://localhost:54307/Chart/Index/WindowFrame 
Accept-Language: zh,es;q=0.9,en-GB;q=0.7,de-DE;q=0.6,fr-FR;q=0.4,nl;q=0.3,fr-CA;q=0.1 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 
Accept-Encoding: gzip, deflate 
Host: localhost:54307 
Connection: Keep-Alive 
Pragma: no-cache 
Cookie: ASP.NET_SessionId=biv2pyhxucudsg3aqsvv3jbs 

GET /Chart/RenderChart HTTP/1.1 
Accept: image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5 
Referer: http://localhost:54307/Chart/Index/Transparent 
Accept-Language: zh,es;q=0.9,en-GB;q=0.7,de-DE;q=0.6,fr-FR;q=0.4,nl;q=0.3,fr-CA;q=0.1 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 
Accept-Encoding: gzip, deflate 
Host: localhost:54307 
Connection: Keep-Alive 
Cookie: ASP.NET_SessionId=biv2pyhxucudsg3aqsvv3jbs 

這裏是一些提琴手的時機(post/imageOK/image fai led)

請注意,失敗的人直到帖子完成後纔開始。讓我懷疑是否沒有某種額外的線程認爲IMG標籤沒有實現,並決定去做。確實是神祕的。

== FLAGS ================== 
BitFlags: [None] 0x0 
X-RESPONSEBODYTRANSFERLENGTH: 5627 
X-PROCESSINFO: iexplore:3100 
X-CLIENTIP: 127.0.0.1 
X-HOSTIP: ::1 
X-EGRESSPORT: 62803 
X-CLIENTPORT: 62801 

== TIMING INFO ============ 
ClientConnected: 21:23:58.866 
ClientBeginRequest: 21:23:58.866 
ClientDoneRequest: 21:23:58.867 
Determine Gateway: 0ms 
DNS Lookup:   0ms 
TCP/IP Connect: 1ms 
HTTPS Handshake: 0ms 
ServerConnected: 21:23:58.868 
FiddlerBeginRequest: 21:23:58.868 
ServerGotRequest: 21:23:58.868 
ServerBeginResponse: 21:23:58.928 
ServerDoneResponse: 21:23:58.928 
ClientBeginResponse: 21:23:58.928 
ClientDoneResponse: 21:23:58.928 

== FLAGS ================== 
BitFlags: [None] 0x0 
X-RESPONSEBODYTRANSFERLENGTH: 17612 
X-PROCESSINFO: iexplore:3100 
X-CLIENTIP: 127.0.0.1 
X-HOSTIP: ::1 
X-EGRESSPORT: 62804 
X-CLIENTPORT: 62802 

== TIMING INFO ============ 
ClientConnected: 21:23:58.866 
ClientBeginRequest: 21:23:59.001 
ClientDoneRequest: 21:23:59.001 
Determine Gateway: 0ms 
DNS Lookup:   0ms 
TCP/IP Connect: 0ms 
HTTPS Handshake: 0ms 
ServerConnected: 21:23:59.002 
FiddlerBeginRequest: 21:23:59.002 
ServerGotRequest: 21:23:59.002 
ServerBeginResponse: 21:23:59.012 
ServerDoneResponse: 21:23:59.012 
ClientBeginResponse: 21:23:59.012 
ClientDoneResponse: 21:23:59.012 

== FLAGS ================== 
BitFlags: [None] 0x0 
X-RESPONSEBODYTRANSFERLENGTH: 7996 
X-PROCESSINFO: iexplore:3100 
X-CLIENTIP: 127.0.0.1 
X-HOSTIP: ::1 
X-EGRESSPORT: 62807 
X-CLIENTPORT: 62805 

== TIMING INFO ============ 
ClientConnected: 21:23:59.062 
ClientBeginRequest: 21:23:59.063 
ClientDoneRequest: 21:23:59.063 
Determine Gateway: 0ms 
DNS Lookup:   0ms 
TCP/IP Connect: 0ms 
HTTPS Handshake: 0ms 
ServerConnected: 21:23:59.063 
FiddlerBeginRequest: 21:23:59.063 
ServerGotRequest: 21:23:59.064 
ServerBeginResponse: 21:24:01.597 
ServerDoneResponse: 21:24:01.597 
ClientBeginResponse: 21:24:01.597 
ClientDoneResponse: 21:24:01.598 
+0

如果通過http://validator.w3.org/#validate_by_input運行生成的HTML會發生什麼? IIS或Cassini中發生問題嗎?如果您使用www.yourwebsite.name而不是localhost:61877,那麼問題是否會消失?它是否以兼容模式運行(http://stackoverflow.com/questions/2742853/force-internet-explorer-8-browser-mode-in-intranet/2745477#2745477)?你能向我們展示2個請求的Fiddler請求頭(成功加不成功)嗎? – mjwills

+0

另外,你是否運行IE9 RTM(http://www.sadev.co.za/content/internet-explorer-9-breaks-localhost)? – mjwills

+0

@mjwills - HTML驗證正常 - 兩個警告,一個用於HTML5,一個用於UTF8字符編碼。我沒有任何地方可以從正確的URL中嘗試它,對不起。 Compatablity模式沒有打開,但是當我把它打開時,一切正常。 IE9是RTM V.9.0.8113.16421(9.0.3)。成功的提琴手將在一會兒加入。 –

回答

2

如果你的觀點是複製/當你有這個問題貼,還有的在那裏}字符不匹配。

的原因,這是相關的是,Html.BeginForm被早早關門,將在事實上呈現form元素在錯誤的地方結束標籤(在你的div的中間)。 這反過來會創建一個無效的HTML情況,瀏覽器需要確定解析和構建DOM樹以向您顯示頁面的最佳操作過程。

Internet Explorer(至少較舊的版本和兼容模式)在某些情況下會通過複製DOM中的節點來解決此問題。 Firefox,Chrome和Safari做一些更智能/不同的事情。

這可能是你看到的結果是因爲IE在其DOM中創建了兩個<img>元素,然後從腳本請求兩次圖像。

這可以通過打開IE9中的頁面,打開F12來打開開發者工具然後瀏覽DOM尋找額外的<img>來確認。

+0

花括號{}標籤全部匹配,並且HTML看起來也OK。沒有什麼不合適的地方。您是否錯過了TempData []位之前的那個? –

1

我不知道爲什麼IE9的請求圖像的兩倍,但我有一個端頭,它可以幫助,感覺不太hackarific:

您生成圖表圖像時,HTML呈現,而不是當該圖像實際上是要求的。如果你改變了你的RenderChart行動,接受以顏色參數,並呈現圖像,然後代替,而不使用TempData的,許多事情會變得容易:

  • 你的RenderAction方法不再依賴於SessionState會儲存到TempData圖像
  • 這使的RenderAction更容易測試
  • 這將刪除假設調用從img標籤/圖/ RenderChart將肯定是從正確的頁面(這是一個邊緣的情況下線程的情況下,肯定的,但它的可能)
  • 應用短O產生兩份utputCache到的RenderAction將防止多個圖像對所述高速緩存的時間內相同的顏色,即使它們被請求兩次

由於地址的圖像現在更RESTful的 - 即,唯一的資源標識符標識唯一的資源,而不是依賴於一個隱藏的TempData值,您還可以將您的表單更改爲GET請求,避免「重新提交表單」瀏覽器警報,或者您甚至可以通過javascript更改img src,並取消完全形成。

+0

感謝您的關注。從我原來的問題中,我解決了這個問題,遵循了類似的建議路線,但這個問題是專門找出是否有人知道爲什麼IE9會執行兩次GET,當Chrome和Firefox做我所期望的。有趣的是IE8模式(通過IE9)工作正常。 –

4

我們在使用圖表時遇到了完全相同的問題,唯一不同的是我們的定製,但是基於MSChart。現在,我們做到以下幾點,使用文件內容的結果,而不是動作結果的

控制器:

public FileContentResult GetGraph(int id) 
{ 
    var image = Resolve<CountryModel>().Load(id).Graph; //gets our Bitmap object 
    image.Save(HttpContext.Response.OutputStream, ImageFormat.Jpeg); 
    var converter = new ImageConverter(); 

    return new FileContentResult((byte[])converter.ConvertTo(image, typeof(byte[])), "image/jpeg"); 
} 

查看:

<img src="@Url.Action("GetGraph", "Country", new {Id = Model.CountryId})" /> 

希望這有助於

編輯:

我剛剛意識到你正在調用TempData集合中的服務器!

刪除此行從您的視圖:

@{TempData["Chart"] = Model.Chart(); 

,改變你的RenderChart做到以下幾點:

public FileContentResult RenderChart() 
{   
    return File(new ChartModel().Chart().ToArray(), "image/jpeg"); 
} 

原因是,當你實際渲染你的看法,你調用Img標籤中的方法,但是在設置臨時數據時也稱它爲

@{TempData["Chart"] = Model.Chart(); 

因此調用圖表方法兩次。希望這有助於:)

+1

好主意(+1)返回真正的類型,但遺憾的是它不能解決問題,我仍然得到兩個GET請求給RenderChart,第二個失敗。我編輯了問題以反映FileContentResult並添加了Fiddler屏幕截圖。 –

+0

檢查我的編輯:) – mattytommo

+0

該解決方案解決了問題,但我已經知道,從我以前的問題。在這個例子中至關重要的是,我不稱之爲「模型」。Chart()'兩次,它只在View中被調用以用內存流填充'TempData [「Chart」]',在RenderChart中,流從'TempData [「Chart」]提取出來並反饋給視圖通過FileContentResult。我認爲真正的問題是IE9出了問題,因爲Chrome和FireFox以及IE8和IE7都按預期工作。我正在尋找爲什麼IE9做這個'錯誤'的原因並不是真正尋找更好的方式來顯示圖像。 –