string 类型的属性,判断为空的问题!!!

icod 2008-07-11 09:20:15
我有一张部门表

序号 id int 主键
名称 departmentName nvarchar(50) 不能为空
备注 ReMark nvarchar(4000) 可为空

然后做一个对应的ORM
很多人和很多书上在构造函数里直接将参数赋值给类内部的私有字段,我认为这样,在别人用这个类来new一个对象时,有可能将不对的参数传进来,于是我在构造函数里直接将参数赋值给属性,(当然默认的构造函数设置私有字段默认值)
代码如下:


public class Department
{
private int _id;
private string _departmentName;
private string _reMark;


public int ID
{
get { return _id; }
set
{
if (value < 1)
new ArgumentException("部门ID不能小于1!");

_id = value;
}
}


public string DepartmentName
{
get { return _departmentName; }
set
{
if (string.IsNullOrEmpty(value))
throw new ApplicationException("部门名称不能为空!");

if (value.Length > 50)
throw new ApplicationException("部门名称不能超过50个字符!");

_departmentName = value;
}
}


public string ReMark
{
get { return _reMark; }
set
{
if( Convert.IsDBNull(value) || value==null )
_reMark=String.Empty;

else if (value.Length > 4000)
throw new ArgumentException( "备注不能大于4000个字符 ");

_reMark = value;
}
}


public Department(int id, string departmentName, string remark)
{
ID = id;
DepartmentName = departmentName;
ReMark = remark;
}

public Department(string departmentName, string remark)
: this(0, departmentName, remark)
{
}

public Department()
{
_id = 0;
_departmentName = string.Empty;
_reMark=string.Empty;

}

/// <summary>
/// 创建一个新部门
/// </summary>
/// <param name="depName"></param>
/// <param name="remark"></param>
public void Insert(string departmentName, string ReMark)
{
if (string.IsNullOrEmpty(ReMark))
ReMark = string.Empty;

Department dep = new Department(departmentName, ReMark);
DALDepartment daldep = new DALDepartment();//创建数据层
daldep.InsertDepartment(dep);
}
........代码略

无论在insert里还是在属性里检查 remark 是否为空,都提示错误

未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。

源错误:

行 62: set
行 63: {
行 64: if if( Convert.IsDBNull(value) || value==null )
..................
该如何设计?
...全文
226 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
lemong 2008-07-12
  • 打赏
  • 举报
回复
1.输入验证没必要这么多,客户端一次,服务端一次就可以了
2.代码错误:输入验证应该首先检验是否为NULL,即if(value==null || Convert.IsDBNull(value))
icod 2008-07-11
  • 打赏
  • 举报
回复
我试过了,类应该没有问题,

<div> <asp:TextBox ID="TextBox1" runat="server"> </asp:TextBox> <br />
<asp:TextBox ID="TextBox2" runat="server"> </asp:TextBox>
<asp:Button ID="Button4" runat="server" Text="Button" onclick="Button4_Click" />
<br /> </div>


protected void Button4_Click(object sender, EventArgs e)
{
Department d = new Department();
d.Insert(TextBox1.Text, TextBox2.Text);
}
不知道为什么一绑定到数据源,GridView,DetailesView,平时操作没有问题,当把一些可为空的数据置空更新就出显上面的错误
bbbbbb888888 2008-07-11
  • 打赏
  • 举报
回复
_reMark = DbNull.Value.ToString();
viki117 2008-07-11
  • 打赏
  • 举报
回复
在麻烦点就用TRY CATCH跳出来就好了
lyhuc 2008-07-11
  • 打赏
  • 举报
回复
行 62: set
行 63: {
行 64: if if( Convert.IsDBNull(value) ¦ ¦ value==null )
多了个if
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
这也没问题呀
MessageBox.Show(string.Empty.Length.ToString());//0


这样试试嗫

public string ReMark {
get { return _reMark; }
set {

if (!string.IsNullOrEmpty(value)) {
if (value.Length > 4000) {
throw new ArgumentException("备注不能大于4000个字符 ");
}
_reMark = value;
}
//if (Convert.IsDBNull(value) || value == null)
// _reMark = String.Empty;

//else if (value.Length > 4000)
// throw new ArgumentException("备注不能大于4000个字符 ");

//_reMark = value;
}
}
icod 2008-07-11
  • 打赏
  • 举报
回复
我试过了,类应该没有问题,

<div><asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button4" runat="server" Text="Button" onclick="Button4_Click" />
<br /></div>


protected void Button4_Click(object sender, EventArgs e)
{
Department d = new Department();
d.Insert(TextBox1.Text, TextBox2.Text);
}

输入名称,没有输入备注,一切都正常,表里的remark对应为空,不是null(没达到初初衷,我想当为空时还为null)但用objectdatasorce及detailesView时就出错,如下提示

“/”应用程序中的服务器错误。
未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。

源错误:

行 62: set
行 63: {
行 64:
行 65: if (value.Length > 4000)
行 66: throw new ArgumentException("备注不能大于4000个字符");


源文件: D:\icodSolution\icodSolution\BusinessLogicLayer\Department.cs 行: 64

堆栈跟踪:

[NullReferenceException: 未将对象引用设置到对象的实例。]
Department.set_ReMark(String value) in D:\icodSolution\icodSolution\BusinessLogicLayer\Department.cs:64
Department..ctor(Int32 id, String departmentName, String remark) in D:\icodSolution\icodSolution\BusinessLogicLayer\Department.cs:77
Department..ctor(String departmentName, String remark) in D:\icodSolution\icodSolution\BusinessLogicLayer\Department.cs:80
Department.Insert(String departmentName, String ReMark) in D:\icodSolution\icodSolution\BusinessLogicLayer\Department.cs:140

[TargetInvocationException: 调用的目标发生了异常。]
System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +72
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +371
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +29
System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +480
System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method) +38
System.Web.UI.WebControls.ObjectDataSourceView.ExecuteInsert(IDictionary values) +867
System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback) +72
System.Web.UI.WebControls.DetailsView.HandleInsert(String commandArg, Boolean causesValidation) +390
System.Web.UI.WebControls.DetailsView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +602
System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent(Object source, EventArgs e) +109
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +132
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +177
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 icod 的回复:]
todk385:改成:if(value==null ¦ ¦ Convert.IsDBNull(value)) 一样


kkun_3yue3: 改成如下,也一样的错误
public class Department
{
private int _id=0 ;
private string _departmentName=string.Empty ;
private string _reMark=string.Empty;


......
public string DepartmentName
{
get { return _departmentName; }
set
{

if (value.Length > 50)
throw new ApplicationException("部门名称不能超过…
[/Quote]


把给DepartmentName赋值那段代码贴出来,应该是传空值了
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 kkun_3yue3 的回复:]
你把给ReMark 赋值那段代码也贴出来吧
[/Quote]
icod 2008-07-11
  • 打赏
  • 举报
回复
虽然找到一半答案:,在objectdatasource的updateing或inserting中
if(e.InputParameters["ReMark"]==null)
e.InputParameters["ReMark"]=string.Empty;

可以不再提示错误。


但还是很想知道,为什么该类一开始就有初始值
public class Department
{
private int _id=0 ;
private string _departmentName=string.Empty ;
private string _reMark=string.Empty;
.....
为什么还会提示"未将对象引用设置到对象的实例。 "
家鸣 2008-07-11
  • 打赏
  • 举报
回复
把你出错的堆栈信息也贴上来吧,if(value==null ¦ ¦ Convert.IsDBNull(value))这里应该不会引发NullReferenceException的异常。
icod 2008-07-11
  • 打赏
  • 举报
回复
todk385:改成:if(value==null ¦ ¦ Convert.IsDBNull(value)) 一样


kkun_3yue3: 改成如下,也一样的错误
public class Department
{
private int _id=0 ;
private string _departmentName=string.Empty ;
private string _reMark=string.Empty;


......
public string DepartmentName
{
get { return _departmentName; }
set
{

if (value.Length > 50)
throw new ApplicationException("部门名称不能超过50个字符!");

_departmentName = value;
}
}
icod 2008-07-11
  • 打赏
  • 举报
回复
代码直接用objectdatasorce 和 DetailsView 组成
<div id="divInsert">
<h1>创建新部门</h1><hr />
<asp:DetailsView ID="dtlDepartMent" runat="server"
AutoGenerateInsertButton="True" AutoGenerateRows="False"
DataSourceID="srcdepartment" DefaultMode="Insert" DataKeyNames="id" CssClass="insertDetailsView">
<Fields>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" InsertVisible="false" />
<asp:TemplateField HeaderText="部门名称" SortExpression="DepartmentName">
<InsertItemTemplate>
<asp:TextBox ID="insDepNameTxt" runat="server"
Text='<%# Bind("DepartmentName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="rerqvdepName" runat="server"
ControlToValidate="insDepNameTxt" Display="Dynamic">*</asp:RequiredFieldValidator>
</InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="部门备注" SortExpression="ReMark">
<InsertItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("ReMark") %>' Rows="5"
TextMode="MultiLine"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>

</div>
<asp:ObjectDataSource ID="srcdepartment" runat="server" DeleteMethod="Delete"
InsertMethod="Insert" SelectMethod="GetAllDepartMent" TypeName="Department"
UpdateMethod="Update">
<DeleteParameters>
<asp:Parameter Name="id" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="id" Type="Int32" />
<asp:Parameter Name="departmentName" Type="String"/>
<asp:Parameter Name="remark" Type="String" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="departmentName" Type="String" />
<asp:Parameter Name="ReMark" Type="String" />
</InsertParameters>
</asp:ObjectDataSource>
SlaughtChen 2008-07-11
  • 打赏
  • 举报
回复
抢个沙发,看结果!
你先给ReMark赋值 看看.哪一块的问题
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
if(  Convert.IsDBNull(value) ¦ ¦ value==null )
_reMark=String.Empty;


楼主这里是不是想判断是否有值,如果没值就赋空值,感觉多此一举,直接给_reMark设置默认值就可以吧,
ericzhangbo1982111 2008-07-11
  • 打赏
  • 举报
回复
备注 ReMark nvarchar(4000) 可为空
可以为null
而你为什么在它是null的时候thorw 异常

在数据库里设置不为null不就可以了
家鸣 2008-07-11
  • 打赏
  • 举报
回复
if(Convert.IsDBNull(value) ¦ ¦ value==null)
改成:
if(value==null ¦ ¦ Convert.IsDBNull(value))
zzyhuian06142 2008-07-11
  • 打赏
  • 举报
回复
你改成==null || ==""来判断试看看
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
你把给ReMark 赋值那段代码也贴出来吧
kkun_3yue3 2008-07-11
  • 打赏
  • 举报
回复
先说一下,

那个,默认值可以放到私有字段里,不必在每一个属性里判断是否为空,也不用在默认构造函数里赋默认值,
报异常的原因正在看,

110,026

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧