IE9与MVC,IMG标记,Url.Action和TempData的意外行为 [英] IE9 unexpected behaviour with MVC, IMG tag, Url.Action and TempData

查看:421
本文介绍了IE9与MVC,IMG标记,Url.Action和TempData的意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提出这作为一个一边当我第一次遇到了这个问题,<一个href=\"http://stackoverflow.com/questions/7996809/memorystream-to-img-via-tempdata-in-mvc3-is-there-a-better-way\">$p$pvious问,我不能针下来我的应用程序,因为有太多的JavaScript,CSS和踢有关图像可能已经加剧的问题。

现在我已经做了一个非常简单的MVC应用程序没有javascipt的,没有CSS,没有其他的图像,似乎IE9叫我的 Url.Action 两次(小提琴手证实),但Chrome和Firefox都做我的期望。

该应用程序很简单,它包含有一个属性,并返回一个MemoryStream(一个MSChart图像)的方法的典范。该视图显示图像和颜色选择器,当视图被发送到控制器,控制器设置颜色图表和创建视图。图表图像是通过调用控制器 RenderChart 通过 Url.Action 动作,显示的MemoryStream 从视图到 RenderImage 操作通过的TempData 通过。这对于一个GET工作正常,但是当它是一个POST IE9总是要求 RenderChart 两次,第二次轮,的TempData 已被删除。这个问题可以通过'复位'在的TempData RenderChart 动作(注释掉线)来解决,但就是这样hackariffic,这显然不是你信任的一个答案。

我不是在寻找替代我已经有了替代品,但....任何人都可以的说明这种行为?

下面的模型

 公共类ChartModel
    {
        公共ChartModel()
        {
            this.ChartColor = Color.Green;
        }
        公共ChartModel(色彩的颜色)
        {
            this.ChartColor =颜色;
        }
        众彩ChartColor {搞定;组; }
        公众的MemoryStream图()
        {
            图图=新图();
            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(默认);
            ca.BackColor = Color.Transparent;
            ca.AxisX.IsMarginVisible = FALSE;            系列系列= chart.Series.Add(浏览器/获取);
            series.ChartType = SeriesChartType.Bar;
            字符串[] =浏览器新的字符串[] {IE9,铬,火狐};
            INT [] =获取新的INT [] {2,1,1};
            series.Points.DataBindXY(浏览器,获取);            使用(MemoryStream的memStream =新的MemoryStream())
            {
                chart.SaveImage(memStream,ChartImageFormat.Jpeg);
                返回memStream;
            }
        }
    }

下面是该视图

  @model TestChart.Models.ChartModel
@ {
    ViewBag.Title =图表;
}
&LT; H2&GT;图&LT; / H&GT;
@using(Html.BeginForm(指数,图表))
{
    @ Html.DropDownListFor(M = GT; m.ChartColor,新的SelectList(Enum.GetNames(typeof运算(System.Drawing.KnownColor))))
    &LT; BR /&GT;
    &LT; D​​IV&GT;
        &LT; D​​IV&GT;
            &LT; BR /&GT;
            @ {TempData的[图表] = Model.Chart();
            }
            &LT; IMG ALT =图SRC =@ Url.Action(RenderChart,图表)/&GT;
        &LT; / DIV&GT;
    &LT; / DIV&GT;
    &LT;输入类型=提交值=邮报/&GT;
}

和这里的控制器

 公共类ChartController:控制器
    {
        公众的ActionResult指数(字符串colorName =白)
        {
            ChartModel模型;
            模型=新ChartModel(Color.FromName(colorName));
            返回查看(模型);
        }        [HttpPost]
        公众的ActionResult指数(ChartModel模型)
        {
            返回RedirectToAction(指数,新的{colorName = model.ChartColor.Name});
        }        公共FileContentResult RenderChart()
        {
            的MemoryStream毫秒​​= TempData的[图表作为MemoryStream的;
            // TempData的[图表] =毫秒; //取消注释此行让IE9的工作 - 事实上奇
            返回文件(ms.ToArray(),图像/ JPEG);
        }
    }

和生成的HTML看起来像......(颜色列表截断)

 &LT;形式的行动=/图的方法=后&GT;
&LT;选择数据-VAL =真正的数据-VAL-所需=是必需的ChartColor场。 ID =ChartColorNAME =ChartColor&GT; &LT;选项&GT; ActiveBorder&LT; /选项&GT;

&LT;选项&GT; MenuHighlight&LT; /选项&GT;
&LT; /选择&GT; &LT; BR /&GT;
    &LT; D​​IV&GT;
        &LT; D​​IV&GT;
            &LT; BR /&GT;
            &LT; IMG ALT =图SRC =/图/ RenderChart/&GT;
        &LT; / DIV&GT;
    &LT; / DIV&GT;
    &LT;输入类型=提交值=邮报/&GT;
&LT; /表及GT;
&LT; /身体GT;
&LT; / HTML&GT;

和提琴手输出看起来是这样的

提琴手当它工作(在兼容模式下)

提琴手头 - 工程确定

  GET /图/索引/窗框HTTP / 1.1
接受:text / html的,是application / xhtml + XML,* / *
引用者:HTTP://本地主机:54307 /图/索引/菜单
接受语言: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
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
接受编码:gzip,紧缩
主机:本地主机:54307
连接:保持活动
编译:无缓存
饼干:ASP.NET_SessionId = biv2pyhxucudsg3aqsvv3jbsGET /图/ RenderChart HTTP / 1.1
接受:图像/ PNG,图像/ SVG + XML,图像/ *; Q = 0.8 * / *; Q = 0.5
引用者:HTTP://本地主机:54307 /图/索引/窗框
接受语言: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
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
接受编码:gzip,紧缩
主机:本地主机:54307
连接:保持活动
饼干:ASP.NET_SessionId = biv2pyhxucudsg3aqsvv3jbs

提琴手头故障

  GET /图/索引/透明HTTP / 1.1
接受:text / html的,是application / xhtml + XML,* / *
引用者:HTTP://本地主机:54307 /图/索引/窗框
接受语言: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
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
接受编码:gzip,紧缩
主机:本地主机:54307
连接:保持活动
编译:无缓存
饼干:ASP.NET_SessionId = biv2pyhxucudsg3aqsvv3jbsGET /图/ RenderChart HTTP / 1.1
接受:图像/ PNG,图像/ SVG + XML,图像/ *; Q = 0.8 * / *; Q = 0.5
引用者:HTTP://本地主机:54307 /图/索引/透明
接受语言: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
用户代理:Mozilla的/ 5.0(兼容; MSIE 9.0; Windows NT的6.1;三叉戟/ 5.0)
接受编码:gzip,紧缩
主机:本地主机:54307
连接:保持活动
饼干:ASP.NET_SessionId = biv2pyhxucudsg3aqsvv3jbs

和这里的提琴手对于一些时序(后/ imageOK /图像失败)

请注意,失败的一个不启动,直到后完成后良好。使我怀疑,如果没有某种额外的线程的地方,认为IMG标签没有被履行,并决定去做到这一点。神秘确实如此。

  == FLAGS ==================
BitFlags:[无]为0x0
的X RESPONSEBODYTRANSFERLENGTH:5627
的X PROCESSINFO:IEXPLORE:3100
的X CLIENTIP:127.0.0.1
的X HOSTIP::: 1
的X EGRESSPORT:62803
的X CLIENTPORT:62801==时序信息============
ClientConnected:21:23:58.866
ClientBeginRequest:21:23:58.866
ClientDoneRequest:21:23:58.867
确定网关:0毫秒
DNS查找:0毫秒
TCP / IP连接:1毫秒
HTTPS握手:0毫秒
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:[无]为0x0
的X RESPONSEBODYTRANSFERLENGTH:17612
的X PROCESSINFO:IEXPLORE:3100
的X CLIENTIP:127.0.0.1
的X HOSTIP::: 1
的X EGRESSPORT:62804
的X CLIENTPORT:62802==时序信息============
ClientConnected:21:23:58.866
ClientBeginRequest:21:23:59.001
ClientDoneRequest:21:23:59.001
确定网关:0毫秒
DNS查找:0毫秒
TCP / IP连接:0毫秒
HTTPS握手:0毫秒
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:[无]为0x0
的X RESPONSEBODYTRANSFERLENGTH:7996
的X PROCESSINFO:IEXPLORE:3100
的X CLIENTIP:127.0.0.1
的X HOSTIP::: 1
的X EGRESSPORT:62807
的X CLIENTPORT:62805==时序信息============
ClientConnected:21:23:59.062
ClientBeginRequest:21:23:59.063
ClientDoneRequest:21:23:59.063
确定网关:0毫秒
DNS查找:0毫秒
TCP / IP连接:0毫秒
HTTPS握手:0毫秒
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


解决方案

我们已经完全相同的问题巧合使用图表,唯一不同的是我们是定制的,但基于MSChart的。现在,我们做到以下几点,使用文件,而不是一个操作结果的内容结果

控制器:

 公共FileContentResult GetGraph(INT ID)
{
    VAR图像=解决&LT; CountryModel&GT;()负载(ID).Graph。 //得到我们的位图对象
    image.Save(HttpContext.Response.OutputStream,ImageFormat.Jpeg);
    VAR器=新ImageConverter();    返回新FileContentResult((字节[])converter.ConvertTo(图像的typeof(字节[])),图像/ JPEG);
}

查看:

 &LT; IMG SRC =@ Url.Action(GetGraph,国家,新{ID = Model.CountryId})/&GT;

希望这有助于

编辑:

我刚刚意识到你打电话你TempData的服务器设置!

从视图中删除这一行:

  @ {TempData的[图表] = Model.Chart();

和改变你的RenderChart做到以下几点:

 公共FileContentResult RenderChart()
{
    返回文件(新ChartModel()图()ToArray的(),图像/ JPEG);
}

原因是,当你实际渲染你的看法,你调用img标签的方法,但你也设置临时数据:当调用它:

  @ {TempData的[图表] = Model.Chart();

因此​​调用两次图表方法。希望这有助于:)

I brought this up as an aside when I first ran into this problem Previous Question, I couldn't pin it down in my app because there were too many javascript, css and images kicking about that might have been aggravating the problem.

Now I've done a very simple MVC app with no javascipt, no css and no other images and it seems that IE9 calls my Url.Action twice (fiddler confirms) but Chrome and Firefox both do what I expect.

The app is simple, it contains a model that has one property and a method that returns a memorystream (of an MSChart image). The view displays the image and a color picker, when the view is posted to the controller, the controller sets the color for the chart and creates the view. The chart image is displayed by calling a controller RenderChart action via Url.Action, the MemoryStream is passed from the view to the RenderImage action via TempData. This works fine for a GET, but when it's a POST IE9 always requests RenderChart twice and the second time round, TempData has been removed. The problem can be resolved by 'resetting' the TempData in the RenderChart action (commented out line) but that is so hackariffic that it clearly isn't an answer that you'd trust.

I'm not looking for alternatives I already have alternatives but....can anyone explain this behaviour?

Here's the model

   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;
            }
        }
    }

Here's the view

@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" />
}

And here's the controller

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");
        }
    }

And the resulting HTML looks like...(colors list truncated)

<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>

And the Fiddler output looks like this Fiddler when it works (in compatibility mode)

Fiddler Header - Works OK

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

Fiddler Header Failure

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

And here's some timings for fiddler (post / imageOK / image failed)

Notice that the failed one doesn't start until well after the post is completed. makes me wonder if there isn't some kind of extra thread somewhere that thinks the IMG tag hasn't been fulfilled and decides to go and do it. Mystery indeed.

== 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

解决方案

We had exactly the same problem coincidently using Charts, only difference was ours were custom, but based on MSChart. We now do the following, using a File Content Result instead of an Action Result

Controller:

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");
}

View:

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

Hope this helps

EDIT:

I've just realised you're calling the server in your TempData set!

remove this line from your view:

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

and change your RenderChart to do the following:

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

The reason is, when you're actually rendering your view, you're calling the method in the Img tag, but you're also calling it when setting the temp data:

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

Thus invoking the chart method twice. Hope this helps :)

这篇关于IE9与MVC,IMG标记,Url.Action和TempData的意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆