ASP.NET MVC 3 ContentResult 将不接受从另一个类继承的类
Posted
技术标签:
【中文标题】ASP.NET MVC 3 ContentResult 将不接受从另一个类继承的类【英文标题】:ASP.NET MVC 3 ContentResult Will Not Accept Class That Inherits From Another Class 【发布时间】:2011-07-10 18:37:42 【问题描述】:这是我在这里提出的另一个问题:Find nearby entities with Bing Maps REST control
在上面的问题中,在函数 DisplayResults(response) 的 for 循环中,我添加了以下代码:
var loc = new Array();
loc[0] = results[i].Longitude;
loc[1] = results[i].Latitude;
var address =
AddressLine1: results[i].Address,
City: results[i].City,
State: results[i].StateOrProvince,
PostalCode: results[i].PostalCode,
Latitude: results[i].Latitude,
Longitude: results[i].Longitude,
Country: results[i].CountryOrRegion,
ID: results[i].UniqueId
;
$.ajax(
url: "/Home/AddAddressToCollection",
type: 'post',
data: JSON.stringify(address),
contentType: 'application/json',
dataType: 'json'
);
上面的代码从结果数据集中包含的每个地址构造一个地址,并将其发送回 ContentResult,该结果返回 null,因为它的目的是将每个地址存储到后端,即 MongoDB。您可能想知道我为什么采用这种方法 - 地址是 MongoDB 的种子数据。这个想法是,这是一个开源项目,我想添加一些个性化来使用开发人员的 GeoLocation,方法是为他们提供一组与他们检测到的位置相对应的本地化地址(该代码都在我之前的帖子中)。
这是 HomeController 中 ContentResult 的代码:
[HttpPost]
public ContentResult AddAddressToCollection(Address address)
address.GeoInsert(_dbName, ref _repository);
return null;
当我的 Address 类如下所示时,此代码可以与相应的 POST 方法一起使用:
公开课地址 私人双纬度; 私人双 _longitude;
[Key]
[Required]
[HiddenInput(DisplayValue=false)]
public string ID get; set;
[Required]
[HiddenInput(DisplayValue = false)]
public virtual Guid AccountID get; set;
[Required]
[Display(Name = "Address Line 1")]
public string AddressLine1 get; set;
[Display(Name = "Address Line 2")]
public string AddressLine2 get; set;
[Required]
[Display(Name = "City")]
public string City get; set;
[Required]
[Display(Name = "State")]
public string State get; set;
[Required]
[Display(Name = "Zip Code")]
public string PostalCode get; set;
public string Country get; set;
[Required]
[HiddenInput(DisplayValue = false)]
public double[] Location get; set;
[Required]
[HiddenInput(DisplayValue = false)]
public double Latitude
get return _latitude;
set
Location[1] = value;
_latitude = value;
[Required]
[HiddenInput(DisplayValue = false)]
public double Longitude
get return _longitude;
set
Location[0] = value;
_longitude = value;
public Address()
Location = new double[2];
public void GeoInsert(string dbName, ref Repository repository)
repository.MongoGeoInsert(dbName, this);
public Dictionary<Address, double> GeoNear(string dbName, ref Repository repository, double maxKilometers, int limitResults)
return repository.MongoGeoNear<Address>(dbName, this.Latitude, this.Longitude, maxKilometers, limitResults);
但这就是我好奇的地方......虽然我现在不需要这个,但我最初尝试让我的模型中的所有类都从同一个基类继承,以帮助我使用一些自定义序列化方法.当我从这样一个类继承......让我们称之为 BaseClass,POST 不再工作,我从服务器收到 500 响应......我只是不清楚原因是什么。这是我正在谈论的一个示例(p.s.如果您碰巧使用以下任何代码,只是提示您应该弄清楚如何使用 Dictionary 进行序列化......它要快得多,但人们更熟悉有反射,所以这就是我要在这里做的):
这么快,对于 Address 类,我将拥有:
地址:基类
构造函数是……
地址 : base("地址") //尽管 base("Address") 不是必需的,除非你使用字典 //序列化方法
现在是 BaseClass...
public class Serialization
public abstract class BaseObject
[BsonId(IdGenerator = typeof(CombGuidGenerator))]
public Guid? Id get; set;
public string ObType get; private set;
public BaseObject() : this("base")
public BaseObject(string obType)
ObType = obType;
Id = Guid.NewGuid();
public virtual BaseObject Parse(XElement xml)
PropertyInfo[] properties = this.GetType().GetProperties();
foreach (var property in properties)
ElementName attribute = Attribute.GetCustomAttribute(property, typeof(ElementName)) as ElementName;
if (attribute == null) continue;
object value = null;
string stringValue = xml.Element(attribute.Name).Value;
switch (property.PropertyType.Name.ToLower())
case "double":
value = double.Parse(stringValue);
break;
default:
value = stringValue;
break;
property.SetValue(this, value, null);
return this;
public class Serializer
public static T Deserialize<T>(XElement xml)
where T : BaseObject, new()
BaseObject obj = new T() as BaseObject;
if (obj != null)
//populate obj properties...
obj.Parse(xml);
return obj as T;
好的,我认为这应该是足够的信息......有什么想法不起作用?希望我在这里没有遗漏一些非常明显的东西......但我做的 Silverlight 比 ASP.NET 编程要多得多,所以我完全有可能是 0:)
谢谢!
【问题讨论】:
你能打开 firebug 告诉我们你遇到了什么错误吗?? 是的,这是一个非常标准的 500 错误:POST /Home/AddAddressToCollection 500 Internal Server Error 我认为它与 MVC 框架如何处理内容和操作结果有关,因为我知道代码客户端正在工作(因为当我不从 BaseClass 继承时它工作) 【参考方案1】:所以这里的第一个问题是你的问题的范围方式太大了。
您首先向这个“黑匣子”服务器发送一个 AJAX 请求。但后来发现你有服务器的代码,那么我为什么要关心 AJAX 请求呢?开始的地方:
-
您确定序列化工作正常吗?您是否有测试证明您的自定义序列化基类确实有效? (伪造输入应该是微不足道的)如果不是,你可能会得到一个错误。
数据是否正确进入 MongoDB?如果没有,您可能会抛出异常并得到错误。请注意 CSharp 驱动程序has its own serialization。你可能会破坏它。
您能否确认相同的数据正在进入视图?您的视图可能会爆炸,因为您依赖于某些不正确存在的字段。
总而言之,这个问题应该很容易通过典型的单元测试覆盖率来诊断。您对一个类进行了一项更改,因此您的测试套件应该会抛出一些非常明确的消息,可能是上述三个之一。
如果您的测试套件没有抛出任何错误,那么您显然错过了一些重要的测试。
如果您没有任何测试覆盖率,现在可能是开始的好时机。
【讨论】:
序列化代码已经过彻底的测试,但我在这个例子中没有使用序列化。为了澄清,我添加这个类是有远见的,我可能想在以后使用序列化,但这不是问题。我知道代码有效,所以我很确定它与引发内部错误的 MVC 框架有关。沿着这些思路 - 当然,我没有考虑这个错误,但如果我有一个针对这个错误的测试,我为什么要问这个问题?! 盖茨,如果你被我的 Mongo 代码吓跑了,我写了一组自定义的 Mongo 操作来简化 Mongo 的使用。我对 Mongo 序列化非常熟悉,这与此无关。为了简化互操作性并减轻传输/存储成本,在传递或存储有关特定类的数据时,我经常使用自定义 xml/json 序列化程序。以上是关于ASP.NET MVC 3 ContentResult 将不接受从另一个类继承的类的主要内容,如果未能解决你的问题,请参考以下文章
我们是不是正在使用 .Net 3.5 中的 MVC 框架转向经典 ASP?
(转)表单和HTML辅助方法 - ASP.NET MVC 3
ASP .NET 5 MVC 6 Identity 3 Roles Claims Groups [关闭]