从MVC3中的String到System.Web.Mvc.ViewResult的转换错误

时间:2013-01-17 12:49:12

标签: asp.net-mvc-3

您好我对MVC很新,我正在尝试创建一个从华氏温度到摄氏温度的简单转换及其单元测试。提前抱歉将所有代码放在这里。

这是我的控制器代码:

public string Convert(double value,string option)
{
    string d;

    if(option=="1") {
        d = " To Celcius"+FahrenheitToCelsius(value).ToString();
    }
    else {
        d = " To Fahrenheit" + CelsiusToFahrenheit(value).ToString();
    }
    return "ConvertTo" + d;
}

public static double CelsiusToFahrenheit(double temperatureCelsius)
{
    double celsius = temperatureCelsius;
    return (celsius * 9 / 5) + 32;
}

public static double FahrenheitToCelsius (double temperatureFahrenheit)
{
    double fahrenheit = temperatureFahrenheit;
    return (fahrenheit - 32) * 5 / 9;
}

这是我的查看页面

protected void btnConvert(object sender, EventArgs e)
{
    if (DropDownList1.SelectedValue=="1"){
        double temp = TemperatureConverterController.FahrenheitToCelsius(double.Parse(TextBox1.Text));
        Literal1.Text = temp.ToString();
    }
    else{
        double temp = TemperatureConverterController.CelsiusToFahrenheit(double.Parse(TextBox1.Text));
        Literal1.Text = temp.ToString();
        Literal1.Text = temp.ToString();
    }
}

当我进行单元测试时出现错误:

[TestMethod]
public void ConvertReturnsAViewResultWhenInputDataIsValid()
{
    //Arrange
    var controller = new TemperatureConverterController();

    //Act
    double x = 80;
    double y = 25;
    var result = controller.Convert(x, "1") as ViewResult;
    //    here i get this error under ViewResult //

    //Assert
    Assert.IsInstanceOfType(result, typeof(ViewResult));
}

[TestMethod]
public void ConvertAsksForAViewTemplateNamedConvert()
{
    //Arrange
    var controller = new TemperatureConverterController();
    String expectedViewTemplate = "Convert";

    //Act
    double x = 80;
    double y = 25;
    var result = controller.Convert(x, "1") as ViewResult;
    ////Assert
    Assert.AreEqual<String>(expectedViewTemplate, result.ViewName);
}

错误是:

Error   Cannot convert type 'string' to 'System.Web.Mvc.ViewResult' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion.

3 个答案:

答案 0 :(得分:2)

问题出在这里

var result = controller.Convert(x, "1") as ViewResult;

您的Convert方法返回字符串,并将其转换为ViewResult

您的转换方法应该是

public ActionResult Convert()
{
    //Make a Model class and pass it to View
    //...
    return View(model_class_object);
}

或者你可以像这样制作控制器

public ActionResult Convert()
{
    ViewData["tempvalue"]=Convert(x, "1");
    //Make a Model class and pass it to View
    //...
    return View();
}

在您的视图中,您可以打印它

@ViewData["tempvalue"].ToString()

答案 1 :(得分:0)

在MVC中,控制器代码应返回包含模型的“ActionResult”对象。

如果要传递给视图的数据只是一个字符串,请使用:

public ActionResult Convert()
{
    //...
    return View("your result here...");
}

您可以使用“视图”或“测试”中的“模型”属性来引用控制器返回的数据。

答案 2 :(得分:-1)

让我们在这里倒退一分钟。

控制器

public class ConvertController : Controller
{
    public ActionResult Convert(MyConvertViewModel vm)
    {
        if (vm == null) { return View("convert", new MyConvertViewModel { ShowResult = false }); }

        if (vm.Option == 1)
        {
            vm.Result = FahrenheitToCelsius(vm.Input);
            vm.OptionName = "Fahrenheit To Celsius";
        }
        else
        {
            vm.Result = CelsiusToFahrenheit(vm.Input);
            vm.OptionName = "Celsius to Fahrenheit";
        }
        vm.ShowResult = true;

        //not needed, just for an example
        ViewData.Add("glosrob-example", "A value goes here!");

        return View("convert", vm);
    }

    private static double CelsiusToFahrenheit(double temperatureCelsius)
    {
        double celsius = temperatureCelsius;
        return (celsius * 9 / 5) + 32;
    }

    private static double FahrenheitToCelsius(double temperatureFahrenheit)
    {
        double fahrenheit = temperatureFahrenheit;
        return (fahrenheit - 32)*5/9;
    }
}

public class MyConvertViewModel
{
    public double Result { get; set; }
    public int Option { get; set; }
    public double Input { get; set; }
    public string OptionName { get; set; }
    public bool ShowResult { get; set; }
}

查看

@model MvcApplication1.Controllers.MyConvertViewModel
@{
    ViewBag.Title = "Convert";
}
<h2>Convert</h2>

@using (Html.BeginForm("convert", "convert", FormMethod.Post))
{
 <div>
     Let's convert some temperatures!
 </div>
 <div>
     @Html.LabelFor(x => x.Input, "Temp. To Convert")
     @Html.TextBoxFor(x => x.Input)
 </div>
 <div>
     @Html.LabelFor(x => x.Option, "Convert to ")
     @Html.DropDownListFor(x => x.Option, new List<SelectListItem>
     {
         new SelectListItem {Text = "Celsius", Value = "1"},
         new SelectListItem {Text = "Fahrenheit", Value = "2"}
     })
 </div>
 <div>
     <button type="submit">Convert It!</button>
 </div>
}
@if (Model.ShowResult)
{
    <p>@Model.OptionName : @Model.Input = @Model.Result</p>
}
免责声明:那里有很多快捷方式,它只是为了让您了解应该拥有的内容。

因此视图会将用户选择的数据发布回控制器操作Convert

控制器将返回一个ViewResult对象,它将使用视图模型中捕获的数据进行渲染MyConvertViewModel

现在我们要测试一下。

所以这里有一些更重要的属性,你似乎需要挂钩

[TestMethod]
public void Not_A_Real_Test_But_Stuff_You_Will_Want_To_Use()
{
    //arrange
    var c = new ConvertController();

    //act
    var results = c.Convert(null) as ViewResult;

    //now results is a ViewResult or null

    var theViewModelProperty = results.Model as MyConvertViewModel;
    var exampleResult = theViewModelProperty.Result;
    var exampleInput = theViewModelProperty.Input;

    //etc

    //how about the view that was returned?
    var theViewName = results.ViewName;

    //or anything you put in the ViewData
    var theViewData = results.ViewData["glosrob-example"];

    Assert.Fail("This was not a real test!");
}

希望这能让您了解如何测试控制器方法的输出。

编辑:我不会为你编写所有测试,而是作为一个例子。

[TestMethod]
public void Convert_Should_Return_A_MyConvertViewModel()
{
    //arrange
    var c = new Controller();

    //act
    var result = c.Convert(null) as ViewResult;

    //assert
    Assert.IsNotNull(result);
    Assert.IsInstanceOfType(result.ViewModel, typeof(MyConvertViewModel));
}

[TestMethod]
public void Convert_Should_Return_The_Correct_View()
{
    //arrange
    var c = new Controller();

    //act
    var result = c.Convert(null) as ViewResult;

    //assert
    Assert.IsNotNull(result);
    Assert.AreEqual("convert", result.ViewName);
}