gpt4 book ai didi

c# - 在 MVC 中填充下拉列表

转载 作者:太空宇宙 更新时间:2023-11-03 17:43:51 25 4
gpt4 key购买 nike

在我的 MVC 应用程序中,我有一个返回以下 XML 的服务调用 (http://dev-service.test.com/api/brands?active=true)

<Brands>
<Brand>
<BrandId>1</BrandId>
<BrandNo>20</BrandNo>
<BrandName>ABC</Domain>
</Brand>

<Brand>
<BrandId>2</BrandId>
<BrandNo>30</BrandNo>
<BrandName>XYZ</Domain>
</Brand>
<Brands>

在我的一个用户控件中,我想用 BrandName 值填充下拉列表。我已经有一个包含一堆属性的 ViewModel。如何使用此 XML 中的值填充下拉列表?

P.S:我是 MVC 新手,仍在学习 View 模型等基础知识。

最佳答案

你的问题真的有两个部分。 XML 解析部分(与 ASP.NET MVC 完全无关)和 ASP.NET MVC 部分。由于您的问题被标记为 asp.net-mvc我们先回答这部分。所以你提到了一个 View 模型。像这样的东西:

public class BrandsViewModel
{
public string Brand { get; set; }
public IEnumerable<SelectListItem> Brands { get; set; }
}

然后是 Controller Action :
public ActionResult Index()
{
BrandsViewModel model = ...
return View(model);
}

最后是 View 部分:
@model BrandsViewModel
@using (Html.BeginForm())
{
@Html.DropDownListFor(x => x.Brand, Model.Brands)
<button type="submit">OK</button>
}

好的,这是 ASP.NET MVC 部分在您的问题中结束的地方。现在是 XML 解析部分。在 C# 中有几种解析 XML 的方法。例如,您可以使用 XDocument类(class)。

当然,在能够解析 XML 之前,您需要有 XML。您在问题中显示的不是 XML。它是一个字符串。您需要先修复它并拥有一个有效的 XML。像这样:
<Brands>
<Brand>
<BrandId>1</BrandId>
<BrandNo>20</BrandNo>
<BrandName>ABC</BrandName>
</Brand>

<Brand>
<BrandId>2</BrandId>
<BrandNo>30</BrandNo>
<BrandName>XYZ</BrandName>
</Brand>
</Brands>

现在您有了有效的 XML,让我们继续使用 XML 解析器。
var brands =
from brand in XDocument.Load("brands.xml").Descendants("Brand")
select new SelectListItem
{
Value = brand.Element("BrandId").Value,
Text = brand.Element("BrandName").Value
};

现在让我们让两者一起工作:
public ActionResult Index()
{
var brandsFile = Server.MapPath("~/app_data/brands.xml");
var brands =
from brand in XDocument.Load(brandsFile).Descendants("Brand")
select new SelectListItem
{
Value = brand.Element("BrandId").Value,
Text = brand.Element("BrandName").Value
};


var model = new BrandsViewModel
{
Brands = brands
};
return View(model);
}

在这里我们可以看到我们已经将 Controller 操作逻辑与 XML 解析逻辑强耦合,这是很糟糕的。您可以引入一个抽象(接口(interface)),该抽象将被注入(inject)到 Controller 的构造函数中,然后由操作使用。然后,您可以提供此抽象的特定实现,它将执行实际的 XML 解析并配置您的依赖注入(inject)框架以将其传递给 Controller ​​。

所以让我们这样做。让我们定义一个代表我们品牌的领域模型:
public class Brand
{
public string Id { get; set; }
public string Name { get; set; }
}

凉爽的。现在我们想用这些品牌做什么?检索它们的列表。让我们定义我们的合约:
public interface IBrandsRepository
{
Brand[] Get();
}

好的,我们已经指定了我们需要对我们的品牌进行哪些操作。现在我们可以让我们的 Controller 看起来像这样:
public class BrandsController: Controller
{
private readonly IBrandsRepository _repository;
public BrandsController(IBrandsRepository repository)
{
_repository = repository;
}

public ActionResult Index()
{
var brands = _repository.Get().Select(b => new SelectListItem
{
Value = b.Id,
Text = b.Name
});
var model = new BrandsViewModel
{
Brands = brands
};
return View(model);
}
}

这个 Controller Action 还有改进的空间。请注意,我们正在查询存储库并获取域模型列表 ( Brand) 并将此域模型转换为 View 模型。这很麻烦并且污染了我们的 Controller 逻辑。最好将此映射外部化到单独的层中。我个人使用 AutoMapper为了那个原因。它是一个轻量级框架,允许您以流畅的方式定义不同类之间的映射,然后简单地将源类型的实例传递给它,它会向您吐出目标类型的实例:
public class BrandsController: Controller
{
private readonly IBrandsRepository _repository;
public BrandsController(IBrandsRepository repository)
{
_repository = repository;
}

public ActionResult Index()
{
var brands = _repository.Get();
var model = new BrandsViewModel
{
Brands = Mapper.Map<IEnumerable<Brand>, IEnumerable<SelectListItem>>(brands)
};
return View(model);
}
}

所以我们在这里取得了进展。现在我们可以实现我们的合约:
public class BrandsRepositoryXml: IBrandsRepository
{
private readonly string _brandsFile;
public BrandsRepositoryXml(string brandsFile)
{
_brandsFile = brandsFile;
}

public Brand[] Get()
{
return
(from brand in XDocument.Load(_brandsFile).Descendants("Brand")
select new Brand
{
Id = brand.Element("BrandId").Value,
Name = brand.Element("BrandName").Value
})
.ToArray();
}
}

难题的最后一步是配置一些 DI 框架,以将我们合约的正确实现注入(inject) Controller 。 .NET 有大量的 DI 框架。随便挑一个。这并不重要。试试 Ninject.MVC3 NuGet。它有点酷且易于设置。或者,如果您不想使用第三方 DI 框架,只需编写自定义 dependency resolver .

关于c# - 在 MVC 中填充下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10112567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com