UrlHelper返回执行其他方法的Url

时间:2017-11-15 14:32:32

标签: c# asp.net-web-api

我正在做一个关于Web API的教程,我有2个控制器,一个repo和一个返回模型的工厂,响应在json中并返回数据和url。

这是我的modelFactory:

public class ModelFactory : IModelFactory
{
    private UrlHelper _UrlHelper;

    public ModelFactory(HttpRequestMessage request)
    {
        _UrlHelper = new UrlHelper(request);
    }

    public FoodModel Create(Food food)
    {
        return new FoodModel()
        {
            Url = _UrlHelper.Link("Food", new { foodid = food.Id }),
            Description = food.Description,
            Measures = food.Measures.Select(m => Create(m))
        };
    }

    public MeasureModel Create(Measure measure)
    {
        MeasureModel measureModel  = new MeasureModel
        {
            Url = _UrlHelper.Link("Food", new { foodid = measure.Food.Id, measures = measure.Id }),
            Description = measure.Description,
            Calories = Math.Round(measure.Calories)
        };

        return measureModel;
    }
}

这些是我在WebApiConfig中的路线:

public static void Register(HttpConfiguration config)
{
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
    .Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
                                  "text/html",
                                  StringComparison.InvariantCultureIgnoreCase,
                                  true,
                                  "application/json"));

    config.Formatters.Remove(config.Formatters.XmlFormatter);

    config.Routes.MapHttpRoute(
        name: "Food",
        routeTemplate: "api/nutrition/foods/{foodid}",
        defaults: new { controller = "foods", foodid = RouteParameter.Optional });

    config.Routes.MapHttpRoute(
        name: "Measures",
        routeTemplate: "api/nutrition/foods/{foodid}/measures/{id}",
        defaults: new { controller = "measures", id = RouteParameter.Optional });
}

这是我的MeasuresController:

public class MeasuresController : BaseApiController
{
    public MeasuresController(ICountingKsRepository repo) : base(repo) { }

    public IEnumerable<MeasureModel> Get(int foodid)
    {
        var results = TheRepository.GetMeasuresForFood(foodid)
            .ToList()
            .Select(m => TheModelFactory.Create(m));

        return results;
    }

    public MeasureModel Get(int foodid,int id)
    {

        var results = TheRepository.GetMeasure(id);

        if(results.Food.Id == foodid)
        {
            return TheModelFactory.Create(results);
        }

        return new MeasureModel
        {
            Description = "No Food id associated with this Measure",
            Calories = 0,
            Url = ""
        };
    }

}

现在,我使用fiddler和Chrome的JSONview插件,当我调用Get(int foodid)时,这是我的json的结构

我转到:http://localhost:8901/api/nutrition/foods/1/measures

[
   {
      Url: "http://localhost:8901/api/nutrition/foods/1?measures=1",
      Description: "1 Cup",
      Calories: 1628
   },
   {
      Url: "http://localhost:8901/api/nutrition/foods/1?measures=2",
      Description: "1 Tbsp",
      Calories: 102
   }
]

如果我想去,请说http://localhost:8901/api/nutrition/foods/1?measures=2它执行Get(int foodid)而不是Get(int foodid,int id)但是如果我将Url更改为http://localhost:8901/api/nutrition/foods/1/measures/2

这是正确的方法。

这是什么原因?

1 个答案:

答案 0 :(得分:0)

好吧,我发现了问题

在我的方法中:

<<create>>

Url正在路由到Food而不是Measures,因此我需要更改Url属性:

public MeasureModel Create(Measure measure)
{
    MeasureModel measureModel  = new MeasureModel
    {
        Url = _UrlHelper.Link("Food", new { foodid = measure.Food.Id, measures = measure.Id }),
        Description = measure.Description,
        Calories = Math.Round(measure.Calories)
    };

    return measureModel;
}