3

MVC モデル クラスを作成しましたが、プロパティの 1 つは「MyObject」タイプです。System.ComponentModel.DataAnnotations.StringLength 属性もあります。

MyObject は暗黙のキャスト演算子として使用されるため、基本的に文字列として使用できます。

public static implicit operator string(MyObject o){...}
public static implicit operator MyObject(string sValue){...}

これは何らかの奇妙な理由で asp mvc の問題ですか? ほとんどの場合、暗黙的なキャストが正常に機能することを知っているため、たとえば、そのプロパティを文字列値に割り当てることができ、正常に機能します。

編集 - OK、エラーが発生する理由はわかっています:
StringLength.IsValid() メソッドがオブジェクトをパラメーターとして受け取るため、キャストは実際には MyObject から文字列ではなく、オブジェクトから文字列に移動するためです。暗黙のキャスト演算子が呼び出されていません。しかし、これを回避するにはどうすればよいでしょうか。

モデルのプロパティに System.ComponentModel.DataAnnotations.StringLength 属性を配置するまで、これはすべて正常に機能し、ビューが送信ボタンから投稿すると、例外が発生しました。

[InvalidCastException: タイプ 'StrataSpot.Shared.Models.Email' のオブジェクトをタイプ 'System.String' にキャストできません。]
System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(オブジェクト値) +34
System.Web.Mvc.d__1. MoveNext() +56 System.Web.Mvc.DefaultModelBinder.OnPropertyValidated(ControllerContext controllerContext、ModelBindingContext bindingContext、PropertyDescriptor propertyDescriptor、オブジェクト値) +203 System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext、ModelBindingContext bindingContext、PropertyDescriptor propertyDescriptor) +413
System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext、ModelBindingContext bindingContext) +90
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext、ModelBindingContext bindingContext、オブジェクト モデル) +383
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext、ModelBindingContext bindingContext) +1048
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext ) controllerContext、ModelBindingContext bindingContext) +280
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext、ParameterDescriptor parameterDescriptor) +257
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext、ActionDescriptor actionDescriptor) +109
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +314 System.Web.Mvc.Controller.ExecuteCore() +105 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +39
System.Web. Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
System.Web.Mvc.<>c__DisplayClass8.b__4() +34 System.Web.Mvc.Async.<>c__DisplayClass1.b__0() + 21 System.Web.Mvc.Async.<>c__DisplayClass8 1.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult1.End() +59 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +44
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest( IAsyncResult 結果) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8678910 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

4

1 に答える 1

5

String 以外の型のプロパティに [StringLength] を使用することはできません。機能を複製したい場合は、StringLengthAttribute をサブクラス化できます。

public class MyCoolAttribute : StringLengthAttribute {
  // constructor here

  public override bool IsValid(object value) {
    return base.IsValid((string)(value as MyObject));
  }
}

次に、プロパティで [StringLength] の代わりに [MyCool] を平手打ちします。この点でキャスト演算子を使用することは、おそらく世界で最もクリーンなことではありません。代わりに ToString() などを使用する必要があります。しかし、考え方は同じです。

または、StringLengthAttribute をサブクラス化したくない場合は、代わりにプライベートな StringLengthAttribute インスタンスの IsValid() メソッドに委譲することができます。

于 2010-01-04T06:21:49.930 に答える